lcp.c
Go to the documentation of this file.
1 /**
2  * @file lcp.c
3  * @brief LCP (PPP Link Control 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_fsm.h"
37 #include "ppp/ppp_misc.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 "debug.h"
45 
46 //Check TCP/IP stack configuration
47 #if (PPP_SUPPORT == ENABLED)
48 
49 
50 /**
51  * @brief LCP FSM callbacks
52  **/
53 
55 {
70 };
71 
72 
73 /**
74  * @brief LCP Open event
75  * @param[in] context PPP context
76  * @return Error code
77  **/
78 
80 {
81  //Debug message
82  TRACE_INFO("\r\nLCP Open event\r\n");
83 
84  //Advance to the Establish phase
85  context->pppPhase = PPP_PHASE_ESTABLISH;
86 
87  //The link is administratively available for traffic
88  pppOpenEvent(context, &context->lcpFsm, &lcpCallbacks);
89  //The lower layer is ready to carry packets
90  pppUpEvent(context, &context->lcpFsm, &lcpCallbacks);
91 
92  //Successful processing
93  return NO_ERROR;
94 }
95 
96 
97 /**
98  * @brief LCP Close event
99  * @param[in] context PPP context
100  * @return Error code
101  **/
102 
104 {
105  //Debug message
106  TRACE_INFO("\r\nLCP Close event\r\n");
107 
108  //The link is no longer available for traffic
109  pppCloseEvent(context, &context->lcpFsm, &lcpCallbacks);
110 
111  //Successful processing
112  return NO_ERROR;
113 }
114 
115 
116 /**
117  * @brief LCP timer handler
118  *
119  * This routine must be periodically called by the TCP/IP stack to
120  * manage retransmissions
121  *
122  * @param[in] context PPP context
123  **/
124 
125 void lcpTick(PppContext *context)
126 {
127  //Check whether the restart timer is running
128  if(context->lcpFsm.state >= PPP_STATE_4_CLOSING &&
129  context->lcpFsm.state <= PPP_STATE_8_ACK_SENT)
130  {
131  //Get current time
133 
134  //Check restart timer
135  if((time - context->lcpFsm.timestamp) >= PPP_RESTART_TIMER)
136  {
137  //Debug message
138  TRACE_INFO("\r\nLCP Timeout event\r\n");
139 
140  //The restart timer is used to retransmit Configure-Request
141  //and Terminate-Request packets
142  pppTimeoutEvent(context, &context->lcpFsm, &lcpCallbacks);
143  }
144  }
145 }
146 
147 
148 /**
149  * @brief Process an incoming LCP packet
150  * @param[in] context PPP context
151  * @param[in] packet LCP packet received from the peer
152  * @param[in] length Length of the packet, in bytes
153  **/
154 
155 void lcpProcessPacket(PppContext *context, const PppPacket *packet, size_t length)
156 {
157  //Ensure the length of the incoming LCP packet is valid
158  if(length < sizeof(PppPacket))
159  return;
160 
161  //Check the length field
162  if(ntohs(packet->length) > length)
163  return;
164  if(ntohs(packet->length) < sizeof(PppPacket))
165  return;
166 
167  //Save the length of the LCP packet
168  length = ntohs(packet->length);
169 
170  //Debug message
171  TRACE_INFO("LCP packet received (%" PRIuSIZE " bytes)...\r\n", length);
172  //Dump LCP packet contents for debugging purpose
174 
175  //Check LCP code field
176  switch(packet->code)
177  {
178  //Configure-Request packet?
180  //Process Configure-Request packet
181  lcpProcessConfigureReq(context, (PppConfigurePacket *) packet);
182  break;
183  //Configure-Ack packet?
185  //Process Configure-Ack packet
186  lcpProcessConfigureAck(context, (PppConfigurePacket *) packet);
187  break;
188  //Configure-Nak packet?
190  //Process Configure-Nak packet
191  lcpProcessConfigureNak(context, (PppConfigurePacket *) packet);
192  break;
193  //Configure-Reject packet?
195  //Process Configure-Reject packet
196  lcpProcessConfigureReject(context, (PppConfigurePacket *) packet);
197  break;
198  //Terminate-Request packet?
200  //Process Terminate-Request packet
201  lcpProcessTerminateReq(context, (PppTerminatePacket *) packet);
202  break;
203  //Terminate-Ack packet?
205  //Process Terminate-Ack packet
206  lcpProcessTerminateAck(context, (PppTerminatePacket *) packet);
207  break;
208  //Code-Reject packet?
209  case PPP_CODE_CODE_REJ:
210  //Process Code-Reject packet
211  lcpProcessCodeRej(context, (PppCodeRejPacket *) packet);
212  break;
213  //Protocol-Reject packet?
215  //Process Protocol-Reject packet
216  lcpProcessProtocolRej(context, (PppProtocolRejPacket *) packet);
217  break;
218  //Echo-Request packet?
219  case PPP_CODE_ECHO_REQ:
220  //Process Echo-Request packet
221  lcpProcessEchoReq(context, (PppEchoPacket *) packet);
222  break;
223  //Echo-Reply packet?
224  case PPP_CODE_ECHO_REP:
225  //Process Echo-Reply packet
226  lcpProcessEchoRep(context, (PppEchoPacket *) packet);
227  break;
228  //Discard-Request packet?
230  //Process Discard-Request packet
231  lcpProcessDiscardReq(context, (PppDiscardReqPacket *) packet);
232  break;
233  //Unknown code field
234  default:
235  //The packet is un-interpretable
236  lcpProcessUnknownCode(context, packet);
237  break;
238  }
239 }
240 
241 
242 /**
243  * @brief Process Configure-Request packet
244  * @param[in] context PPP context
245  * @param[in] configureReqPacket Packet received from the peer
246  * @return Error code
247  **/
248 
250  const PppConfigurePacket *configureReqPacket)
251 {
252  error_t error;
253  size_t length;
254  bool_t notRecognizable;
255  bool_t notAcceptable;
256  PppOption *option;
257 
258  //Debug message
259  TRACE_INFO("\r\nLCP Receive-Configure-Request event\r\n");
260 
261  //Initialize variables
262  error = NO_ERROR;
263  notRecognizable = FALSE;
264  notAcceptable = FALSE;
265 
266  //Retrieve the length of the option list
267  length = ntohs(configureReqPacket->length) - sizeof(PppConfigurePacket);
268  //Point to the first option
269  option = (PppOption *) configureReqPacket->options;
270 
271  //Parse configuration options
272  while(length > 0)
273  {
274  //Parse current option
275  error = lcpParseOption(context, option, length, NULL);
276 
277  //Any error to report?
278  if(error == ERROR_INVALID_TYPE)
279  {
280  //Option not recognizable
281  notRecognizable = TRUE;
282  //Catch error
283  error = NO_ERROR;
284  }
285  else if(error == ERROR_INVALID_VALUE)
286  {
287  //Option not acceptable for configuration
288  notAcceptable = TRUE;
289  //Catch error
290  error = NO_ERROR;
291  }
292  else if(error)
293  {
294  //Malformed Configure-Request packet
295  break;
296  }
297 
298  //Remaining bytes to process
299  length -= option->length;
300  //Jump to the next option
301  option = (PppOption *) ((uint8_t *) option + option->length);
302  }
303 
304  //Valid Configure-Request packet received from the peer?
305  if(!error)
306  {
307  //Check flags
308  if(notRecognizable)
309  {
310  //If some configuration options received in the Configure-Request are not
311  //recognizable or not acceptable for negotiation, then the implementation
312  //must transmit a Configure-Reject
313  pppRcvConfigureReqEvent(context, &context->lcpFsm, &lcpCallbacks,
314  configureReqPacket, PPP_CODE_CONFIGURE_REJ);
315  }
316  else if(notAcceptable)
317  {
318  //If all configuration options are recognizable, but some values are not
319  //acceptable, then the implementation must transmit a Configure-Nak
320  pppRcvConfigureReqEvent(context, &context->lcpFsm, &lcpCallbacks,
321  configureReqPacket, PPP_CODE_CONFIGURE_NAK);
322  }
323  else
324  {
325  //If every configuration option received in the Configure-Request is
326  //recognizable and all values are acceptable, then the implementation
327  //must transmit a Configure-Ack
328  pppRcvConfigureReqEvent(context, &context->lcpFsm, &lcpCallbacks,
329  configureReqPacket, PPP_CODE_CONFIGURE_ACK);
330  }
331  }
332 
333  //Return status code
334  return error;
335 }
336 
337 
338 /**
339  * @brief Process Configure-Ack packet
340  * @param[in] context PPP context
341  * @param[in] configureAckPacket Packet received from the peer
342  * @return Error code
343  **/
344 
346  const PppConfigurePacket *configureAckPacket)
347 {
348  //Debug message
349  TRACE_INFO("\r\nLCP Receive-Configure-Ack event\r\n");
350 
351  //When a packet is received with an invalid Identifier field, the
352  //packet is silently discarded without affecting the automaton
353  if(configureAckPacket->identifier != context->lcpFsm.identifier)
354  return ERROR_WRONG_IDENTIFIER;
355 
356  //A valid Configure-Ack packet has been received from the peer
357  pppRcvConfigureAckEvent(context, &context->lcpFsm, &lcpCallbacks);
358 
359  //Successful processing
360  return NO_ERROR;
361 }
362 
363 
364 /**
365  * @brief Process Configure-Nak packet
366  * @param[in] context PPP context
367  * @param[in] configureNakPacket Packet received from the peer
368  * @return Error code
369  **/
370 
372  const PppConfigurePacket *configureNakPacket)
373 {
374  size_t length;
375  PppOption *option;
376 
377  //Debug message
378  TRACE_INFO("LCP Receive-Configure-Nak event\r\n");
379 
380  //When a packet is received with an invalid Identifier field, the
381  //packet is silently discarded without affecting the automaton
382  if(configureNakPacket->identifier != context->lcpFsm.identifier)
383  return ERROR_WRONG_IDENTIFIER;
384 
385  //Retrieve the length of the option list
386  length = ntohs(configureNakPacket->length) - sizeof(PppConfigurePacket);
387  //Point to the first option
388  option = (PppOption *) configureNakPacket->options;
389 
390  //Parse configuration options
391  while(length > 0)
392  {
393  //Check option length
394  if(option->length < sizeof(PppOption))
395  return ERROR_INVALID_LENGTH;
396  if(option->length > length)
397  return ERROR_INVALID_LENGTH;
398 
399  //Maximum-Receive-Unit option?
400  if(option->type == LCP_OPTION_MRU)
401  {
402  //Cast option
403  LcpMruOption *mruOption = (LcpMruOption *) option;
404 
405  //Check option length
406  if(mruOption->length != sizeof(LcpMruOption))
407  return ERROR_INVALID_LENGTH;
408 
409  //Save value
410  context->localConfig.mru = ntohs(mruOption->mru);
411  //Make sure the MRU is acceptable
412  context->localConfig.mru = MAX(context->localConfig.mru, PPP_MIN_MRU);
413  context->localConfig.mru = MIN(context->localConfig.mru, PPP_MAX_MRU);
414  }
415  else if(option->type == LCP_OPTION_ACCM)
416  {
417  //Cast option
418  LcpAccmOption *accmOption = (LcpAccmOption *) option;
419 
420  //Check option length
421  if(accmOption->length != sizeof(LcpAccmOption))
422  return ERROR_INVALID_LENGTH;
423 
424  //Save value
425  context->localConfig.accm = ntohl(accmOption->accm);
426  }
427  //Authentication-Protocol option?
428  else if(option->type == LCP_OPTION_AUTH_PROTOCOL)
429  {
430  //Cast option
431  LcpAuthProtocolOption *authProtocolOption = (LcpAuthProtocolOption *) option;
432 
433  //Check option length
434  if(authProtocolOption->length < sizeof(LcpAuthProtocolOption))
435  return ERROR_INVALID_LENGTH;
436 
437  //Check the value provided by the peer
438  if(ntohs(authProtocolOption->protocol) == PPP_PROTOCOL_PAP)
439  {
440 #if (PAP_SUPPORT == ENABLED)
441  //Manage authentication policy
442  if(context->settings.authProtocol & PPP_AUTH_PROTOCOL_PAP)
443  {
444  //Select PAP authentication protocol
445  context->localConfig.authProtocol = PPP_PROTOCOL_PAP;
446  }
447 #endif
448  }
449  else if(ntohs(authProtocolOption->protocol) == PPP_PROTOCOL_CHAP)
450  {
451 #if (CHAP_SUPPORT == ENABLED)
452  //Make sure that the length of the option is correct
453  if(authProtocolOption->length > sizeof(LcpAuthProtocolOption))
454  {
455  //Check the algorithm identifier
456  if(authProtocolOption->data[0] == CHAP_ALGO_ID_CHAP_MD5)
457  {
458  //Manage authentication policy
459  if(context->settings.authProtocol & PPP_AUTH_PROTOCOL_CHAP_MD5)
460  {
461  //Select CHAP with MD5 authentication protocol
462  context->localConfig.authProtocol = PPP_PROTOCOL_CHAP;
463  context->localConfig.authAlgo = CHAP_ALGO_ID_CHAP_MD5;
464  }
465  }
466  }
467 #endif
468  }
469  }
470 
471  //Remaining bytes to process
472  length -= option->length;
473  //Jump to the next option
474  option = (PppOption *) ((uint8_t *) option + option->length);
475  }
476 
477  //A valid Configure-Nak or Configure-Reject packet has been received from the peer
478  pppRcvConfigureNakEvent(context, &context->lcpFsm, &lcpCallbacks);
479 
480  //Successful processing
481  return NO_ERROR;
482 }
483 
484 
485 /**
486  * @brief Process Configure-Reject packet
487  * @param[in] context PPP context
488  * @param[in] configureRejPacket Packet received from the peer
489  * @return Error code
490  **/
491 
493  const PppConfigurePacket *configureRejPacket)
494 {
495  size_t length;
496  PppOption *option;
497 
498  //Debug message
499  TRACE_INFO("\r\nLCP Receive-Configure-Reject event\r\n");
500 
501  //When a packet is received with an invalid Identifier field, the
502  //packet is silently discarded without affecting the automaton
503  if(configureRejPacket->identifier != context->lcpFsm.identifier)
504  return ERROR_WRONG_IDENTIFIER;
505 
506  //Retrieve the length of the option list
507  length = ntohs(configureRejPacket->length) - sizeof(PppConfigurePacket);
508  //Point to the first option
509  option = (PppOption *) configureRejPacket->options;
510 
511  //Parse configuration options
512  while(length > 0)
513  {
514  //Check option length
515  if(option->length < sizeof(PppOption))
516  return ERROR_INVALID_LENGTH;
517  if(option->length > length)
518  return ERROR_INVALID_LENGTH;
519 
520  //Maximum-Receive-Unit option?
521  if(option->type == LCP_OPTION_MRU)
522  {
523  //The option is not recognized by the peer
524  context->localConfig.mruRejected = TRUE;
525  //Restore default value
526  context->localConfig.mru = PPP_DEFAULT_MRU;
527  }
528  //Async-Control-Character-Map option?
529  else if(option->type == LCP_OPTION_ACCM)
530  {
531  //The option is not recognized by the peer
532  context->localConfig.accmRejected = TRUE;
533  //Restore default value
534  context->localConfig.accm = PPP_DEFAULT_ACCM;
535  }
536  //Authentication-Protocol option?
537  else if(option->type == LCP_OPTION_AUTH_PROTOCOL)
538  {
539  //This is an unrecoverable error that terminates the connection
540  pppRcvCodeRejEvent(context, &context->lcpFsm, &lcpCallbacks, FALSE);
541  //Exit immediately
542  return ERROR_FAILURE;
543  }
544  //Magic-Number option?
545  else if(option->type == LCP_OPTION_MAGIC_NUMBER)
546  {
547  //The option is not recognized by the peer
548  context->localConfig.magicNumberRejected = TRUE;
549  //Restore default value
550  context->localConfig.magicNumber = PPP_DEFAULT_MAGIC_NUMBER;
551  }
552  //Protocol-Field-Compression option?
553  else if(option->type == LCP_OPTION_PFC)
554  {
555  //The option is not recognized by the peer
556  context->localConfig.pfcRejected = TRUE;
557  //Restore default value
558  context->localConfig.pfc = FALSE;
559  }
560  //Address-and-Control-Field-Compression option?
561  else if(option->type == LCP_OPTION_ACFC)
562  {
563  //The option is not recognized by the peer
564  context->localConfig.acfcRejected = TRUE;
565  //Restore default value
566  context->localConfig.acfc = FALSE;
567  }
568 
569  //Remaining bytes to process
570  length -= option->length;
571  //Jump to the next option
572  option = (PppOption *) ((uint8_t *) option + option->length);
573  }
574 
575  //A valid Configure-Nak or Configure-Reject packet has been received from the peer
576  pppRcvConfigureNakEvent(context, &context->lcpFsm, &lcpCallbacks);
577 
578  //Successful processing
579  return NO_ERROR;
580 }
581 
582 
583 /**
584  * @brief Process Terminate-Request packet
585  * @param[in] context PPP context
586  * @param[in] terminateReqPacket Packet received from the peer
587  * @return Error code
588  **/
589 
591  const PppTerminatePacket *terminateReqPacket)
592 {
593  //Debug message
594  TRACE_INFO("\r\nLCP Receive-Terminate-Request event\r\n");
595 
596  //The Terminate-Request indicates the desire of the peer to close the connection
597  pppRcvTerminateReqEvent(context, &context->lcpFsm,
598  &lcpCallbacks, terminateReqPacket);
599 
600  //Successful processing
601  return NO_ERROR;
602 }
603 
604 
605 /**
606  * @brief Process Terminate-Ack packet
607  * @param[in] context PPP context
608  * @param[in] terminateAckPacket Packet received from the peer
609  * @return Error code
610  **/
611 
613  const PppTerminatePacket *terminateAckPacket)
614 {
615  //Debug message
616  TRACE_INFO("\r\nLCP Receive-Terminate-Ack event\r\n");
617 
618  //The Terminate-Ack packet is usually a response to a Terminate-Request
619  //packet. This packet may also indicate that the peer is in Closed or
620  //Stopped states, and serves to re-synchronize the link configuration
621  pppRcvTerminateAckEvent(context, &context->lcpFsm, &lcpCallbacks);
622 
623  //Successful processing
624  return NO_ERROR;
625 }
626 
627 
628 /**
629  * @brief Process Code-Reject packet
630  * @param[in] context PPP context
631  * @param[in] codeRejPacket Packet received from the peer
632  * @return Error code
633  **/
634 
636  const PppCodeRejPacket *codeRejPacket)
637 {
638  size_t length;
639  PppPacket *packet;
640 
641  //Debug message
642  TRACE_INFO("\r\nLCP Receive-Code-Reject event\r\n");
643 
644  //Point to the rejected packet
645  packet = (PppPacket *) codeRejPacket->rejectedPacket;
646  //Retrieve the length of the rejected packet
647  length = ntohs(codeRejPacket->length) - sizeof(PppCodeRejPacket);
648 
649  //Make sure the length of the rejected packet is valid
650  if(length < sizeof(PppPacket))
651  return ERROR_INVALID_LENGTH;
652 
653  //Check whether the rejected value is acceptable or catastrophic
654  if(packet->code < PPP_CODE_CONFIGURE_REQ ||
655  packet->code > PPP_CODE_DISCARD_REQ)
656  {
657  //The RXJ+ event arises when the rejected value is acceptable, such
658  //as a Code-Reject of an extended code, or a Protocol-Reject of a
659  //NCP. These are within the scope of normal operation
660  pppRcvCodeRejEvent(context, &context->lcpFsm, &lcpCallbacks, TRUE);
661  }
662  else
663  {
664  //The RXJ- event arises when the rejected value is catastrophic, such
665  //as a Code-Reject of Configure-Request! This event communicates an
666  //unrecoverable error that terminates the connection
667  pppRcvCodeRejEvent(context, &context->lcpFsm, &lcpCallbacks, FALSE);
668  }
669 
670  //Successful processing
671  return NO_ERROR;
672 }
673 
674 
675 /**
676  * @brief Process Protocol-Reject packet
677  * @param[in] context PPP context
678  * @param[in] protocolRejPacket Packet received from the peer
679  * @return Error code
680  **/
681 
683  const PppProtocolRejPacket *protocolRejPacket)
684 {
685  size_t length;
686  uint16_t protocol;
687 
688  //Debug message
689  TRACE_INFO("\r\nLCP Receive-Protocol-Reject event\r\n");
690 
691  //Retrieve the length of the packet
692  length = ntohs(protocolRejPacket->length);
693 
694  //Make sure the length of the Protocol-Reject packet is valid
695  if(length < sizeof(PppProtocolRejPacket))
696  return ERROR_INVALID_LENGTH;
697 
698  //Convert the Rejected-Protocol field to host byte order
699  protocol = ntohs(protocolRejPacket->rejectedProtocol);
700 
701  //Check Rejected-Protocol field value
702  switch(protocol)
703  {
704  //LCP protocol?
705  case PPP_PROTOCOL_LCP:
706  //The rejected value is catastrophic. This event communicates
707  //an unrecoverable error that terminates the connection
708  pppRcvCodeRejEvent(context, &context->lcpFsm, &lcpCallbacks, FALSE);
709  break;
710 
711  //IPv4 or IPCP protocol?
712  case PPP_PROTOCOL_IP:
713  case PPP_PROTOCOL_IPCP:
714  //The implementation must stop sending the offending packet type
715  context->ipRejected = TRUE;
716  //This is within the scope of normal operation...
717  pppRcvCodeRejEvent(context, &context->lcpFsm, &lcpCallbacks, TRUE);
718  break;
719 
720  //IPv6 or IPV6CP protocol?
721  case PPP_PROTOCOL_IPV6:
722  case PPP_PROTOCOL_IPV6CP:
723  //The implementation must stop sending the offending packet type
724  context->ipv6Rejected = TRUE;
725  //This is within the scope of normal operation...
726  pppRcvCodeRejEvent(context, &context->lcpFsm, &lcpCallbacks, TRUE);
727  break;
728 
729  //Unknown protocol?
730  default:
731  //Just for sanity's sake...
732  break;
733  }
734 
735  //Successful processing
736  return NO_ERROR;
737 }
738 
739 
740 /**
741  * @brief Process Echo-Request packet
742  * @param[in] context PPP context
743  * @param[in] echoReqPacket Packet received from the peer
744  * @return Error code
745  **/
746 
748  const PppEchoPacket *echoReqPacket)
749 {
750  //Debug message
751  TRACE_INFO("\r\nLCP Receive-Echo-Request event\r\n");
752 
753  //An Echo-Reply packet is transmitted to acknowledge the
754  //reception of the Echo-Request packet
755  pppRcvEchoReqEvent(context, &context->lcpFsm,
756  &lcpCallbacks, echoReqPacket);
757 
758  //Successful processing
759  return NO_ERROR;
760 }
761 
762 
763 /**
764  * @brief Process Echo-Reply packet
765  * @param[in] context PPP context
766  * @param[in] echoRepPacket Packet received from the peer
767  * @return Error code
768  **/
769 
771  const PppEchoPacket *echoRepPacket)
772 {
773  //Debug message
774  TRACE_INFO("\r\nLCP Receive-Echo-Reply event\r\n");
775 
776  //Successful processing
777  return NO_ERROR;
778 }
779 
780 
781 /**
782  * @brief Process Discard-Request packet
783  * @param[in] context PPP context
784  * @param[in] discardReqPacket Packet received from the peer
785  * @return Error code
786  **/
787 
789  const PppDiscardReqPacket *discardReqPacket)
790 {
791  //Debug message
792  TRACE_INFO("\r\nLCP Receive-Discard-Request event\r\n");
793 
794  //The receiver must silently discard any Discard-Request that it receives
795  return NO_ERROR;
796 }
797 
798 
799 /**
800  * @brief Process packet with unknown code
801  * @param[in] context PPP context
802  * @param[in] packet Un-interpretable packet received from the peer
803  * @return Error code
804  **/
805 
807  const PppPacket *packet)
808 {
809  //Debug message
810  TRACE_INFO("\r\nLCP Receive-Unknown-Code event\r\n");
811 
812  //This event occurs when an un-interpretable packet is received from
813  //the peer. A Code-Reject packet is sent in response
814  pppRcvUnknownCodeEvent(context, &context->lcpFsm, &lcpCallbacks, packet);
815 
816  //Successful processing
817  return NO_ERROR;
818 }
819 
820 
821 /**
822  * @brief Process PPP frame with unknown protocol
823  * @param[in] context PPP context
824  * @param[in] protocol Rejected protocol
825  * @param[in] information Rejected information
826  * @param[in] length Length of the rejected information
827  * @return Error code
828  **/
829 
831  uint16_t protocol, const uint8_t *information, size_t length)
832 {
833  //Debug message
834  TRACE_INFO("\r\nLCP Receive-Unknown-Protocol event\r\n");
835 
836  //The peer is attempting to use a protocol which is unsupported
837  if(context->lcpFsm.state == PPP_STATE_9_OPENED)
838  {
839  //The Identifier field must be changed for each Protocol-Reject sent
840  context->lcpFsm.identifier++;
841 
842  //If the LCP automaton is in the Opened state, then this must be
843  //reported back to the peer by transmitting a Protocol-Reject
844  pppSendProtocolRej(context, context->lcpFsm.identifier,
845  protocol, information, length);
846  }
847 
848  //Successful processing
849  return NO_ERROR;
850 }
851 
852 
853 /**
854  * @brief This-Layer-Up callback function
855  * @param[in] context PPP context
856  **/
857 
859 {
860  //Debug message
861  TRACE_INFO("LCP This-Layer-Up callback\r\n");
862 
863  //Check whether the other end of the PPP link is being authenticated
864  if(context->localConfig.authProtocol != 0)
865  {
866  context->localAuthDone = FALSE;
867  }
868  else
869  {
870  context->localAuthDone = TRUE;
871  }
872 
873  //Check whether the other end of the PPP link is the authenticator
874  if(context->peerConfig.authProtocol != 0)
875  {
876  context->peerAuthDone = FALSE;
877  }
878  else
879  {
880  context->peerAuthDone = TRUE;
881  }
882 
883 #if (PAP_SUPPORT == ENABLED)
884  //PAP authentication required?
885  if(context->localConfig.authProtocol == PPP_PROTOCOL_PAP ||
886  context->peerConfig.authProtocol == PPP_PROTOCOL_PAP)
887  {
888  //Advance to the Authentication phase
889  context->pppPhase = PPP_PHASE_AUTHENTICATE;
890  //Start PAP authentication process
891  papStartAuth(context);
892  }
893 #endif
894 #if (CHAP_SUPPORT == ENABLED)
895  //CHAP authentication required?
896  if(context->localConfig.authProtocol == PPP_PROTOCOL_CHAP ||
897  context->peerConfig.authProtocol == PPP_PROTOCOL_CHAP)
898  {
899  //Advance to the Authentication phase
900  context->pppPhase = PPP_PHASE_AUTHENTICATE;
901  //Start CHAP authentication process
902  chapStartAuth(context);
903  }
904 #endif
905 
906  //Check whether PPP authentication is complete
907  if(context->localAuthDone && context->peerAuthDone)
908  {
909  //Advance to the Network phase
910  context->pppPhase = PPP_PHASE_NETWORK;
911 
912 #if (IPV4_SUPPORT == ENABLED)
913  //IPCP Open event
914  ipcpOpen(context);
915 #endif
916 #if (IPV6_SUPPORT == ENABLED)
917  //IPV6CP Open event
918  ipv6cpOpen(context);
919 #endif
920  }
921 }
922 
923 
924 /**
925  * @brief This-Layer-Down callback function
926  * @param[in] context PPP context
927  **/
928 
930 {
931  //Debug message
932  TRACE_INFO("LCP This-Layer-Down callback\r\n");
933 
934  //Advance to the Terminate phase
935  context->pppPhase = PPP_PHASE_TERMINATE;
936 
937 #if (IPV4_SUPPORT == ENABLED)
938  //IPCP Close event
939  ipcpClose(context);
940 #endif
941 #if (IPV6_SUPPORT == ENABLED)
942  //IPV6CP Close event
943  ipv6cpClose(context);
944 #endif
945 
946 #if (PAP_SUPPORT == ENABLED)
947  //Abort PAP authentication process
948  papAbortAuth(context);
949 #endif
950 
951 #if (CHAP_SUPPORT == ENABLED)
952  //Abort CHAP authentication process
953  chapAbortAuth(context);
954 #endif
955 }
956 
957 
958 /**
959  * @brief This-Layer-Started callback function
960  * @param[in] context PPP context
961  **/
962 
964 {
965  //Debug message
966  TRACE_INFO("LCP This-Layer-Started callback\r\n");
967 }
968 
969 
970 /**
971  * @brief This-Layer-Finished callback function
972  * @param[in] context PPP context
973  **/
974 
976 {
977  //Debug message
978  TRACE_INFO("LCP This-Layer-Finished callback\r\n");
979 
980  //The link is no longer available for traffic
981  pppCloseEvent(context, &context->lcpFsm, &lcpCallbacks);
982  //The lower layer is no longer ready to carry packets
983  pppDownEvent(context, &context->lcpFsm, &lcpCallbacks);
984 
985  //Advance to the Link Dead phase
986  context->pppPhase = PPP_PHASE_DEAD;
987 }
988 
989 
990 /**
991  * @brief Initialize-Restart-Count callback function
992  * @param[in] context PPP context
993  * @param[in] value Restart counter value
994  **/
995 
997 {
998  //Debug message
999  TRACE_INFO("LCP Initialize-Restart-Count callback\r\n");
1000 
1001  //Initialize restart counter
1002  context->lcpFsm.restartCounter = value;
1003 }
1004 
1005 
1006 /**
1007  * @brief Zero-Restart-Count callback function
1008  * @param[in] context PPP context
1009  **/
1010 
1012 {
1013  //Debug message
1014  TRACE_INFO("LCP Zero-Restart-Count callback\r\n");
1015 
1016  //Zero restart counter
1017  context->lcpFsm.restartCounter = 0;
1018 
1019  //The receiver of a Terminate-Request should wait for the peer to
1020  //disconnect, and must not disconnect until at least one Restart
1021  //time has passed after sending a Terminate-Ack
1022  context->lcpFsm.timestamp = osGetSystemTime();
1023 }
1024 
1025 
1026 /**
1027  * @brief Send-Configure-Request callback function
1028  * @param[in] context PPP context
1029  * @return Error code
1030  **/
1031 
1033 {
1034  error_t error;
1035  size_t length;
1036  size_t offset;
1037  NetBuffer *buffer;
1038  PppConfigurePacket *configureReqPacket;
1039 
1040  //Debug message
1041  TRACE_INFO("LCP Send-Configure-Request callback\r\n");
1042 
1043  //Allocate a buffer memory to hold the Configure-Request packet
1044  buffer = pppAllocBuffer(PPP_MAX_CONF_REQ_SIZE, &offset);
1045  //Failed to allocate memory?
1046  if(buffer == NULL)
1047  return ERROR_OUT_OF_MEMORY;
1048 
1049  //Point to the Configure-Request packet
1050  configureReqPacket = netBufferAt(buffer, offset);
1051 
1052  //Format packet header
1053  configureReqPacket->code = PPP_CODE_CONFIGURE_REQ;
1054  configureReqPacket->identifier = ++context->lcpFsm.identifier;
1055  configureReqPacket->length = sizeof(PppConfigurePacket);
1056 
1057  //Make sure the Maximum-Receive-Unit option has not been
1058  //previously rejected
1059  if(!context->localConfig.mruRejected)
1060  {
1061  //Convert MRU to network byte order
1062  uint16_t value = htons(context->localConfig.mru);
1063  //Add option
1064  pppAddOption(configureReqPacket, LCP_OPTION_MRU, &value, sizeof(uint16_t));
1065  }
1066 
1067  //Make sure the Async-Control-Character-Map option has not been
1068  //previously rejected
1069  if(!context->localConfig.accmRejected)
1070  {
1071  //Convert ACCM to network byte order
1072  uint32_t value = htonl(context->localConfig.accm);
1073  //Add option
1074  pppAddOption(configureReqPacket, LCP_OPTION_ACCM, &value, sizeof(uint32_t));
1075  }
1076 
1077  //Make sure the Authentication-Protocol option has not been
1078  //previously rejected
1079  if(!context->localConfig.authProtocolRejected)
1080  {
1081  uint8_t value[3];
1082 
1083  //PAP authentication protocol?
1084  if(context->localConfig.authProtocol == PPP_PROTOCOL_PAP)
1085  {
1086  //Format Authentication-Protocol option
1087  value[0] = MSB(PPP_PROTOCOL_PAP);
1088  value[1] = LSB(PPP_PROTOCOL_PAP);
1089 
1090  //Add option
1091  pppAddOption(configureReqPacket, LCP_OPTION_AUTH_PROTOCOL, &value, 2);
1092  }
1093  //CHAP authentication protocol?
1094  else if(context->localConfig.authProtocol == PPP_PROTOCOL_CHAP)
1095  {
1096  //Format Authentication-Protocol option
1097  value[0] = MSB(PPP_PROTOCOL_CHAP);
1098  value[1] = LSB(PPP_PROTOCOL_CHAP);
1099  value[2] = context->localConfig.authAlgo;
1100 
1101  //Add option
1102  pppAddOption(configureReqPacket, LCP_OPTION_AUTH_PROTOCOL, &value, 3);
1103  }
1104  }
1105 
1106  //Make sure the Protocol-Field-Compression option has not been
1107  //previously rejected
1108  if(!context->localConfig.pfcRejected)
1109  {
1110  //Check whether compression of the Protocol field is supported
1111  if(context->localConfig.pfc)
1112  {
1113  //Add option
1114  pppAddOption(configureReqPacket, LCP_OPTION_PFC, NULL, 0);
1115  }
1116  }
1117 
1118  //Make sure the Address-and-Control-Field-Compression option has not been
1119  //previously rejected
1120  if(!context->localConfig.acfcRejected)
1121  {
1122  //Check whether compression of the Address and Control fields is supported
1123  if(context->localConfig.acfc)
1124  {
1125  //Add option
1126  pppAddOption(configureReqPacket, LCP_OPTION_ACFC, NULL, 0);
1127  }
1128  }
1129 
1130  //Save packet length
1131  length = configureReqPacket->length;
1132  //Convert length field to network byte order
1133  configureReqPacket->length = htons(length);
1134 
1135  //Adjust the length of the multi-part buffer
1136  netBufferSetLength(buffer, offset + length);
1137 
1138  //Debug message
1139  TRACE_INFO("Sending Configure-Request packet (%" PRIuSIZE " bytes)...\r\n", length);
1140  //Dump packet contents for debugging purpose
1141  pppDumpPacket((PppPacket *) configureReqPacket, length, PPP_PROTOCOL_LCP);
1142 
1143  //Send PPP frame
1144  error = pppSendFrame(context->interface, buffer, offset, PPP_PROTOCOL_LCP);
1145 
1146  //The restart counter is decremented each time a Configure-Request is sent
1147  if(context->lcpFsm.restartCounter > 0)
1148  context->lcpFsm.restartCounter--;
1149 
1150  //Save the time at which the packet was sent
1151  context->lcpFsm.timestamp = osGetSystemTime();
1152 
1153  //Free previously allocated memory block
1154  netBufferFree(buffer);
1155  //Return status code
1156  return error;
1157 }
1158 
1159 
1160 /**
1161  * @brief Send-Configure-Ack callback function
1162  * @param[in] context PPP context
1163  * @param[in] configureReqPacket Configure-Request packet received from the peer
1164  * @return Error code
1165  **/
1166 
1168  const PppConfigurePacket *configureReqPacket)
1169 {
1170  //Debug message
1171  TRACE_INFO("LCP Send-Configure-Ack callback\r\n");
1172 
1173  //Send Configure-Ack packet
1174  return pppSendConfigureAckNak(context, configureReqPacket,
1176 }
1177 
1178 
1179 /**
1180  * @brief Send-Configure-Nak callback function
1181  * @param[in] context PPP context
1182  * @param[in] configureReqPacket Configure-Request packet received from the peer
1183  * @return Error code
1184  **/
1185 
1187  const PppConfigurePacket *configureReqPacket)
1188 {
1189  //Debug message
1190  TRACE_INFO("LCP Send-Configure-Nak callback\r\n");
1191 
1192  //Send Configure-Nak packet
1193  return pppSendConfigureAckNak(context, configureReqPacket,
1195 }
1196 
1197 
1198 /**
1199  * @brief Send-Configure-Reject callback function
1200  * @param[in] context PPP context
1201  * @param[in] configureReqPacket Configure-Request packet received from the peer
1202  * @return Error code
1203  **/
1204 
1206  const PppConfigurePacket *configureReqPacket)
1207 {
1208  //Debug message
1209  TRACE_INFO("LCP Send-Configure-Reject callback\r\n");
1210 
1211  //Send Configure-Reject packet
1212  return pppSendConfigureAckNak(context, configureReqPacket,
1214 }
1215 
1216 
1217 /**
1218  * @brief Send-Terminate-Request callback function
1219  * @param[in] context PPP context
1220  * @return Error code
1221  **/
1222 
1224 {
1225  error_t error;
1226 
1227  //Debug message
1228  TRACE_INFO("LCP Send-Terminate-Request callback\r\n");
1229 
1230  //On transmission, the Identifier field must be changed
1231  context->lcpFsm.identifier++;
1232 
1233  //Send Terminate-Request packet
1234  error = pppSendTerminateReq(context, context->lcpFsm.identifier, PPP_PROTOCOL_LCP);
1235 
1236  //The restart counter is decremented each time a Terminate-Request is sent
1237  if(context->lcpFsm.restartCounter > 0)
1238  context->lcpFsm.restartCounter--;
1239 
1240  //Save the time at which the packet was sent
1241  context->lcpFsm.timestamp = osGetSystemTime();
1242 
1243  //Return status code
1244  return error;
1245 }
1246 
1247 
1248 /**
1249  * @brief Send-Terminate-Ack callback function
1250  * @param[in] context PPP context
1251  * @param[in] terminateReqPacket Terminate-Request packet received from the peer
1252  * @return Error code
1253  **/
1254 
1256  const PppTerminatePacket *terminateReqPacket)
1257 {
1258  uint8_t identifier;
1259 
1260  //Debug message
1261  TRACE_INFO("LCP Send-Terminate-Ack callback\r\n");
1262 
1263  //Check whether this Terminate-Ack acknowledges the reception of a
1264  //Terminate-Request packet
1265  if(terminateReqPacket != NULL)
1266  {
1267  //The Identifier field of the Terminate-Request is copied into the
1268  //Identifier field of the Terminate-Ack packet
1269  identifier = terminateReqPacket->identifier;
1270  }
1271  else
1272  {
1273  //This Terminate-Ack packet serves to synchronize the automatons
1274  identifier = ++context->lcpFsm.identifier;
1275  }
1276 
1277  //Send Terminate-Ack packet
1279 }
1280 
1281 
1282 /**
1283  * @brief Send-Code-Reject callback function
1284  * @param[in] context PPP context
1285  * @param[in] packet Un-interpretable packet received from the peer
1286  * @return Error code
1287  **/
1288 
1289 error_t lcpSendCodeRej(PppContext *context, const PppPacket *packet)
1290 {
1291  //Debug message
1292  TRACE_INFO("LCP Send-Code-Reject callback\r\n");
1293 
1294  //The Identifier field must be changed for each Code-Reject sent
1295  context->lcpFsm.identifier++;
1296 
1297  //Send Code-Reject packet
1298  return pppSendCodeRej(context, packet, context->lcpFsm.identifier, PPP_PROTOCOL_LCP);
1299 }
1300 
1301 
1302 /**
1303  * @brief Send-Echo-Reply callback function
1304  * @param[in] context PPP context
1305  * @param[in] echoReqPacket Echo-Request packet received from the peer
1306  * @return Error code
1307  **/
1308 
1309 error_t lcpSendEchoRep(PppContext *context, const PppEchoPacket *echoReqPacket)
1310 {
1311  //Debug message
1312  TRACE_INFO("LCP Send-Echo-Reply callback\r\n");
1313 
1314  //Send Echo-Reply packet
1315  return pppSendEchoRep(context, echoReqPacket, PPP_PROTOCOL_LCP);
1316 }
1317 
1318 
1319 /**
1320  * @brief Parse LCP configuration option
1321  * @param[in] context PPP context
1322  * @param[in] option Option to be checked
1323  * @param[in] inPacketLen Remaining bytes to process in the incoming packet
1324  * @param[out] outPacket Pointer to the Configure-Ack, Nak or Reject packet
1325  * @return Error code
1326  **/
1327 
1329  size_t inPacketLen, PppConfigurePacket *outPacket)
1330 {
1331  error_t error;
1332 
1333  //Malformed LCP packet?
1334  if(inPacketLen < sizeof(PppOption))
1335  return ERROR_INVALID_LENGTH;
1336 
1337  //Check option length
1338  if(option->length < sizeof(PppOption))
1339  return ERROR_INVALID_LENGTH;
1340  if(option->length > inPacketLen)
1341  return ERROR_INVALID_LENGTH;
1342 
1343  //Check option type
1344  switch(option->type)
1345  {
1346  case LCP_OPTION_MRU:
1347  //Check Maximum-Receive-Unit option
1348  error = lcpParseMruOption(context, (LcpMruOption *) option, outPacket);
1349  break;
1350  case LCP_OPTION_ACCM:
1351  //Check Async-Control-Character-Map option
1352  error = lcpParseAccmOption(context, (LcpAccmOption *) option, outPacket);
1353  break;
1355  //Check Authentication-Protocol option
1356  error = lcpParseAuthProtocolOption(context, (LcpAuthProtocolOption *) option, outPacket);
1357  break;
1359  //Check Magic-Number option
1360  error = lcpParseMagicNumberOption(context, (LcpMagicNumberOption *) option, outPacket);
1361  break;
1362  case LCP_OPTION_PFC:
1363  //Check Protocol-Field-Compression option
1364  error = lcpParsePfcOption(context, (LcpPfcOption *) option, outPacket);
1365  break;
1366  case LCP_OPTION_ACFC:
1367  //Check Address-and-Control-Field-Compression option
1368  error = lcpParseAcfcOption(context, (LcpAcfcOption *) option, outPacket);
1369  break;
1370  default:
1371  //If some configuration options received in the Configure-Request are not
1372  //recognizable or not acceptable for negotiation, then the implementation
1373  //must transmit a Configure-Reject
1374  if(outPacket != NULL && outPacket->code == PPP_CODE_CONFIGURE_REJ)
1375  {
1376  //The options field of the Configure-Reject packet is filled
1377  //with the unrecognized options from the Configure-Request
1378  pppAddOption(outPacket, option->type, option->data,
1379  option->length - sizeof(PppOption));
1380  }
1381 
1382  //The option is not acceptable for negotiation
1383  error = ERROR_INVALID_TYPE;
1384  break;
1385  }
1386 
1387  //Return status code
1388  return error;
1389 }
1390 
1391 
1392 /**
1393  * @brief Parse Maximum-Receive-Unit option
1394  * @param[in] context PPP context
1395  * @param[in] option Option to be checked
1396  * @param[out] outPacket Pointer to the Configure-Nak or Configure-Reject packet
1397  * @return Error code
1398  **/
1399 
1401  LcpMruOption *option, PppConfigurePacket *outPacket)
1402 {
1403  error_t error;
1404  uint16_t value;
1405 
1406  //Check length field
1407  if(option->length == sizeof(LcpMruOption))
1408  {
1409  //Check whether the option value is acceptable
1410  if(ntohs(option->mru) >= PPP_MIN_MRU)
1411  {
1412  //If every configuration option received in the Configure-Request is
1413  //recognizable and all values are acceptable, then the implementation
1414  //must transmit a Configure-Ack
1415  if(outPacket != NULL && outPacket->code == PPP_CODE_CONFIGURE_ACK)
1416  {
1417  //Save Maximum-Receive-Unit option
1418  context->peerConfig.mru = ntohl(option->mru);
1419 
1420  //The options field of the Configure-Ack packet contains the
1421  //configuration options that the sender is acknowledging
1422  pppAddOption(outPacket, LCP_OPTION_MRU, (void *) &option->mru,
1423  option->length - sizeof(PppOption));
1424  }
1425 
1426  //The value is acceptable
1427  error = NO_ERROR;
1428  }
1429  else
1430  {
1431  //If all configuration options are recognizable, but some values are not
1432  //acceptable, then the implementation must transmit a Configure-Nak
1433  if(outPacket != NULL && outPacket->code == PPP_CODE_CONFIGURE_NAK)
1434  {
1435  //Use default value
1437 
1438  //The option must be modified to a value acceptable to the
1439  //Configure-Nak sender
1440  pppAddOption(outPacket, LCP_OPTION_MRU, &value, sizeof(uint16_t));
1441  }
1442 
1443  //The value is not acceptable
1444  error = ERROR_INVALID_VALUE;
1445  }
1446  }
1447  else
1448  {
1449  //Invalid length field
1450  error = ERROR_INVALID_LENGTH;
1451  }
1452 
1453  //Return status code
1454  return error;
1455 }
1456 
1457 
1458 /**
1459  * @brief Parse Async-Control-Character-Map option
1460  * @param[in] context PPP context
1461  * @param[in] option Option to be checked
1462  * @param[out] outPacket Pointer to the Configure-Nak or Configure-Reject packet
1463  * @return Error code
1464  **/
1465 
1467  LcpAccmOption *option, PppConfigurePacket *outPacket)
1468 {
1469  error_t error;
1470 
1471  //Check length field
1472  if(option->length == sizeof(LcpAccmOption))
1473  {
1474  //If every configuration option received in the Configure-Request is
1475  //recognizable and all values are acceptable, then the implementation
1476  //must transmit a Configure-Ack
1477  if(outPacket != NULL && outPacket->code == PPP_CODE_CONFIGURE_ACK)
1478  {
1479  //Save Async-Control-Character-Map option
1480  context->peerConfig.accm = ntohl(option->accm);
1481 
1482  //The options field of the Configure-Ack packet contains the
1483  //configuration options that the sender is acknowledging
1484  pppAddOption(outPacket, LCP_OPTION_ACCM, (void *) &option->accm,
1485  option->length - sizeof(PppOption));
1486  }
1487 
1488  //The value is acceptable
1489  error = NO_ERROR;
1490  }
1491  else
1492  {
1493  //Invalid length field
1494  error = ERROR_INVALID_LENGTH;
1495  }
1496 
1497  //Return status code
1498  return error;
1499 }
1500 
1501 
1502 /**
1503  * @brief Parse Authentication-Protocol option
1504  * @param[in] context PPP context
1505  * @param[in] option Option to be checked
1506  * @param[out] outPacket Pointer to the Configure-Nak or Configure-Reject packet
1507  * @return Error code
1508  **/
1509 
1511  LcpAuthProtocolOption *option, PppConfigurePacket *outPacket)
1512 {
1513  error_t error;
1514  uint8_t value[3];
1515 
1516  //Assume an error condition...
1517  error = ERROR_INVALID_LENGTH;
1518 
1519  //Check the length of the option
1520  if(option->length >= sizeof(LcpAuthProtocolOption))
1521  {
1522  //The Authentication-Protocol option for PAP must be exactly 4 bytes
1523  if(ntohs(option->protocol) == PPP_PROTOCOL_PAP)
1524  {
1525  if(option->length == 4)
1526  error = NO_ERROR;
1527  }
1528  //The Authentication-Protocol option for CHAP must be exactly 5 bytes
1529  else if(ntohs(option->protocol) == PPP_PROTOCOL_CHAP)
1530  {
1531  if(option->length == 5)
1532  error = NO_ERROR;
1533  }
1534  }
1535 
1536  //Make sure the length field is valid
1537  if(!error)
1538  {
1539  //PAP authentication protocol?
1540  if(context->settings.authProtocol & PPP_AUTH_PROTOCOL_PAP &&
1541  ntohs(option->protocol) == PPP_PROTOCOL_PAP)
1542  {
1543  //If every configuration option received in the Configure-Request is
1544  //recognizable and all values are acceptable, then the implementation
1545  //must transmit a Configure-Ack
1546  if(outPacket != NULL && outPacket->code == PPP_CODE_CONFIGURE_ACK)
1547  {
1548  //Save the authentication protocol to be used
1549  context->peerConfig.authProtocol = PPP_PROTOCOL_PAP;
1550 
1551  //The options field of the Configure-Ack packet contains the
1552  //configuration options that the sender is acknowledging
1553  pppAddOption(outPacket, option->type, (void *) &option->protocol,
1554  option->length - sizeof(PppOption));
1555  }
1556 
1557  //The value is acceptable
1558  error = NO_ERROR;
1559  }
1560  //CHAP with MD5 authentication protocol?
1561  else if(context->settings.authProtocol & PPP_AUTH_PROTOCOL_CHAP_MD5 &&
1562  ntohs(option->protocol) == PPP_PROTOCOL_CHAP &&
1563  option->data[0] == CHAP_ALGO_ID_CHAP_MD5)
1564  {
1565  //If every configuration option received in the Configure-Request is
1566  //recognizable and all values are acceptable, then the implementation
1567  //must transmit a Configure-Ack
1568  if(outPacket != NULL && outPacket->code == PPP_CODE_CONFIGURE_ACK)
1569  {
1570  //Save the authentication protocol to be used
1571  context->peerConfig.authProtocol = PPP_PROTOCOL_CHAP;
1572  context->peerConfig.authAlgo = CHAP_ALGO_ID_CHAP_MD5;
1573 
1574  //The options field of the Configure-Ack packet contains the
1575  //configuration options that the sender is acknowledging
1576  pppAddOption(outPacket, option->type, (void *) &option->protocol,
1577  option->length - sizeof(PppOption));
1578  }
1579 
1580  //The value is acceptable
1581  error = NO_ERROR;
1582  }
1583  else
1584  {
1585  //PAP authentication protocol allowed?
1586  if(context->settings.authProtocol & PPP_AUTH_PROTOCOL_PAP)
1587  {
1588  //If all configuration options are recognizable, but some values are not
1589  //acceptable, then the implementation must transmit a Configure-Nak
1590  if(outPacket != NULL && outPacket->code == PPP_CODE_CONFIGURE_NAK)
1591  {
1592  //Format Authentication-Protocol option
1593  value[0] = MSB(PPP_PROTOCOL_PAP);
1594  value[1] = LSB(PPP_PROTOCOL_PAP);
1595 
1596  //The option must be modified to a value acceptable to the
1597  //Configure-Nak sender
1599  }
1600 
1601  //The value is not acceptable
1602  error = ERROR_INVALID_VALUE;
1603  }
1604  //CHAP with MD5 authentication protocol allowed?
1605  else if(context->settings.authProtocol & PPP_AUTH_PROTOCOL_CHAP_MD5)
1606  {
1607  //If all configuration options are recognizable, but some values are not
1608  //acceptable, then the implementation must transmit a Configure-Nak
1609  if(outPacket != NULL && outPacket->code == PPP_CODE_CONFIGURE_NAK)
1610  {
1611  //Format Authentication-Protocol option
1612  value[0] = MSB(PPP_PROTOCOL_CHAP);
1613  value[1] = LSB(PPP_PROTOCOL_CHAP);
1615 
1616  //The option must be modified to a value acceptable to the
1617  //Configure-Nak sender
1619  }
1620 
1621  //The value is not acceptable
1622  error = ERROR_INVALID_VALUE;
1623  }
1624  else
1625  {
1626  //If some configuration options received in the Configure-Request are not
1627  //recognizable or not acceptable for negotiation, then the implementation
1628  //must transmit a Configure-Reject
1629  if(outPacket != NULL && outPacket->code == PPP_CODE_CONFIGURE_REJ)
1630  {
1631  //The options field of the Configure-Reject packet is filled
1632  //with the unrecognized options from the Configure-Request
1633  pppAddOption(outPacket, option->type, (void *) &option->protocol,
1634  option->length - sizeof(PppOption));
1635  }
1636 
1637  //The option is not acceptable for negotiation
1638  error = ERROR_INVALID_TYPE;
1639  }
1640  }
1641  }
1642 
1643  //Return status code
1644  return error;
1645 }
1646 
1647 
1648 /**
1649  * @brief Parse Magic-Number option
1650  * @param[in] context PPP context
1651  * @param[in] option Option to be checked
1652  * @param[out] outPacket Pointer to the Configure-Nak or Configure-Reject packet
1653  * @return Error code
1654  **/
1655 
1657  LcpMagicNumberOption *option, PppConfigurePacket *outPacket)
1658 {
1659  error_t error;
1660 
1661  //Check length field
1662  if(option->length == sizeof(LcpMagicNumberOption))
1663  {
1664  //If every configuration option received in the Configure-Request is
1665  //recognizable and all values are acceptable, then the implementation
1666  //must transmit a Configure-Ack
1667  if(outPacket != NULL && outPacket->code == PPP_CODE_CONFIGURE_ACK)
1668  {
1669  //Save Magic-Number option
1670  context->peerConfig.magicNumber = ntohl(option->magicNumber);
1671 
1672  //The options field of the Configure-Ack packet contains the
1673  //configuration options that the sender is acknowledging
1674  pppAddOption(outPacket, LCP_OPTION_MAGIC_NUMBER, (void *) &option->magicNumber,
1675  option->length - sizeof(PppOption));
1676  }
1677 
1678  //The value is acceptable
1679  error = NO_ERROR;
1680  }
1681  else
1682  {
1683  //Invalid length field
1684  error = ERROR_INVALID_LENGTH;
1685  }
1686 
1687  //Return status code
1688  return error;
1689 }
1690 
1691 
1692 /**
1693  * @brief Parse Protocol-Field-Compression option
1694  * @param[in] context PPP context
1695  * @param[in] option Option to be checked
1696  * @param[out] outPacket Pointer to the Configure-Nak or Configure-Reject packet
1697  * @return Error code
1698  **/
1699 
1701  LcpPfcOption *option, PppConfigurePacket *outPacket)
1702 {
1703  error_t error;
1704 
1705  //Check length field
1706  if(option->length == sizeof(LcpPfcOption))
1707  {
1708  //If every configuration option received in the Configure-Request is
1709  //recognizable and all values are acceptable, then the implementation
1710  //must transmit a Configure-Ack
1711  if(outPacket != NULL && outPacket->code == PPP_CODE_CONFIGURE_ACK)
1712  {
1713  //Save Protocol-Field-Compression option
1714  context->peerConfig.pfc = TRUE;
1715 
1716  //The options field of the Configure-Ack packet contains the
1717  //configuration options that the sender is acknowledging
1718  pppAddOption(outPacket, LCP_OPTION_PFC, NULL, 0);
1719  }
1720 
1721  //The value is acceptable
1722  error = NO_ERROR;
1723  }
1724  else
1725  {
1726  //Invalid length field
1727  error = ERROR_INVALID_LENGTH;
1728  }
1729 
1730  //Return status code
1731  return error;
1732 }
1733 
1734 
1735 /**
1736  * @brief Parse Address-and-Control-Field-Compression option
1737  * @param[in] context PPP context
1738  * @param[in] option Option to be checked
1739  * @param[out] outPacket Pointer to the Configure-Nak or Configure-Reject packet
1740  * @return Error code
1741  **/
1742 
1744  LcpAcfcOption *option, PppConfigurePacket *outPacket)
1745 {
1746  error_t error;
1747 
1748  //Check length field
1749  if(option->length == sizeof(LcpAcfcOption))
1750  {
1751  //If every configuration option received in the Configure-Request is
1752  //recognizable and all values are acceptable, then the implementation
1753  //must transmit a Configure-Ack
1754  if(outPacket != NULL && outPacket->code == PPP_CODE_CONFIGURE_ACK)
1755  {
1756  //Save Address-and-Control-Field-Compression option
1757  context->peerConfig.acfc = TRUE;
1758 
1759  //The options field of the Configure-Ack packet contains the
1760  //configuration options that the sender is acknowledging
1761  pppAddOption(outPacket, LCP_OPTION_ACFC, NULL, 0);
1762  }
1763 
1764  //The value is acceptable
1765  error = NO_ERROR;
1766  }
1767  else
1768  {
1769  //Invalid length field
1770  error = ERROR_INVALID_LENGTH;
1771  }
1772 
1773  //Return status code
1774  return error;
1775 }
1776 
1777 #endif
error_t chapAbortAuth(PppContext *context)
Abort CHAP authentication.
Definition: chap.c:91
error_t chapStartAuth(PppContext *context)
Start CHAP authentication.
Definition: chap.c:57
CHAP (Challenge Handshake Authentication Protocol)
@ CHAP_ALGO_ID_CHAP_MD5
Definition: chap.h:103
unsigned int uint_t
Definition: compiler_port.h:50
#define PRIuSIZE
int bool_t
Definition: compiler_port.h:53
#define ntohl(value)
Definition: cpu_endian.h:422
#define htonl(value)
Definition: cpu_endian.h:414
#define htons(value)
Definition: cpu_endian.h:413
#define ntohs(value)
Definition: cpu_endian.h:421
Debugging facilities.
#define TRACE_INFO(...)
Definition: debug.h:95
uint8_t identifier[]
uint32_t time
error_t
Error codes.
Definition: error.h:43
@ ERROR_WRONG_IDENTIFIER
Definition: error.h:89
@ ERROR_INVALID_TYPE
Definition: error.h:115
@ ERROR_INVALID_VALUE
Definition: error.h:116
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
@ ERROR_INVALID_LENGTH
Definition: error.h:111
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
error_t ipcpClose(PppContext *context)
IPCP Close event.
Definition: ipcp.c:97
error_t ipcpOpen(PppContext *context)
IPCP Open event.
Definition: ipcp.c:76
IPCP (PPP Internet Protocol Control Protocol)
uint8_t protocol
Definition: ipv4.h:296
error_t ipv6cpOpen(PppContext *context)
IPV6CP Open event.
Definition: ipv6cp.c:77
error_t ipv6cpClose(PppContext *context)
IPV6CP Close event.
Definition: ipv6cp.c:98
IPV6CP (PPP IPv6 Control Protocol)
error_t lcpParseAcfcOption(PppContext *context, LcpAcfcOption *option, PppConfigurePacket *outPacket)
Parse Address-and-Control-Field-Compression option.
Definition: lcp.c:1743
error_t lcpParseMruOption(PppContext *context, LcpMruOption *option, PppConfigurePacket *outPacket)
Parse Maximum-Receive-Unit option.
Definition: lcp.c:1400
error_t lcpParsePfcOption(PppContext *context, LcpPfcOption *option, PppConfigurePacket *outPacket)
Parse Protocol-Field-Compression option.
Definition: lcp.c:1700
void lcpThisLayerDown(PppContext *context)
This-Layer-Down callback function.
Definition: lcp.c:929
error_t lcpProcessConfigureReq(PppContext *context, const PppConfigurePacket *configureReqPacket)
Process Configure-Request packet.
Definition: lcp.c:249
error_t lcpProcessEchoRep(PppContext *context, const PppEchoPacket *echoRepPacket)
Process Echo-Reply packet.
Definition: lcp.c:770
error_t lcpProcessTerminateReq(PppContext *context, const PppTerminatePacket *terminateReqPacket)
Process Terminate-Request packet.
Definition: lcp.c:590
const PppCallbacks lcpCallbacks
LCP FSM callbacks.
Definition: lcp.c:54
error_t lcpProcessConfigureNak(PppContext *context, const PppConfigurePacket *configureNakPacket)
Process Configure-Nak packet.
Definition: lcp.c:371
error_t lcpSendTerminateAck(PppContext *context, const PppTerminatePacket *terminateReqPacket)
Send-Terminate-Ack callback function.
Definition: lcp.c:1255
error_t lcpProcessEchoReq(PppContext *context, const PppEchoPacket *echoReqPacket)
Process Echo-Request packet.
Definition: lcp.c:747
error_t lcpSendTerminateReq(PppContext *context)
Send-Terminate-Request callback function.
Definition: lcp.c:1223
void lcpThisLayerStarted(PppContext *context)
This-Layer-Started callback function.
Definition: lcp.c:963
error_t lcpClose(PppContext *context)
LCP Close event.
Definition: lcp.c:103
error_t lcpProcessUnknownCode(PppContext *context, const PppPacket *packet)
Process packet with unknown code.
Definition: lcp.c:806
error_t lcpProcessConfigureAck(PppContext *context, const PppConfigurePacket *configureAckPacket)
Process Configure-Ack packet.
Definition: lcp.c:345
error_t lcpProcessTerminateAck(PppContext *context, const PppTerminatePacket *terminateAckPacket)
Process Terminate-Ack packet.
Definition: lcp.c:612
error_t lcpProcessConfigureReject(PppContext *context, const PppConfigurePacket *configureRejPacket)
Process Configure-Reject packet.
Definition: lcp.c:492
error_t lcpProcessDiscardReq(PppContext *context, const PppDiscardReqPacket *discardReqPacket)
Process Discard-Request packet.
Definition: lcp.c:788
error_t lcpParseOption(PppContext *context, PppOption *option, size_t inPacketLen, PppConfigurePacket *outPacket)
Parse LCP configuration option.
Definition: lcp.c:1328
error_t lcpProcessProtocolRej(PppContext *context, const PppProtocolRejPacket *protocolRejPacket)
Process Protocol-Reject packet.
Definition: lcp.c:682
error_t lcpSendEchoRep(PppContext *context, const PppEchoPacket *echoReqPacket)
Send-Echo-Reply callback function.
Definition: lcp.c:1309
error_t lcpSendConfigureNak(PppContext *context, const PppConfigurePacket *configureReqPacket)
Send-Configure-Nak callback function.
Definition: lcp.c:1186
error_t lcpSendConfigureRej(PppContext *context, const PppConfigurePacket *configureReqPacket)
Send-Configure-Reject callback function.
Definition: lcp.c:1205
error_t lcpProcessCodeRej(PppContext *context, const PppCodeRejPacket *codeRejPacket)
Process Code-Reject packet.
Definition: lcp.c:635
void lcpThisLayerUp(PppContext *context)
This-Layer-Up callback function.
Definition: lcp.c:858
error_t lcpSendCodeRej(PppContext *context, const PppPacket *packet)
Send-Code-Reject callback function.
Definition: lcp.c:1289
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
void lcpZeroRestartCount(PppContext *context)
Zero-Restart-Count callback function.
Definition: lcp.c:1011
error_t lcpOpen(PppContext *context)
LCP Open event.
Definition: lcp.c:79
error_t lcpSendConfigureAck(PppContext *context, const PppConfigurePacket *configureReqPacket)
Send-Configure-Ack callback function.
Definition: lcp.c:1167
error_t lcpParseAccmOption(PppContext *context, LcpAccmOption *option, PppConfigurePacket *outPacket)
Parse Async-Control-Character-Map option.
Definition: lcp.c:1466
error_t lcpParseMagicNumberOption(PppContext *context, LcpMagicNumberOption *option, PppConfigurePacket *outPacket)
Parse Magic-Number option.
Definition: lcp.c:1656
void lcpInitRestartCount(PppContext *context, uint_t value)
Initialize-Restart-Count callback function.
Definition: lcp.c:996
void lcpThisLayerFinished(PppContext *context)
This-Layer-Finished callback function.
Definition: lcp.c:975
error_t lcpParseAuthProtocolOption(PppContext *context, LcpAuthProtocolOption *option, PppConfigurePacket *outPacket)
Parse Authentication-Protocol option.
Definition: lcp.c:1510
error_t lcpSendConfigureReq(PppContext *context)
Send-Configure-Request callback function.
Definition: lcp.c:1032
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)
LcpPfcOption
Definition: lcp.h:138
@ LCP_OPTION_PFC
Protocol-Field-Compression.
Definition: lcp.h:55
@ LCP_OPTION_MAGIC_NUMBER
Magic-Number.
Definition: lcp.h:54
@ LCP_OPTION_AUTH_PROTOCOL
Authentication-Protocol.
Definition: lcp.h:52
@ LCP_OPTION_ACCM
Async-Control-Character-Map.
Definition: lcp.h:51
@ LCP_OPTION_MRU
Maximum-Receive-Unit.
Definition: lcp.h:50
@ LCP_OPTION_ACFC
Address-and-Control-Field-Compression.
Definition: lcp.h:56
LcpAccmOption
Definition: lcp.h:89
LcpMruOption
Definition: lcp.h:77
LcpAcfcOption
Definition: lcp.h:149
LcpMagicNumberOption
Definition: lcp.h:127
LcpAuthProtocolOption
Definition: lcp.h:102
TCP/IP stack core.
void * netBufferAt(const NetBuffer *buffer, size_t offset)
Returns a pointer to the data at the specified position.
Definition: net_mem.c:415
void netBufferFree(NetBuffer *buffer)
Dispose a multi-part buffer.
Definition: net_mem.c:282
error_t netBufferSetLength(NetBuffer *buffer, size_t length)
Adjust the length of a multi-part buffer.
Definition: net_mem.c:322
#define LSB(x)
Definition: os_port.h:55
#define MIN(a, b)
Definition: os_port.h:63
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
#define MSB(x)
Definition: os_port.h:59
#define MAX(a, b)
Definition: os_port.h:67
systime_t osGetSystemTime(void)
Retrieve system time.
uint32_t systime_t
System time.
error_t papStartAuth(PppContext *context)
Start PAP authentication.
Definition: pap.c:53
error_t papAbortAuth(PppContext *context)
Abort PAP authentication.
Definition: pap.c:87
PAP (Password Authentication Protocol)
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
PppConfigurePacket
Definition: ppp.h:274
PppOption
Definition: ppp.h:354
PppProtocolRejPacket
Definition: ppp.h:314
@ PPP_STATE_9_OPENED
Definition: ppp.h:189
@ PPP_STATE_4_CLOSING
Definition: ppp.h:184
@ PPP_STATE_8_ACK_SENT
Definition: ppp.h:188
@ 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 PppContext
Definition: ppp.h:38
@ PPP_AUTH_PROTOCOL_PAP
Definition: ppp.h:236
@ PPP_AUTH_PROTOCOL_CHAP_MD5
Definition: ppp.h:237
@ PPP_CODE_ECHO_REP
Echo-Reply.
Definition: ppp.h:225
@ PPP_CODE_CONFIGURE_REQ
Configure-Request.
Definition: ppp.h:216
@ PPP_CODE_CONFIGURE_REJ
Configure-Reject.
Definition: ppp.h:219
@ PPP_CODE_PROTOCOL_REJ
Protocol-Reject.
Definition: ppp.h:223
@ PPP_CODE_TERMINATE_ACK
Terminate-Ack.
Definition: ppp.h:221
@ PPP_CODE_TERMINATE_REQ
Terminate-Request.
Definition: ppp.h:220
@ PPP_CODE_CODE_REJ
Code-Reject.
Definition: ppp.h:222
@ PPP_CODE_DISCARD_REQ
Discard-Request.
Definition: ppp.h:226
@ PPP_CODE_CONFIGURE_ACK
Configure-Ack.
Definition: ppp.h:217
@ PPP_CODE_ECHO_REQ
Echo-Request.
Definition: ppp.h:224
@ PPP_CODE_CONFIGURE_NAK
Configure-Nak.
Definition: ppp.h:218
#define PPP_DEFAULT_ACCM
Definition: ppp.h:130
#define PPP_MIN_MRU
Definition: ppp.h:135
@ PPP_PHASE_TERMINATE
Link termination phase.
Definition: ppp.h:170
@ PPP_PHASE_ESTABLISH
Link establishment phase.
Definition: ppp.h:167
@ PPP_PHASE_AUTHENTICATE
Authentication phase.
Definition: ppp.h:168
@ 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_MAX_MRU
Definition: ppp.h:137
PppCodeRejPacket
Definition: ppp.h:300
PppDiscardReqPacket
Definition: ppp.h:342
PppEchoPacket
Definition: ppp.h:328
#define PPP_MAX_CONF_REQ_SIZE
Definition: ppp.h:140
PppTerminatePacket
Definition: ppp.h:287
#define PPP_DEFAULT_MAGIC_NUMBER
Definition: ppp.h:132
#define PPP_RESTART_TIMER
Definition: ppp.h:96
error_t pppDumpPacket(const PppPacket *packet, size_t length, PppProtocol protocol)
Dump LCP/NCP packet for debugging purpose.
Definition: ppp_debug.c:143
Data logging functions for debugging purpose (PPP)
void pppTimeoutEvent(PppContext *context, PppFsm *fsm, const PppCallbacks *callbacks)
Process Timeout event.
Definition: ppp_fsm.c:257
void pppRcvConfigureAckEvent(PppContext *context, PppFsm *fsm, const PppCallbacks *callbacks)
Process Receive-Configure-Ack event.
Definition: ppp_fsm.c:524
void pppOpenEvent(PppContext *context, PppFsm *fsm, const PppCallbacks *callbacks)
Process Open event.
Definition: ppp_fsm.c:135
void pppCloseEvent(PppContext *context, PppFsm *fsm, const PppCallbacks *callbacks)
Process Close event.
Definition: ppp_fsm.c:189
void pppRcvCodeRejEvent(PppContext *context, PppFsm *fsm, const PppCallbacks *callbacks, bool_t acceptable)
Process Receive-Code-Reject or Receive-Protocol-Reject event.
Definition: ppp_fsm.c:792
void pppDownEvent(PppContext *context, PppFsm *fsm, const PppCallbacks *callbacks)
Process Down event.
Definition: ppp_fsm.c:84
void pppUpEvent(PppContext *context, PppFsm *fsm, const PppCallbacks *callbacks)
Process Up event.
Definition: ppp_fsm.c:50
void pppRcvUnknownCodeEvent(PppContext *context, PppFsm *fsm, const PppCallbacks *callbacks, const PppPacket *packet)
Process Receive-Unknown-Code event.
Definition: ppp_fsm.c:757
void pppRcvTerminateReqEvent(PppContext *context, PppFsm *fsm, const PppCallbacks *callbacks, const PppTerminatePacket *terminateReqPacket)
Process Receive-Terminate-Req event.
Definition: ppp_fsm.c:648
void pppRcvTerminateAckEvent(PppContext *context, PppFsm *fsm, const PppCallbacks *callbacks)
Process Receive-Terminate-Ack event.
Definition: ppp_fsm.c:697
void pppRcvConfigureReqEvent(PppContext *context, PppFsm *fsm, const PppCallbacks *callbacks, const PppConfigurePacket *configureReqPacket, PppCode code)
Process Receive-Configure-Request event.
Definition: ppp_fsm.c:335
void pppRcvEchoReqEvent(PppContext *context, PppFsm *fsm, const PppCallbacks *callbacks, const PppEchoPacket *echoReqPacket)
Process Receive-Echo-Request event.
Definition: ppp_fsm.c:889
void pppRcvConfigureNakEvent(PppContext *context, PppFsm *fsm, const PppCallbacks *callbacks)
Process Receive-Configure-Nak event.
Definition: ppp_fsm.c:586
PPP finite state machine.
error_t pppSendTerminateAck(PppContext *context, uint8_t identifier, PppProtocol protocol)
Send Terminate-Ack packet.
Definition: ppp_misc.c:215
error_t pppSendCodeRej(PppContext *context, const PppPacket *packet, uint8_t identifier, PppProtocol protocol)
Send Code-Reject packet.
Definition: ppp_misc.c:265
error_t pppSendConfigureAckNak(PppContext *context, const PppConfigurePacket *configureReqPacket, PppProtocol protocol, PppCode code)
Send Configure-Ack, Nak or Reject packet.
Definition: ppp_misc.c:56
error_t pppSendEchoRep(PppContext *context, const PppEchoPacket *echoReqPacket, PppProtocol protocol)
Send Echo-Reply packet.
Definition: ppp_misc.c:385
error_t pppAddOption(PppConfigurePacket *packet, uint8_t optionType, const void *optionValue, uint8_t optionLen)
Add an option to a Configure packet.
Definition: ppp_misc.c:448
error_t pppSendProtocolRej(PppContext *context, uint8_t identifier, uint16_t protocol, const uint8_t *information, size_t length)
Send Protocol-Reject packet.
Definition: ppp_misc.c:325
error_t pppSendTerminateReq(PppContext *context, uint8_t identifier, PppProtocol protocol)
Send Terminate-Request packet.
Definition: ppp_misc.c:166
PPP miscellaneous functions.
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:89
PPP FSM actions.
Definition: ppp_fsm.h:153
uint8_t length
Definition: tcp.h:368
uint8_t value[]
Definition: tcp.h:369