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