ppp.c
Go to the documentation of this file.
1 /**
2  * @file ppp.c
3  * @brief PPP (Point-to-Point Protocol)
4  *
5  * @section License
6  *
7  * Copyright (C) 2010-2018 Oryx Embedded SARL. All rights reserved.
8  *
9  * This file is part of CycloneTCP Open.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @author Oryx Embedded SARL (www.oryx-embedded.com)
26  * @version 1.9.0
27  **/
28 
29 //Switch to the appropriate trace level
30 #define TRACE_LEVEL PPP_TRACE_LEVEL
31 
32 //Dependencies
33 #include "core/net.h"
34 #include "ppp/ppp.h"
35 #include "ppp/ppp_hdlc.h"
36 #include "ppp/ppp_debug.h"
37 #include "ppp/lcp.h"
38 #include "ppp/ipcp.h"
39 #include "ppp/ipv6cp.h"
40 #include "ppp/pap.h"
41 #include "ppp/chap.h"
42 #include "str.h"
43 #include "debug.h"
44 
45 //Check TCP/IP stack configuration
46 #if (PPP_SUPPORT == ENABLED)
47 
48 //Tick counter to handle periodic operations
50 
51 //FCS lookup table
52 static const uint16_t fcsTable[256] =
53 {
54  0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
55  0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
56  0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E,
57  0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876,
58  0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD,
59  0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5,
60  0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C,
61  0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974,
62  0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB,
63  0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3,
64  0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A,
65  0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72,
66  0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9,
67  0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1,
68  0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738,
69  0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70,
70  0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7,
71  0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF,
72  0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036,
73  0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E,
74  0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5,
75  0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
76  0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134,
77  0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C,
78  0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3,
79  0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB,
80  0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232,
81  0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A,
82  0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1,
83  0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9,
84  0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330,
85  0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78
86 };
87 
88 
89 /**
90  * @brief Initialize settings with default values
91  * @param[out] settings Structure that contains PPP settings
92  **/
93 
95 {
96  //Use default interface
97  settings->interface = netGetDefaultInterface();
98 
99  //Default MRU
100  settings->mru = PPP_DEFAULT_MRU;
101  //Default async control character map
102  settings->accm = PPP_DEFAULT_ACCM;
103  //Allowed authentication protocols
105 
106  //Random data generation callback function
107  settings->randCallback = NULL;
108  //PPP authentication callback function
109  settings->authCallback = NULL;
110 }
111 
112 
113 /**
114  * @brief PPP initialization
115  * @param[in] context Pointer to the PPP context
116  * @param[in] settings PPP specific settings
117  * @return Error code
118  **/
119 
120 error_t pppInit(PppContext *context, const PppSettings *settings)
121 {
122  error_t error;
123  NetInterface *interface;
124 
125  //Debug message
126  TRACE_INFO("PPP initialization\r\n");
127 
128  //Underlying network interface
129  interface = settings->interface;
130 
131  //Initialize PPP context
132  memset(context, 0, sizeof(PppContext));
133 
134  //Save user settings
135  context->settings = *settings;
136 
137 #if (PAP_SUPPORT == DISABLED)
138  //PAP authentication is not supported
139  context->settings.authProtocol &= ~PPP_AUTH_PROTOCOL_PAP;
140 #endif
141 
142 #if (PAP_SUPPORT == DISABLED)
143  //CHAP with MD5 authentication is not supported
144  context->settings.authProtocol &= ~PPP_AUTH_PROTOCOL_CHAP_MD5;
145 #endif
146 
147  //Attach the PPP context to the network interface
148  interface->pppContext = context;
149 
150  //Initialize structure
151  context->interface = interface;
152  context->timeout = INFINITE_DELAY;
153 
154  //Initialize PPP finite state machine
155  context->pppPhase = PPP_PHASE_DEAD;
156  context->lcpFsm.state = PPP_STATE_0_INITIAL;
157 
158 #if (IPV4_SUPPORT == ENABLED)
159  //Initialize IPCP finite state machine
160  context->ipcpFsm.state = PPP_STATE_0_INITIAL;
161 #endif
162 
163 #if (IPV6_SUPPORT == ENABLED)
164  //Initialize IPV6CP finite state machine
165  context->ipv6cpFsm.state = PPP_STATE_0_INITIAL;
166 #endif
167 
168 #if (PAP_SUPPORT == ENABLED)
169  //Initialize PAP finite state machine
170  context->papFsm.localState = PAP_STATE_0_INITIAL;
171  context->papFsm.peerState = PAP_STATE_0_INITIAL;
172 #endif
173 
174 #if (CHAP_SUPPORT == ENABLED)
175  //Initialize CHAP finite state machine
176  context->chapFsm.localState = CHAP_STATE_0_INITIAL;
177  context->chapFsm.peerState = CHAP_STATE_0_INITIAL;
178 #endif
179 
180  //Attach PPP HDLC driver
181  error = netSetDriver(interface, &pppHdlcDriver);
182 
183  //Return status code
184  return error;
185 }
186 
187 
188 /**
189  * @brief Set timeout value for blocking operations
190  * @param[in] interface Underlying network interface
191  * @param[in] timeout Maximum time to wait
192  * @return Error code
193  **/
194 
196 {
197  PppContext *context;
198 
199  //Check parameters
200  if(interface == NULL)
202  //Make sure PPP has been properly configured
203  if(interface->pppContext == NULL)
204  return ERROR_NOT_CONFIGURED;
205 
206  //Point to the PPP context
207  context = interface->pppContext;
208 
209  //Get exclusive access
211 
212  //Set timeout value
213  context->timeout = timeout;
214 
215  //Release exclusive access
217 
218  //No error to report
219  return NO_ERROR;
220 }
221 
222 
223 /**
224  * @brief Set PPP authentication information
225  * @param[in] interface Underlying network interface
226  * @param[in] username NULL-terminated string containing the user name to be used
227  * @param[in] password NULL-terminated string containing the password to be used
228  * @return Error code
229  **/
230 
232  const char_t *username, const char_t *password)
233 {
234  PppContext *context;
235 
236  //Check parameters
237  if(interface == NULL || username == NULL || password == NULL)
239  //Make sure PPP has been properly configured
240  if(interface->pppContext == NULL)
241  return ERROR_NOT_CONFIGURED;
242 
243  //Point to the PPP context
244  context = interface->pppContext;
245 
246  //Get exclusive access
248 
249  //Save user name
250  strSafeCopy(context->username, username, PPP_MAX_USERNAME_LEN);
251  //Save password
252  strSafeCopy(context->password, password, PPP_MAX_PASSWORD_LEN);
253 
254  //Release exclusive access
256 
257  //No error to report
258  return NO_ERROR;
259 }
260 
261 
262 /**
263  * @brief Password verification
264  * @param[in] interface Underlying network interface
265  * @param[in] password NULL-terminated string containing the password to be checked
266  * @return TRUE if the password is valid, else FALSE
267  **/
268 
269 bool_t pppCheckPassword(NetInterface *interface, const char_t *password)
270 {
271  bool_t status;
272  PppContext *context;
273 
274  //Debug message
275  TRACE_DEBUG("PPP password verification...\r\n");
276 
277  //The password has not been verified yet
278  status = FALSE;
279 
280  //Point to the PPP context
281  context = interface->pppContext;
282 
283  //Make sure PPP has been properly configured
284  if(context != NULL)
285  {
286  //Check authentication protocol
287  if(context->localConfig.authProtocol == PPP_PROTOCOL_PAP)
288  {
289 #if (PAP_SUPPORT == ENABLED)
290  //PAP authentication protocol
291  status = papCheckPassword(context, password);
292 #endif
293  }
294  //CHAP authentication protocol?
295  else if(context->localConfig.authProtocol == PPP_PROTOCOL_CHAP)
296  {
297 #if (CHAP_SUPPORT == ENABLED)
298  //CHAP authentication protocol
299  status = chapCheckPassword(context, password);
300 #endif
301  }
302  }
303 
304  //Return TRUE is the password is valid, else FALSE
305  return status;
306 }
307 
308 
309 /**
310  * @brief Send AT command
311  * @param[in] interface Underlying network interface
312  * @param[in] data NULL-terminated string that contains the AT command to be sent
313  * @return Error code
314  **/
315 
317 {
318  error_t error;
319  bool_t status;
320  PppContext *context;
321 
322  //Check parameters
323  if(interface == NULL)
325  //Make sure PPP has been properly configured
326  if(interface->pppContext == NULL)
327  return ERROR_NOT_CONFIGURED;
328 
329  //Point to the PPP context
330  context = interface->pppContext;
331 
332  //Wait for the send buffer to be available for writing
333  status = osWaitForEvent(&interface->nicTxEvent, context->timeout);
334 
335  //Check status
336  if(status)
337  {
338  //Get exclusive access
340 
341  //Check current PPP state
342  if(context->pppPhase == PPP_PHASE_DEAD)
343  {
344  //Purge receive buffer
345  error = pppHdlcDriverPurgeRxBuffer(context);
346 
347  //Send AT command
348  if(!error)
349  error = pppHdlcDriverSendAtCommand(interface, data);
350  }
351  else
352  {
353  //Report an error
354  error = ERROR_ALREADY_CONNECTED;
355  }
356 
357  //Release exclusive access
359  }
360  else
361  {
362  //Timeout error
363  return ERROR_TIMEOUT;
364  }
365 
366  //Return status code
367  return error;
368 }
369 
370 
371 /**
372  * @brief Wait for an incoming AT command
373  * @param[in] interface Underlying network interface
374  * @param[out] data Buffer where to store the incoming AT command
375  * @param[in] size Size of the buffer, in bytes
376  * @return Error code
377  **/
378 
380 {
381  error_t error;
382  systime_t time;
383  systime_t start;
384  PppContext *context;
385 
386  //Check parameters
387  if(interface == NULL)
389  //Make sure PPP has been properly configured
390  if(interface->pppContext == NULL)
391  return ERROR_NOT_CONFIGURED;
392 
393  //Point to the PPP context
394  context = interface->pppContext;
395  //Save current time
396  start = osGetSystemTime();
397 
398  //Wait for an incoming AT command
399  while(1)
400  {
401  //Get exclusive access
403 
404  //Check current PPP state
405  if(context->pppPhase == PPP_PHASE_DEAD)
406  {
407  //Wait for an incoming AT command
408  error = pppHdlcDriverReceiveAtCommand(interface, data, size);
409  }
410  else
411  {
412  //Report an error
413  error = ERROR_ALREADY_CONNECTED;
414  }
415 
416  //Release exclusive access
418 
419  //No data received?
420  if(error == ERROR_BUFFER_EMPTY || data[0] == '\0')
421  {
422  //Get current time
423  time = osGetSystemTime();
424 
425  //Check whether the timeout period has elapsed
426  if(timeCompare(time, start + context->timeout) >= 0)
427  {
428  //Timeout error
429  error = ERROR_TIMEOUT;
430  //Exit immediately
431  break;
432  }
433  else
434  {
435  //Wait for more data to be received
437  }
438  }
439  else
440  {
441  //We are done
442  break;
443  }
444  }
445 
446  //Return status code
447  return error;
448 }
449 
450 
451 /**
452  * @brief Establish a PPP connection
453  * @param[in] interface Underlying network interface
454  * @return Error code
455  **/
456 
458 {
459  error_t error;
460  PppContext *context;
461 #if (NET_RTOS_SUPPORT == ENABLED)
462  systime_t time;
463  systime_t start;
464 #endif
465 
466  //Check parameters
467  if(interface == NULL)
469  //Make sure PPP has been properly configured
470  if(interface->pppContext == NULL)
471  return ERROR_NOT_CONFIGURED;
472 
473  //Point to the PPP context
474  context = interface->pppContext;
475 
476  //Get exclusive access
478 
479  //Default PPP phase
480  context->pppPhase = PPP_PHASE_DEAD;
481 
482  //Initialize LCP FSM
483  context->lcpFsm.state = PPP_STATE_0_INITIAL;
484  context->lcpFsm.identifier = 0;
485  context->lcpFsm.restartCounter = 0;
486  context->lcpFsm.failureCounter = 0;
487 
488 #if (IPV4_SUPPORT == ENABLED)
489  //Initialize IPCP FSM
490  context->ipcpFsm.state = PPP_STATE_0_INITIAL;
491  context->ipcpFsm.identifier = 0;
492  context->ipcpFsm.restartCounter = 0;
493  context->ipcpFsm.failureCounter = 0;
494 #endif
495 
496 #if (IPV6_SUPPORT == ENABLED)
497  //Initialize IPV6CP FSM
498  context->ipv6cpFsm.state = PPP_STATE_0_INITIAL;
499  context->ipv6cpFsm.identifier = 0;
500  context->ipv6cpFsm.restartCounter = 0;
501  context->ipv6cpFsm.failureCounter = 0;
502 #endif
503 
504  //Authentication has not been completed
505  context->localAuthDone = FALSE;
506  context->peerAuthDone = FALSE;
507 
508 #if (PAP_SUPPORT == ENABLED)
509  //Initialize PAP FSM
510  context->papFsm.localState = PAP_STATE_0_INITIAL;
511  context->papFsm.peerState = PAP_STATE_0_INITIAL;
512  context->papFsm.identifier = 0;
513  context->papFsm.restartCounter = 0;
514 #endif
515 
516 #if (CHAP_SUPPORT == ENABLED)
517  //Initialize CHAP FSM
518  context->chapFsm.localState = CHAP_STATE_0_INITIAL;
519  context->chapFsm.localIdentifier = 0;
520  context->chapFsm.peerState = CHAP_STATE_0_INITIAL;
521  context->chapFsm.peerIdentifier = 0;
522 #endif
523 
524  //Default local configuration
525  context->localConfig.mru = context->settings.mru;
526  context->localConfig.mruRejected = FALSE;
527  context->localConfig.accm = context->settings.accm;
528  context->localConfig.accmRejected = FALSE;
529  context->localConfig.authProtocol = 0;
530  context->localConfig.authAlgo = 0;
531  context->localConfig.authProtocolRejected = FALSE;
532  context->localConfig.magicNumber = PPP_DEFAULT_MAGIC_NUMBER;
533  context->localConfig.magicNumberRejected = FALSE;
534  context->localConfig.pfc = TRUE;
535  context->localConfig.pfcRejected = FALSE;
536  context->localConfig.acfc = TRUE;
537  context->localConfig.acfcRejected = FALSE;
538 
539  //Check whether the other end of the PPP link must be authenticated
540  if(context->settings.authCallback != NULL)
541  {
542 #if (PAP_SUPPORT == ENABLED)
543  //PAP provides an easy implementation of peer authentication
544  if(context->settings.authProtocol & PPP_AUTH_PROTOCOL_PAP)
545  {
546  //Select PAP authentication protocol
547  context->localConfig.authProtocol = PPP_PROTOCOL_PAP;
548  }
549 #endif
550 #if (CHAP_SUPPORT == ENABLED)
551  //CHAP with MD5 ensures greater security in the implementation
552  if(context->settings.authProtocol & PPP_AUTH_PROTOCOL_CHAP_MD5)
553  {
554  //Select CHAP with MD5 authentication protocol
555  context->localConfig.authProtocol = PPP_PROTOCOL_CHAP;
556  context->localConfig.authAlgo = CHAP_ALGO_ID_CHAP_MD5;
557  }
558 #endif
559  }
560 
561  //Default peer's configuration
562  context->peerConfig.mru = PPP_DEFAULT_MRU;
563  context->peerConfig.accm = PPP_DEFAULT_ACCM;
564  context->peerConfig.authProtocol = 0;
565  context->peerConfig.magicNumber = PPP_DEFAULT_MAGIC_NUMBER;
566  context->peerConfig.pfc = FALSE;
567  context->peerConfig.acfc = FALSE;
568 
569 #if (IPV4_SUPPORT == ENABLED)
570  //Default local configuration
571  context->localConfig.ipAddr = interface->ipv4Context.addr;
572  context->localConfig.ipAddrRejected = FALSE;
573  context->localConfig.primaryDns = interface->ipv4Context.dnsServerList[0];
574  context->localConfig.primaryDnsRejected = FALSE;
575 
576 #if (IPV4_DNS_SERVER_LIST_SIZE >= 2)
577  context->localConfig.secondaryDns = interface->ipv4Context.dnsServerList[1];
578  context->localConfig.secondaryDnsRejected = FALSE;
579 #else
580  context->localConfig.secondaryDns = IPV4_UNSPECIFIED_ADDR;
581  context->localConfig.secondaryDnsRejected = FALSE;
582 #endif
583 
584  //Manual primary DNS configuration?
585  if(context->localConfig.primaryDns != IPV4_UNSPECIFIED_ADDR)
586  context->localConfig.primaryDnsRejected = TRUE;
587 
588  //Manual secondary DNS configuration?
589  if(context->localConfig.secondaryDns != IPV4_UNSPECIFIED_ADDR)
590  context->localConfig.secondaryDnsRejected = TRUE;
591 
592  //Default peer's configuration
593  context->peerConfig.ipAddr = interface->ipv4Context.defaultGateway;
594 #endif
595 
596 #if (IPV6_SUPPORT == ENABLED)
597  //Default local configuration
598  eui64CopyAddr(&context->localConfig.interfaceId,
599  interface->ipv6Context.addrList[0].addr.b + 8);
600 
601  context->localConfig.interfaceIdRejected = FALSE;
602 
603  //Default peer's configuration
604  eui64CopyAddr(&context->peerConfig.interfaceId,
605  interface->ipv6Context.routerList[0].addr.b + 8);
606 #endif
607 
608  //The link is available for traffic
609  error = lcpOpen(context);
610 
611  //Release exclusive access
613 
614  //Any error to report?
615  if(error)
616  return error;
617 
618 #if (NET_RTOS_SUPPORT == ENABLED)
619  //Save current time
620  start = osGetSystemTime();
621 
622  //Wait for the connection to be established
623  while(1)
624  {
625  //Check current PPP phase
626  if(context->pppPhase == PPP_PHASE_NETWORK)
627  {
628 #if (IPV4_SUPPORT == ENABLED)
629  //Check current IPCP state
630  if(context->ipcpFsm.state == PPP_STATE_9_OPENED)
631  {
632  //Connection successfully established
633  error = NO_ERROR;
634  //Exit immediately
635  break;
636  }
637 #endif
638 #if (IPV6_SUPPORT == ENABLED)
639  //Check current IPV6CP state
640  if(context->ipv6cpFsm.state == PPP_STATE_9_OPENED)
641  {
642  //Connection successfully established
643  error = NO_ERROR;
644  //Exit immediately
645  break;
646  }
647 #endif
648  }
649  else if(context->pppPhase == PPP_PHASE_DEAD)
650  {
651  //Failed to establish connection
652  error = ERROR_CONNECTION_FAILED;
653  //Exit immediately
654  break;
655  }
656 
657  //Check timeout value
658  if(context->timeout != INFINITE_DELAY)
659  {
660  //Get current time
661  time = osGetSystemTime();
662 
663  //Check whether the timeout period has elapsed
664  if(timeCompare(time, start + context->timeout) >= 0)
665  {
666  //Report an error
667  error = ERROR_TIMEOUT;
668  //Exit immediately
669  break;
670  }
671  }
672 
673  //Polling delay
675  }
676 
677  //Failed to establish connection?
678  if(error)
679  {
680  //Get exclusive access
682 
683  //Abort the PPP connection
684  context->pppPhase = PPP_PHASE_DEAD;
685  context->lcpFsm.state = PPP_STATE_0_INITIAL;
686 
687 #if (IPV4_SUPPORT == ENABLED)
688  //Reset IPCP finite state machine
689  context->ipcpFsm.state = PPP_STATE_0_INITIAL;
690 #endif
691 
692 #if (IPV6_SUPPORT == ENABLED)
693  //Reset IPV6CP finite state machine
694  context->ipv6cpFsm.state = PPP_STATE_0_INITIAL;
695 #endif
696 
697 #if (PAP_SUPPORT == ENABLED)
698  //Abort PAP authentication process
699  context->papFsm.localState = PAP_STATE_0_INITIAL;
700  context->papFsm.peerState = PAP_STATE_0_INITIAL;
701 #endif
702 
703 #if (CHAP_SUPPORT == ENABLED)
704  //Abort CHAP authentication process
705  context->chapFsm.localState = CHAP_STATE_0_INITIAL;
706  context->chapFsm.peerState = CHAP_STATE_0_INITIAL;
707 #endif
708 
709  //Release exclusive access
711  }
712 #endif
713 
714  //Return status code
715  return error;
716 }
717 
718 
719 /**
720  * @brief Close a PPP connection
721  * @param[in] interface Underlying network interface
722  * @return Error code
723  **/
724 
726 {
727  error_t error;
728  PppContext *context;
729 #if (NET_RTOS_SUPPORT == ENABLED)
730  systime_t time;
731  systime_t start;
732 #endif
733 
734  //Check parameters
735  if(interface == NULL)
737  //Make sure PPP has been properly configured
738  if(interface->pppContext == NULL)
739  return ERROR_NOT_CONFIGURED;
740 
741  //Point to the PPP context
742  context = interface->pppContext;
743 
744  //Get exclusive access
746 
747  //The link is no longer available for traffic
748  error = lcpClose(context);
749 
750  //Release exclusive access
752 
753  //Any error to report?
754  if(error)
755  return error;
756 
757 #if (NET_RTOS_SUPPORT == ENABLED)
758  //Save current time
759  start = osGetSystemTime();
760 
761  //Wait for the connection to be closed
762  while(1)
763  {
764  //Check current PPP phase
765  if(context->pppPhase == PPP_PHASE_DEAD)
766  {
767  //PPP connection is closed
768  error = NO_ERROR;
769  //Exit immediately
770  break;
771  }
772 
773  //Check timeout value
774  if(context->timeout != INFINITE_DELAY)
775  {
776  //Get current time
777  time = osGetSystemTime();
778 
779  //Check whether the timeout period has elapsed
780  if(timeCompare(time, start + context->timeout) >= 0)
781  {
782  //Report an error
783  error = ERROR_TIMEOUT;
784  //Exit immediately
785  break;
786  }
787  }
788 
789  //Poll the state
791  }
792 
793  //Failed to properly close the connection?
794  if(error)
795  {
796  //Get exclusive access
798 
799  //Abort the PPP connection
800  context->pppPhase = PPP_PHASE_DEAD;
801  context->lcpFsm.state = PPP_STATE_0_INITIAL;
802 
803 #if (IPV4_SUPPORT == ENABLED)
804  //Reset IPCP finite state machine
805  context->ipcpFsm.state = PPP_STATE_0_INITIAL;
806 #endif
807 
808 #if (IPV6_SUPPORT == ENABLED)
809  //Reset IPV6CP finite state machine
810  context->ipv6cpFsm.state = PPP_STATE_0_INITIAL;
811 #endif
812 
813 #if (PAP_SUPPORT == ENABLED)
814  //Abort PAP authentication process
815  context->papFsm.localState = PAP_STATE_0_INITIAL;
816  context->papFsm.peerState = PAP_STATE_0_INITIAL;
817 #endif
818 
819 #if (CHAP_SUPPORT == ENABLED)
820  //Abort CHAP authentication process
821  context->chapFsm.localState = CHAP_STATE_0_INITIAL;
822  context->chapFsm.peerState = CHAP_STATE_0_INITIAL;
823 #endif
824 
825  //Release exclusive access
827  }
828 #endif
829 
830  //Return status code
831  return error;
832 }
833 
834 
835 /**
836  * @brief PPP timer handler
837  *
838  * This routine must be periodically called by the TCP/IP stack to
839  * manage retransmissions
840  *
841  * @param[in] interface Underlying network interface
842  **/
843 
844 void pppTick(NetInterface *interface)
845 {
846  PppContext *context;
847 
848  //PPP driver?
849  if(interface->nicDriver->type == NIC_TYPE_PPP)
850  {
851  //Point to the PPP context
852  context = interface->pppContext;
853 
854  //Handle LCP retransmission timer
855  lcpTick(context);
856 
857 #if (IPV4_SUPPORT == ENABLED)
858  //Handle IPCP retransmission timer
859  ipcpTick(context);
860 #endif
861 
862 #if (IPV6_SUPPORT == ENABLED)
863  //Handle IPV6CP retransmission timer
864  ipv6cpTick(context);
865 #endif
866 
867 #if (PAP_SUPPORT == ENABLED)
868  //Handle PAP timer
869  papTick(context);
870 #endif
871 
872 #if (CHAP_SUPPORT == ENABLED)
873  //Handle CHAP timer
874  chapTick(context);
875 #endif
876  }
877 }
878 
879 
880 /**
881  * @brief Process an incoming PPP frame
882  * @param[in] interface Underlying network interface
883  * @param[in] frame Incoming PPP frame to process
884  * @param[in] length Total frame length
885  **/
886 
887 void pppProcessFrame(NetInterface *interface, uint8_t *frame, size_t length)
888 {
889  size_t n;
890  uint16_t protocol;
891  PppContext *context;
892 #if (IPV6_SUPPORT == ENABLED)
893  NetBuffer1 buffer;
894 #endif
895 
896  //Point to the PPP context
897  context = interface->pppContext;
898 
899  //Check the length of the PPP frame
900  if(length < PPP_FCS_SIZE)
901  return;
902 
903  //Debug message
904  TRACE_DEBUG("PPP frame received (%" PRIuSIZE " bytes)...\r\n", length);
905 
906  //The value of the residue is 0x0F47 when no FCS errors are detected
907  if(pppCalcFcs(frame, length) != 0x0F47)
908  {
909  //Debug message
910  TRACE_WARNING("Wrong FCS detected!\r\n");
911  //Drop the received frame
912  return;
913  }
914 
915  //Calculate the length of PPP frame excluding the FCS field
916  length -= PPP_FCS_SIZE;
917 
918  //Decompress the frame header
919  n = pppParseFrameHeader(frame, length, &protocol);
920  //Malformed PPP frame?
921  if(!n)
922  return;
923 
924  //Point to the payload field
925  frame += n;
926  length -= n;
927 
928  //Check protocol field
929  switch(protocol)
930  {
931  //Link control protocol?
932  case PPP_PROTOCOL_LCP:
933  //Process incoming LCP packet
934  lcpProcessPacket(context, (PppPacket *) frame, length);
935  break;
936 
937 #if (IPV4_SUPPORT == ENABLED)
938  //IP control protocol?
939  case PPP_PROTOCOL_IPCP:
940  //Process incoming IPCP packet
941  ipcpProcessPacket(context, (PppPacket *) frame, length);
942  break;
943  //IP protocol?
944  case PPP_PROTOCOL_IP:
945  //Process incoming IPv4 packet
946  ipv4ProcessPacket(interface, (Ipv4Header *) frame, length);
947  break;
948 #endif
949 
950 #if (IPV6_SUPPORT == ENABLED)
951  //IPv6 control protocol?
952  case PPP_PROTOCOL_IPV6CP:
953  //Process incoming IPV6CP packet
954  ipv6cpProcessPacket(context, (PppPacket *) frame, length);
955  break;
956  //IPv6 protocol?
957  case PPP_PROTOCOL_IPV6:
958  //The incoming PPP frame fits in a single chunk
959  buffer.chunkCount = 1;
960  buffer.maxChunkCount = 1;
961  buffer.chunk[0].address = frame;
962  buffer.chunk[0].length = (uint16_t) length;
963  buffer.chunk[0].size = 0;
964 
965  //Process incoming IPv6 packet
966  ipv6ProcessPacket(interface, (NetBuffer *) &buffer, 0);
967  break;
968 #endif
969 
970 #if (PAP_SUPPORT == ENABLED)
971  //PAP protocol?
972  case PPP_PROTOCOL_PAP:
973  //Process incoming PAP packet
974  papProcessPacket(context, (PppPacket *) frame, length);
975  break;
976 #endif
977 
978 #if (CHAP_SUPPORT == ENABLED)
979  //CHAP protocol?
980  case PPP_PROTOCOL_CHAP:
981  //Process incoming CHAP packet
982  chapProcessPacket(context, (PppPacket *) frame, length);
983  break;
984 #endif
985 
986  //Unknown protocol field
987  default:
988  //The peer is attempting to use a protocol which is unsupported
989  lcpProcessUnknownProtocol(context, protocol, frame, length);
990  break;
991  }
992 }
993 
994 
995 /**
996  * @brief Send a PPP frame
997  * @param[in] interface Underlying network interface
998  * @param[in] buffer Multi-part buffer containing the data
999  * @param[in] offset Offset to the first data byte
1000  * @param[in] protocol Protocol field value
1001  * @return Error code
1002  **/
1003 
1005  NetBuffer *buffer, size_t offset, uint16_t protocol)
1006 {
1007  error_t error;
1008  size_t length;
1009  uint16_t fcs;
1010  uint8_t *p;
1011  PppContext *context;
1012 
1013  //Point to the PPP context
1014  context = interface->pppContext;
1015 
1016  //Check whether the Protocol field can be compressed
1017  if(context->peerConfig.pfc && MSB(protocol) == 0)
1018  {
1019  //Is there enough space in the buffer to store the compressed
1020  //Protocol field?
1021  if(offset < 1)
1022  return ERROR_FAILURE;
1023 
1024  //Make room for the Protocol field
1025  offset--;
1026  //Move backward
1027  p = netBufferAt(buffer, offset);
1028  //Compress the Protocol field
1029  p[0] = LSB(protocol);
1030  }
1031  else
1032  {
1033  //Is there enough space in the buffer to store the uncompressed
1034  //Protocol field?
1035  if(offset < 2)
1036  return ERROR_FAILURE;
1037 
1038  //Make room for the Protocol field
1039  offset -= 2;
1040  //Move backward
1041  p = netBufferAt(buffer, offset);
1042  //Do not compress the Protocol field
1043  p[0] = MSB(protocol);
1044  p[1] = LSB(protocol);
1045  }
1046 
1047  //Check whether the Address and Control fields can be compressed
1048  if(context->peerConfig.acfc && protocol != PPP_PROTOCOL_LCP)
1049  {
1050  //On transmission, compressed Address and Control fields
1051  //are simply omitted...
1052  }
1053  else
1054  {
1055  //Is there enough space in the buffer to store the uncompressed
1056  //Address and Control fields?
1057  if(offset < 2)
1058  return ERROR_FAILURE;
1059 
1060  //Make room for the Address and Control fields
1061  offset -= 2;
1062  //Move backward
1063  p = netBufferAt(buffer, offset);
1064  //Do not compress the Address and Control fields
1065  p[0] = PPP_ADDR_FIELD;
1066  p[1] = PPP_CTRL_FIELD;
1067  }
1068 
1069  //Retrieve the length of the frame
1070  length = netBufferGetLength(buffer) - offset;
1071 
1072  //Compute FCS over the header and payload
1073  fcs = pppCalcFcsEx(buffer, offset, length);
1074  //The FCS is transmitted least significant octet first
1075  fcs = htole16(fcs);
1076 
1077  //Append the calculated FCS value
1078  error = netBufferAppend(buffer, &fcs, PPP_FCS_SIZE);
1079  //Any error to report?
1080  if(error)
1081  return error;
1082 
1083  //Adjust frame length
1084  length += PPP_FCS_SIZE;
1085 
1086  //Debug message
1087  TRACE_DEBUG("Sending PPP frame (%" PRIuSIZE " bytes)...\r\n", length);
1088  TRACE_DEBUG(" Protocol = 0x%04" PRIX16 "\r\n", protocol);
1089 
1090  //Send the resulting frame over the specified link
1091  error = nicSendPacket(interface, buffer, offset);
1092  //Return status code
1093  return error;
1094 }
1095 
1096 
1097 /**
1098  * @brief Parse PPP frame header
1099  * @param[in] frame Pointer to the PPP frame
1100  * @param[in] length Length of the frame, in bytes
1101  * @param[out] protocol Value of the Protocol field
1102  * @return If the PPP header was successfully parsed, the function returns the size
1103  * of the PPP header, in bytes. If a parsing error occurred, zero is returned
1104  **/
1105 
1106 size_t pppParseFrameHeader(const uint8_t *frame, size_t length, uint16_t *protocol)
1107 {
1108  size_t n;
1109 
1110  //Size of the PPP header, in bytes
1111  n = 0;
1112 
1113  //On reception, the Address and Control fields are decompressed by
1114  //examining the first two octets
1115  if(length >= 2)
1116  {
1117  //If they contain the values 0xff and 0x03, they are assumed to be
1118  //the Address and Control fields. If not, it is assumed that the
1119  //fields were compressed and were not transmitted
1120  if(frame[0] == PPP_ADDR_FIELD && frame[1] == PPP_CTRL_FIELD)
1121  {
1122  //Move to the Protocol field
1123  n = 2;
1124  }
1125  }
1126 
1127  //Check the length of the PPP frame
1128  if(length >= (n + 1))
1129  {
1130  //PPP Protocol field numbers are chosen such that some values may be
1131  //compressed into a single octet form which is clearly distinguishable
1132  //from the two octet form
1133  if(frame[n] & 0x01)
1134  {
1135  //The presence of a binary 1 as the LSB marks the last octet of
1136  //the Protocol field
1137  *protocol = frame[n];
1138 
1139  //Update the length of the header
1140  n++;
1141  }
1142  else
1143  {
1144  //Check the length of the PPP frame
1145  if(length >= (n + 2))
1146  {
1147  //The Protocol field is not compressed
1148  *protocol = (frame[n] << 8) | frame[n + 1];
1149 
1150  //Update the length of the header
1151  n += 2;
1152  }
1153  else
1154  {
1155  //Malformed PPP frame
1156  n = 0;
1157  }
1158  }
1159  }
1160  else
1161  {
1162  //Malformed PPP frame
1163  n = 0;
1164  }
1165 
1166  //Return the size of the PPP header, in bytes
1167  return n;
1168 }
1169 
1170 
1171 /**
1172  * @brief FCS calculation
1173  * @param[in] data Pointer to the data over which to calculate the FCS
1174  * @param[in] length Number of bytes to process
1175  * @return Resulting FCS value
1176  **/
1177 
1178 uint16_t pppCalcFcs(const uint8_t *data, size_t length)
1179 {
1180  size_t i;
1181  uint16_t fcs;
1182 
1183  //FCS preset value
1184  fcs = 0xFFFF;
1185 
1186  //Loop through data
1187  for(i = 0; i < length; i++)
1188  {
1189  //The message is processed byte by byte
1190  fcs = (fcs >> 8) ^ fcsTable[(fcs & 0xFF) ^ data[i]];
1191  }
1192 
1193  //Return 1's complement value
1194  return ~fcs;
1195 }
1196 
1197 
1198 /**
1199  * @brief Calculate FCS over a multi-part buffer
1200  * @param[in] buffer Pointer to the multi-part buffer
1201  * @param[in] offset Offset from the beginning of the buffer
1202  * @param[in] length Number of bytes to process
1203  * @return Resulting FCS value
1204  **/
1205 
1206 uint16_t pppCalcFcsEx(const NetBuffer *buffer, size_t offset, size_t length)
1207 {
1208  uint_t i;
1209  uint_t n;
1210  uint16_t fcs;
1211  uint8_t *p;
1212 
1213  //FCS preset value
1214  fcs = 0xFFFF;
1215 
1216  //Loop through data chunks
1217  for(i = 0; i < buffer->chunkCount && length > 0; i++)
1218  {
1219  //Is there any data to process in the current chunk?
1220  if(offset < buffer->chunk[i].length)
1221  {
1222  //Point to the first data byte
1223  p = (uint8_t *) buffer->chunk[i].address + offset;
1224  //Compute the number of bytes to process
1225  n = MIN(buffer->chunk[i].length - offset, length);
1226  //Adjust byte counter
1227  length -= n;
1228 
1229  //Process current chunk
1230  while(n > 0)
1231  {
1232  //The message is processed byte by byte
1233  fcs = (fcs >> 8) ^ fcsTable[(fcs & 0xFF) ^ *p];
1234 
1235  //Next byte
1236  p++;
1237  n--;
1238  }
1239 
1240  //Process the next block from the start
1241  offset = 0;
1242  }
1243  else
1244  {
1245  //Skip the current chunk
1246  offset -= buffer->chunk[i].length;
1247  }
1248  }
1249 
1250  //Return 1's complement value
1251  return ~fcs;
1252 }
1253 
1254 
1255 /**
1256  * @brief Allocate a buffer to hold a PPP frame
1257  * @param[in] length Desired payload length
1258  * @param[out] offset Offset to the first byte of the payload
1259  * @return The function returns a pointer to the newly allocated
1260  * buffer. If the system is out of resources, NULL is returned
1261  **/
1262 
1263 NetBuffer *pppAllocBuffer(size_t length, size_t *offset)
1264 {
1265  NetBuffer *buffer;
1266 
1267  //Allocate a buffer to hold the Ethernet header and the payload
1269  //Failed to allocate buffer?
1270  if(buffer == NULL)
1271  return NULL;
1272 
1273  //Offset to the first byte of the payload
1274  *offset = PPP_FRAME_HEADER_SIZE;
1275 
1276  //Return a pointer to the freshly allocated buffer
1277  return buffer;
1278 }
1279 
1280 #endif
PPP (Point-to-Point Protocol)
uint32_t systime_t
Definition: compiler_port.h:44
#define timeCompare(t1, t2)
Definition: os_port.h:40
char char_t
Definition: compiler_port.h:41
#define PPP_POLLING_INTERVAL
Definition: ppp.h:87
uint32_t accm
Default async control character map.
Definition: ppp.h:382
systime_t osGetSystemTime(void)
Retrieve system time.
#define MSB(x)
Definition: os_port.h:56
uint32_t time
#define PPP_DEFAULT_MAGIC_NUMBER
Definition: ppp.h:130
IPV6CP (PPP IPv6 Control Protocol)
Data logging functions for debugging purpose (PPP)
TCP/IP stack core.
Debugging facilities.
void ipv6cpProcessPacket(PppContext *context, const PppPacket *packet, size_t length)
Process an incoming IPV6CP packet.
Definition: ipv6cp.c:150
uint_t chunkCount
Definition: net_mem.h:96
uint8_t p
Definition: ndp.h:295
uint_t maxChunkCount
Definition: net_mem.h:97
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:295
PppAuthCallback authCallback
PPP authentication callback function.
Definition: ppp.h:385
PAP (Password Authentication Protocol)
error_t pppReceiveAtCommand(NetInterface *interface, char_t *data, size_t size)
Wait for an incoming AT command.
Definition: ppp.c:379
Generic error code.
Definition: error.h:43
error_t pppClose(NetInterface *interface)
Close a PPP connection.
Definition: ppp.c:725
bool_t papCheckPassword(PppContext *context, const char_t *password)
Password verification.
Definition: pap.c:600
Invalid parameter.
Definition: error.h:45
error_t pppSetTimeout(NetInterface *interface, systime_t timeout)
Set timeout value for blocking operations.
Definition: ppp.c:195
Network-layer protocol phase.
Definition: ppp.h:167
IPv6 Control Protocol.
Definition: ppp.h:200
error_t lcpClose(PppContext *context)
LCP Close event.
Definition: lcp.c:101
void ipv6ProcessPacket(NetInterface *interface, NetBuffer *ipPacket, size_t ipPacketOffset)
Incoming IPv6 packet processing.
Definition: ipv6.c:885
error_t pppSendAtCommand(NetInterface *interface, const char_t *data)
Send AT command.
Definition: ppp.c:316
PPP interface.
Definition: nic.h:70
PPP HDLC driver.
#define eui64CopyAddr(destEui64Addr, srcEui64Addr)
Definition: ethernet.h:101
String manipulation helper functions.
error_t nicSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset)
Send a packet to the network controller.
Definition: nic.c:148
void chapProcessPacket(PppContext *context, const PppPacket *packet, size_t length)
Process an incoming CHAP packet.
Definition: chap.c:147
NetInterface * interface
Underlying network interface.
Definition: ppp.h:380
void papProcessPacket(PppContext *context, const PppPacket *packet, size_t length)
Process an incoming PAP packet.
Definition: pap.c:147
#define LSB(x)
Definition: os_port.h:52
uint_t authProtocol
Allowed authentication protocols.
Definition: ppp.h:383
#define PPP_CTRL_FIELD
PPP Control field.
Definition: ppp.h:150
void * address
Definition: net_mem.h:76
#define PppPacket
Definition: ppp.h:35
void lcpProcessPacket(PppContext *context, const PppPacket *packet, size_t length)
Process an incoming LCP packet.
Definition: lcp.c:153
IP Control Protocol.
Definition: ppp.h:199
uint16_t pppCalcFcsEx(const NetBuffer *buffer, size_t offset, size_t length)
Calculate FCS over a multi-part buffer.
Definition: ppp.c:1206
error_t lcpOpen(PppContext *context)
LCP Open event.
Definition: lcp.c:77
#define PPP_MAX_USERNAME_LEN
Definition: ppp.h:66
#define TRUE
Definition: os_port.h:48
PPP settings.
Definition: ppp.h:378
error_t lcpProcessUnknownProtocol(PppContext *context, uint16_t protocol, const uint8_t *information, size_t length)
Process PPP frame with unknown protocol.
Definition: lcp.c:828
Password Authentication Protocol.
Definition: ppp.h:202
error_t pppConnect(NetInterface *interface)
Establish a PPP connection.
Definition: ppp.c:457
ChunkDesc chunk[]
Definition: net_mem.h:90
uint16_t size
Definition: net_mem.h:78
bool_t chapCheckPassword(PppContext *context, const char_t *password)
Password verification.
Definition: chap.c:710
void lcpTick(PppContext *context)
LCP timer handler.
Definition: lcp.c:123
#define PPP_DEFAULT_MRU
Definition: ppp.h:126
void * netBufferAt(const NetBuffer *buffer, size_t offset)
Returns a pointer to the data at the specified position.
Definition: net_mem.c:411
void ipv6cpTick(PppContext *context)
IPV6CP timer handler.
Definition: ipv6cp.c:120
#define PPP_FRAME_HEADER_SIZE
Definition: ppp.h:141
ChunkDesc chunk[1]
Definition: net_mem.h:98
const NicDriver pppHdlcDriver
PPP HDLC driver.
Definition: ppp_hdlc.c:47
error_t pppHdlcDriverReceiveAtCommand(NetInterface *interface, char_t *data, size_t size)
Wait for an incoming AT command.
Definition: ppp_hdlc.c:421
error_t pppSetAuthInfo(NetInterface *interface, const char_t *username, const char_t *password)
Set PPP authentication information.
Definition: ppp.c:231
#define INFINITE_DELAY
Definition: os_port.h:72
void ipcpProcessPacket(PppContext *context, const PppPacket *packet, size_t length)
Process an incoming IPCP packet.
Definition: ipcp.c:149
LCP (PPP Link Control Protocol)
size_t pppParseFrameHeader(const uint8_t *frame, size_t length, uint16_t *protocol)
Parse PPP frame header.
Definition: ppp.c:1106
void osDelayTask(systime_t delay)
Delay routine.
NetInterface * netGetDefaultInterface(void)
Get default network interface.
Definition: net.c:1495
uint16_t mru
Default MRU.
Definition: ppp.h:381
CHAP (Challenge Handshake Authentication Protocol)
void chapTick(PppContext *context)
CHAP timer handler.
Definition: chap.c:108
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:86
#define MIN(a, b)
Definition: os_port.h:60
void pppGetDefaultSettings(PppSettings *settings)
Initialize settings with default values.
Definition: ppp.c:94
#define PppContext
Definition: ppp.h:36
NetBuffer * netBufferAlloc(size_t length)
Allocate a multi-part buffer.
Definition: net_mem.c:241
bool_t pppCheckPassword(NetInterface *interface, const char_t *password)
Password verification.
Definition: ppp.c:269
#define TRACE_INFO(...)
Definition: debug.h:86
#define PPP_FCS_SIZE
Definition: ppp.h:143
systime_t pppTickCounter
Definition: ppp.c:49
Success.
Definition: error.h:42
uint16_t length
Definition: net_mem.h:77
void papTick(PppContext *context)
PAP timer handler.
Definition: pap.c:108
error_t
Error codes.
Definition: error.h:40
#define TRACE_WARNING(...)
Definition: debug.h:78
bool_t osWaitForEvent(OsEvent *event, systime_t timeout)
Wait until the specified event is in the signaled state.
unsigned int uint_t
Definition: compiler_port.h:43
error_t netBufferAppend(NetBuffer *dest, const void *src, size_t length)
Append data a multi-part buffer.
Definition: net_mem.c:584
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
error_t strSafeCopy(char_t *dest, const char_t *src, size_t destSize)
Copy string.
Definition: str.c:157
error_t netSetDriver(NetInterface *interface, const NicDriver *driver)
Set Ethernet MAC driver.
Definition: net.c:668
uint16_t pppCalcFcs(const uint8_t *data, size_t length)
FCS calculation.
Definition: ppp.c:1178
uint8_t data[]
Definition: dtls_misc.h:167
#define PRIuSIZE
Definition: compiler_port.h:72
#define NetInterface
Definition: net.h:34
Internet Protocol.
Definition: ppp.h:197
Challenge Handshake Authentication Protocol.
Definition: ppp.h:204
Link Control Protocol.
Definition: ppp.h:201
error_t pppInit(PppContext *context, const PppSettings *settings)
PPP initialization.
Definition: ppp.c:120
#define Ipv4Header
Definition: ipv4.h:34
#define PPP_MAX_PASSWORD_LEN
Definition: ppp.h:73
error_t pppHdlcDriverPurgeRxBuffer(PppContext *context)
Purge RX buffer.
Definition: ppp_hdlc.c:528
#define IPV4_UNSPECIFIED_ADDR
Definition: ipv4.h:95
error_t pppSendFrame(NetInterface *interface, NetBuffer *buffer, size_t offset, uint16_t protocol)
Send a PPP frame.
Definition: ppp.c:1004
OsMutex netMutex
Definition: net.c:70
Internet Protocol version 6.
Definition: ppp.h:198
#define htole16(value)
Definition: cpu_endian.h:403
#define PPP_ADDR_FIELD
Definition: ppp.h:148
Link dead.
Definition: ppp.h:164
uint8_t protocol
PppRandCallback randCallback
Random data generation callback function.
Definition: ppp.h:384
void pppTick(NetInterface *interface)
PPP timer handler.
Definition: ppp.c:844
uint8_t length
Definition: dtls_misc.h:140
uint8_t n
#define PPP_DEFAULT_ACCM
Definition: ppp.h:128
#define FALSE
Definition: os_port.h:44
IPCP (PPP Internet Protocol Control Protocol)
void ipcpTick(PppContext *context)
IPCP timer handler.
Definition: ipcp.c:119
int bool_t
Definition: compiler_port.h:47
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void ipv4ProcessPacket(NetInterface *interface, Ipv4Header *packet, size_t length)
Incoming IPv4 packet processing.
Definition: ipv4.c:440
error_t pppHdlcDriverSendAtCommand(NetInterface *interface, const char_t *data)
Send AT command.
Definition: ppp_hdlc.c:386
uint_t chunkCount
Definition: net_mem.h:88
#define TRACE_DEBUG(...)
Definition: debug.h:98
void pppProcessFrame(NetInterface *interface, uint8_t *frame, size_t length)
Process an incoming PPP frame.
Definition: ppp.c:887
NetBuffer * pppAllocBuffer(size_t length, size_t *offset)
Allocate a buffer to hold a PPP frame.
Definition: ppp.c:1263