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