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