ppp_debug.c
Go to the documentation of this file.
1 /**
2  * @file ppp_debug.c
3  * @brief Data logging functions for debugging purpose (PPP)
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 //Dependencies
32 #include "core/net.h"
33 #include "ppp/ppp_debug.h"
34 #include "debug.h"
35 
36 //Check TCP/IP stack configuration
37 #if (PPP_SUPPORT == ENABLED && PPP_TRACE_LEVEL >= TRACE_LEVEL_DEBUG)
38 
39 //LCP codes
40 static const char_t *const lcpCodeLabel[] =
41 {
42  "", //0
43  "Configure-Request", //1
44  "Configure-Ack", //2
45  "Configure-Nak", //3
46  "Configure-Reject", //4
47  "Terminate-Request", //5
48  "Terminate-Ack", //6
49  "Code-Reject", //7
50  "Protocol-Reject", //8
51  "Echo-Request", //9
52  "Echo-Reply", //10
53  "Discard-Request" //11
54 };
55 
56 //NCP codes
57 static const char_t *const ncpCodeLabel[] =
58 {
59  "", //0
60  "Configure-Request", //1
61  "Configure-Ack", //2
62  "Configure-Nak", //3
63  "Configure-Reject", //4
64  "Terminate-Request", //5
65  "Terminate-Ack", //6
66  "Code-Reject" //7
67 };
68 
69 //PAP codes
70 static const char_t *const papCodeLabel[] =
71 {
72  "", //0
73  "Authenticate-Request", //1
74  "Authenticate-Ack", //2
75  "Authenticate-Nak" //3
76 };
77 
78 //CHAP codes
79 static const char_t *const chapCodeLabel[] =
80 {
81  "", //0
82  "Challenge", //1
83  "Response", //2
84  "Success", //3
85  "Failure" //4
86 };
87 
88 //LCP options
89 static const char_t *const lcpOptionLabel[] =
90 {
91  "", //0
92  "Maximum-Receive-Unit", //1
93  "Async-Control-Character-Map", //2
94  "Authentication-Protocol", //3
95  "Quality-Protocol", //4
96  "Magic-Number", //5
97  "", //6
98  "Protocol-Field-Compression", //7
99  "Address-and-Control-Field-Compression", //8
100  "FCS-Alternatives", //9
101  "Self-Describing-Pad", //10
102  "Numbered-Mode", //11
103  "", //12
104  "Callback" //13
105 };
106 
107 //IPCP options
108 static const char_t *const ipcpOptionLabel[] =
109 {
110  "", //0
111  "IP-Addresses", //1
112  "IP-Compression-Protocol", //2
113  "IP-Address", //3
114  "Mobile-IPv4", //4
115 };
116 
117 static const char_t *const ipcpOptionLabel2[] =
118 {
119  "", //128
120  "Primary-DNS-Server-Address", //129
121  "Primary-NBNS-Server-Address", //130
122  "Secondary-DNS-Server-Address", //131
123  "Secondary-NBNS-Server-Address" //132
124 };
125 
126 //IPV6CP options
127 static const char_t *const ipv6cpOptionLabel[] =
128 {
129  "", //0
130  "Interface-Identifier", //1
131  "IPv6-Compression-Protocol" //2
132 };
133 
134 
135 /**
136  * @brief Dump LCP/NCP packet for debugging purpose
137  * @param[in] packet Pointer to the LCP packet
138  * @param[in] length Length of the packet, in bytes
139  * @param[in] protocol Protocol field
140  * @return Error code
141  **/
142 
144 {
145  error_t error;
146 
147  //Check protocol field
148  switch(protocol)
149  {
150  //LCP packet?
151  case PPP_PROTOCOL_LCP:
152  error = lcpDumpPacket(packet, length);
153  break;
154  //NCP packet?
155  case PPP_PROTOCOL_IPCP:
156  case PPP_PROTOCOL_IPV6CP:
157  error = ncpDumpPacket(packet, length, protocol);
158  break;
159 
160  //PAP packet?
161  case PPP_PROTOCOL_PAP:
162  error = papDumpPacket(packet, length);
163  break;
164 
165  //CHAP packet?
166  case PPP_PROTOCOL_CHAP:
167  error = chapDumpPacket(packet, length);
168  break;
169 
170  //Unknown protocol?
171  default:
172  error = ERROR_FAILURE;
173  break;
174  }
175 
176  //Return status code
177  return error;
178 }
179 
180 
181 /**
182  * @brief Dump LCP packet for debugging purpose
183  * @param[in] packet Pointer to the LCP packet
184  * @param[in] length Length of the packet, in bytes
185  * @return Error code
186  **/
187 
188 error_t lcpDumpPacket(const PppPacket *packet, size_t length)
189 {
190  error_t error;
191  const char_t *label;
192 
193  //Make sure the LCP packet is valid
194  if(length < sizeof(PppPacket))
195  return ERROR_INVALID_LENGTH;
196 
197  //Check the length field
198  if(ntohs(packet->length) > length)
199  return ERROR_INVALID_LENGTH;
200  if(ntohs(packet->length) < sizeof(PppPacket))
201  return ERROR_INVALID_LENGTH;
202 
203  //Save the length of the LCP packet
204  length = ntohs(packet->length);
205 
206  //Retrieve the name of the LCP packet
207  if(packet->code < arraysize(lcpCodeLabel))
208  {
209  label = lcpCodeLabel[packet->code];
210  }
211  else
212  {
213  label = "Unknown";
214  }
215 
216  //Dump LCP packet header
217  TRACE_DEBUG(" Code = %" PRIu8 " (%s)\r\n", packet->code, label);
218  TRACE_DEBUG(" Identifier = %" PRIu8 "\r\n", packet->identifier);
219  TRACE_DEBUG(" Length = %" PRIu16 "\r\n", ntohs(packet->length));
220 
221  //Configure-Request, Configure-Ack, Configure-Nak or Configure-Reject packet?
222  if(packet->code == PPP_CODE_CONFIGURE_REQ ||
223  packet->code == PPP_CODE_CONFIGURE_ACK ||
224  packet->code == PPP_CODE_CONFIGURE_NAK ||
225  packet->code == PPP_CODE_CONFIGURE_REJ)
226  {
227  //Cast LCP packet
229 
230  //Valid packet length?
231  if(length < sizeof(PppConfigurePacket))
232  return ERROR_INVALID_LENGTH;
233 
234  //Retrieve the length of the option list
235  length -= sizeof(PppConfigurePacket);
236 
237  //Dump options
238  error = lcpDumpOptions((PppOption *) p->options, length);
239  //Any error to report?
240  if(error)
241  return error;
242  }
243  //Terminate-Request or Terminate-Ack packet?
244  else if(packet->code == PPP_CODE_TERMINATE_REQ ||
245  packet->code == PPP_CODE_TERMINATE_ACK)
246  {
247  //Cast LCP packet
249 
250  //Valid packet length?
251  if(length < sizeof(PppTerminatePacket))
252  return ERROR_INVALID_LENGTH;
253 
254  //Retrieve the length of data
255  length -= sizeof(PppTerminatePacket);
256 
257  //Any data?
258  if(length > 0)
259  {
260  //Dump data
261  TRACE_DEBUG(" Data (%" PRIuSIZE " bytes)\r\n", length);
262  TRACE_DEBUG_ARRAY(" ", p->data, length);
263  }
264  }
265  //Code-Reject packet?
266  else if(packet->code == PPP_CODE_CODE_REJ)
267  {
268  //Cast LCP packet
269  PppCodeRejPacket *p = (PppCodeRejPacket *) packet;
270 
271  //Valid packet length?
272  if(length < sizeof(PppCodeRejPacket))
273  return ERROR_INVALID_LENGTH;
274 
275  //Retrieve the length of Rejected-Packet field
276  length -= sizeof(PppCodeRejPacket);
277 
278  //Rejected-Packet
279  TRACE_DEBUG(" Rejected-Packet (%" PRIuSIZE " bytes)\r\n", length);
280  TRACE_DEBUG_ARRAY(" ", p->rejectedPacket, length);
281  }
282  //Protocol-Reject packet?
283  else if(packet->code == PPP_CODE_PROTOCOL_REJ)
284  {
285  //Cast LCP packet
287 
288  //Valid packet length?
289  if(length < sizeof(PppProtocolRejPacket))
290  return ERROR_INVALID_LENGTH;
291 
292  //Retrieve the length of Rejected-Information field
293  length -= sizeof(PppProtocolRejPacket);
294 
295  //Rejected-Protocol
296  TRACE_DEBUG(" Rejected-Protocol = %" PRIu16 "\r\n", htons(p->rejectedProtocol));
297  //Rejected-Information
298  TRACE_DEBUG(" Rejected-Information (%" PRIuSIZE " bytes)\r\n", length);
299  TRACE_DEBUG_ARRAY(" ", p->rejectedInfo, length);
300  }
301  //Echo-Request, Echo-Reply or Discard-Request packet?
302  else if(packet->code == PPP_CODE_ECHO_REQ ||
303  packet->code == PPP_CODE_ECHO_REP ||
304  packet->code == PPP_CODE_DISCARD_REQ)
305  {
306  //Cast LCP packet
307  PppEchoPacket *p = (PppEchoPacket *) packet;
308 
309  //Valid packet length?
310  if(length < sizeof(PppEchoPacket))
311  return ERROR_INVALID_LENGTH;
312 
313  //Retrieve the length of data
314  length -= sizeof(PppEchoPacket);
315 
316  //Magic-Number
317  TRACE_DEBUG(" Magic-Number = %" PRIu32 "\r\n", htonl(p->magicNumber));
318  //Data
319  TRACE_DEBUG(" Data (%" PRIuSIZE " bytes)\r\n", length);
320  TRACE_DEBUG_ARRAY(" ", p->data, length);
321  }
322  //Unknown packet?
323  else
324  {
325  //Retrieve the length of data
326  length -= sizeof(PppPacket);
327 
328  //Any data?
329  if(length > 0)
330  {
331  //Dump data
332  TRACE_DEBUG(" Data (%" PRIuSIZE " bytes)\r\n", length);
333  TRACE_DEBUG_ARRAY(" ", packet->data, length);
334  }
335  }
336 
337  //No error to report
338  return NO_ERROR;
339 }
340 
341 
342 /**
343  * @brief Dump NCP packet for debugging purpose
344  * @param[in] packet Pointer to the NCP packet
345  * @param[in] length Length of the packet, in bytes
346  * @param[in] protocol Protocol field
347  * @return Error code
348  **/
349 
351 {
352  error_t error;
353  const char_t *label;
354 
355  //Make sure the NDP packet is valid
356  if(length < sizeof(PppPacket))
357  return ERROR_INVALID_LENGTH;
358 
359  //Check the length field
360  if(ntohs(packet->length) > length)
361  return ERROR_INVALID_LENGTH;
362  if(ntohs(packet->length) < sizeof(PppPacket))
363  return ERROR_INVALID_LENGTH;
364 
365  //Save the length of the NDP packet
366  length = ntohs(packet->length);
367 
368  //Retrieve the name of the NDP packet
369  if(packet->code < arraysize(ncpCodeLabel))
370  {
371  label = ncpCodeLabel[packet->code];
372  }
373  else
374  {
375  label = "Unknown";
376  }
377 
378  //Dump NDP packet header
379  TRACE_DEBUG(" Code = %" PRIu8 " (%s)\r\n", packet->code, label);
380  TRACE_DEBUG(" Identifier = %" PRIu8 "\r\n", packet->identifier);
381  TRACE_DEBUG(" Length = %" PRIu16 "\r\n", ntohs(packet->length));
382 
383  //Configure-Request, Configure-Ack, Configure-Nak or Configure-Reject packet?
384  if(packet->code == PPP_CODE_CONFIGURE_REQ ||
385  packet->code == PPP_CODE_CONFIGURE_ACK ||
386  packet->code == PPP_CODE_CONFIGURE_NAK ||
387  packet->code == PPP_CODE_CONFIGURE_REJ)
388  {
389  //Cast NDP packet
391 
392  //Valid packet length?
393  if(length < sizeof(PppConfigurePacket))
394  return ERROR_INVALID_LENGTH;
395 
396  //Retrieve the length of the option list
397  length -= sizeof(PppConfigurePacket);
398 
399  //IPCP protocol?
401  {
402  //Dump options
403  error = ipcpDumpOptions((PppOption *) p->options, length);
404  //Any error to report?
405  if(error)
406  return error;
407  }
408  //IPV6CP protocol?
409  else if(protocol == PPP_PROTOCOL_IPV6CP)
410  {
411  //Dump options
412  error = ipv6cpDumpOptions((PppOption *) p->options, length);
413  //Any error to report?
414  if(error)
415  return error;
416  }
417  }
418  //Terminate-Request or Terminate-Ack packet?
419  else if(packet->code == PPP_CODE_TERMINATE_REQ ||
420  packet->code == PPP_CODE_TERMINATE_ACK)
421  {
422  //Cast NDP packet
424 
425  //Valid packet length?
426  if(length < sizeof(PppTerminatePacket))
427  return ERROR_INVALID_LENGTH;
428 
429  //Retrieve the length of data
430  length -= sizeof(PppTerminatePacket);
431 
432  //Any data?
433  if(length > 0)
434  {
435  //Dump data
436  TRACE_DEBUG(" Data (%" PRIuSIZE " bytes)\r\n", length);
437  TRACE_DEBUG_ARRAY(" ", p->data, length);
438  }
439  }
440  //Code-Reject packet?
441  else if(packet->code == PPP_CODE_CODE_REJ)
442  {
443  //Cast NDP packet
444  PppCodeRejPacket *p = (PppCodeRejPacket *) packet;
445 
446  //Valid packet length?
447  if(length < sizeof(PppCodeRejPacket))
448  return ERROR_INVALID_LENGTH;
449 
450  //Retrieve the length of Rejected-Packet field
451  length -= sizeof(PppCodeRejPacket);
452 
453  //Rejected-Packet
454  TRACE_DEBUG(" Rejected-Packet (%" PRIuSIZE " bytes)\r\n", length);
455  TRACE_DEBUG_ARRAY(" ", p->rejectedPacket, length);
456  }
457  //Unknown packet?
458  else
459  {
460  //Retrieve the length of data
461  length -= sizeof(PppPacket);
462 
463  //Any data?
464  if(length > 0)
465  {
466  //Dump data
467  TRACE_DEBUG(" Data (%" PRIuSIZE " bytes)\r\n", length);
468  TRACE_DEBUG_ARRAY(" ", packet->data, length);
469  }
470  }
471 
472  //No error to report
473  return NO_ERROR;
474 }
475 
476 
477 /**
478  * @brief Dump PAP packet for debugging purpose
479  * @param[in] packet Pointer to the PAP packet
480  * @param[in] length Length of the packet, in bytes
481  * @return Error code
482  **/
483 
484 error_t papDumpPacket(const PppPacket *packet, size_t length)
485 {
486  const char_t *label;
487 
488  //Make sure the PAP packet is valid
489  if(length < sizeof(PppPacket))
490  return ERROR_INVALID_LENGTH;
491 
492  //Check the length field
493  if(ntohs(packet->length) > length)
494  return ERROR_INVALID_LENGTH;
495  if(ntohs(packet->length) < sizeof(PppPacket))
496  return ERROR_INVALID_LENGTH;
497 
498  //Save the length of the PAP packet
499  length = ntohs(packet->length);
500 
501  //Retrieve the name of the PAP packet
502  if(packet->code < arraysize(papCodeLabel))
503  {
504  label = papCodeLabel[packet->code];
505  }
506  else
507  {
508  label = "Unknown";
509  }
510 
511  //Dump PAP packet header
512  TRACE_DEBUG(" Code = %" PRIu8 " (%s)\r\n", packet->code, label);
513  TRACE_DEBUG(" Identifier = %" PRIu8 "\r\n", packet->identifier);
514  TRACE_DEBUG(" Length = %" PRIu16 "\r\n", ntohs(packet->length));
515 
516  //Authenticate-Request packet?
517  if(packet->code == PAP_CODE_AUTH_REQ)
518  {
519  uint8_t *q;
521 
522  //Cast PAP packet
523  p = (PapAuthReqPacket *) packet;
524 
525  //Valid packet length?
526  if(length < sizeof(PapAuthReqPacket))
527  return ERROR_INVALID_LENGTH;
528 
529  //Peer-ID-Length field
530  TRACE_DEBUG(" Peer-ID-Length = %" PRIu8 "\r\n", p->peerIdLength);
531 
532  //Check the length of the Peer-ID field
533  if(length < (sizeof(PapAuthAckPacket) + 1 + p->peerIdLength))
534  return ERROR_INVALID_LENGTH;
535 
536  //Peer-ID field
537  TRACE_DEBUG(" Peer-ID\r\n");
538  TRACE_DEBUG_ARRAY(" ", p->peerId, p->peerIdLength);
539 
540  //Point to the Passwd-Length field
541  q = p->peerId + p->peerIdLength;
542 
543  //Passwd-Length field
544  TRACE_DEBUG(" Passwd-Length = %" PRIu8 "\r\n", q[0]);
545 
546  //Check the length of the Password field
547  if(length < (sizeof(PapAuthAckPacket) + 1 + p->peerIdLength + q[0]))
548  return ERROR_INVALID_LENGTH;
549 
550  //Password field
551  TRACE_DEBUG(" Password\r\n");
552  TRACE_DEBUG_ARRAY(" ", q + 1, q[0]);
553  }
554  //Authenticate-Ack or Authenticate-Nak packet?
555  else if(packet->code == PAP_CODE_AUTH_ACK ||
556  packet->code == PAP_CODE_AUTH_NAK)
557  {
559 
560  //Cast PAP packet
561  p = (PapAuthAckPacket *) packet;
562 
563  //Valid packet length?
564  if(length < sizeof(PapAuthAckPacket))
565  return ERROR_INVALID_LENGTH;
566 
567  //Msg-Length field
568  TRACE_DEBUG(" Msg-Length = %" PRIu8 "\r\n", p->msgLength);
569 
570  //Check the length of the Message field
571  if(length < (sizeof(PapAuthAckPacket) + p->msgLength))
572  return ERROR_INVALID_LENGTH;
573 
574  if(length > 0)
575  {
576  //Message field
577  TRACE_DEBUG(" Message\r\n");
578  TRACE_DEBUG_ARRAY(" ", p->message, p->msgLength);
579  }
580  }
581  //Unknown packet?
582  else
583  {
584  //Retrieve the length of data
585  length -= sizeof(PppPacket);
586 
587  //Any data?
588  if(length > 0)
589  {
590  //Dump data
591  TRACE_DEBUG(" Data (%" PRIuSIZE " bytes)\r\n", length);
592  TRACE_DEBUG_ARRAY(" ", packet->data, length);
593  }
594  }
595 
596  //No error to report
597  return NO_ERROR;
598 }
599 
600 
601 /**
602  * @brief Dump CHAP packet for debugging purpose
603  * @param[in] packet Pointer to the PAP packet
604  * @param[in] length Length of the packet, in bytes
605  * @return Error code
606  **/
607 
608 error_t chapDumpPacket(const PppPacket *packet, size_t length)
609 {
610  const char_t *label;
611 
612  //Make sure the CHAP packet is valid
613  if(length < sizeof(PppPacket))
614  return ERROR_INVALID_LENGTH;
615 
616  //Check the length field
617  if(ntohs(packet->length) > length)
618  return ERROR_INVALID_LENGTH;
619  if(ntohs(packet->length) < sizeof(PppPacket))
620  return ERROR_INVALID_LENGTH;
621 
622  //Save the length of the CHAP packet
623  length = ntohs(packet->length);
624 
625  //Retrieve the name of the CHAP packet
626  if(packet->code < arraysize(chapCodeLabel))
627  {
628  label = chapCodeLabel[packet->code];
629  }
630  else
631  {
632  label = "Unknown";
633  }
634 
635  //Dump CHAP packet header
636  TRACE_DEBUG(" Code = %" PRIu8 " (%s)\r\n", packet->code, label);
637  TRACE_DEBUG(" Identifier = %" PRIu8 "\r\n", packet->identifier);
638  TRACE_DEBUG(" Length = %" PRIu16 "\r\n", ntohs(packet->length));
639 
640  //Challenge or Response packet?
641  if(packet->code == CHAP_CODE_CHALLENGE ||
642  packet->code == CHAP_CODE_RESPONSE)
643  {
644  uint8_t *q;
646 
647  //Cast CHAP packet
648  p = (ChapChallengePacket *) packet;
649 
650  //Valid packet length?
651  if(length < sizeof(ChapChallengePacket))
652  return ERROR_INVALID_LENGTH;
653 
654  //Value-Size field
655  TRACE_DEBUG(" Value-Size = %" PRIu8 "\r\n", p->valueSize);
656 
657  //Check the length of the Value field
658  if(length < (sizeof(ChapChallengePacket) + p->valueSize))
659  return ERROR_INVALID_LENGTH;
660 
661  //Value field
662  TRACE_DEBUG(" Value\r\n");
663  TRACE_DEBUG_ARRAY(" ", p->value, p->valueSize);
664 
665  //Point to the Name field
666  q = p->value + p->valueSize;
667  //Retrieve the length of the Name field
668  length -= sizeof(ChapChallengePacket) + p->valueSize;
669 
670  //Name field
671  TRACE_DEBUG(" Name (%" PRIuSIZE " bytes)\r\n", length);
672  TRACE_DEBUG_ARRAY(" ", q, length);
673  }
674  //Success or Failure packet?
675  else if(packet->code == CHAP_CODE_SUCCESS ||
676  packet->code == CHAP_CODE_FAILURE)
677  {
679 
680  //Cast CHAP packet
681  p = (ChapSuccessPacket *) packet;
682 
683  //Valid packet length?
684  if(length < sizeof(ChapSuccessPacket))
685  return ERROR_INVALID_LENGTH;
686 
687  //Retrieve the length of Message field
688  length -= sizeof(ChapSuccessPacket);
689 
690  //Message field
691  TRACE_DEBUG(" Message (%" PRIuSIZE " bytes)\r\n", length);
692  TRACE_DEBUG_ARRAY(" ", p->message, length);
693  }
694  //Unknown packet?
695  else
696  {
697  //Retrieve the length of data
698  length -= sizeof(PppPacket);
699 
700  //Any data?
701  if(length > 0)
702  {
703  //Dump data
704  TRACE_DEBUG(" Data (%" PRIuSIZE " bytes)\r\n", length);
705  TRACE_DEBUG_ARRAY(" ", packet->data, length);
706  }
707  }
708 
709  //No error to report
710  return NO_ERROR;
711 }
712 
713 
714 /**
715  * @brief Dump LCP options for debugging purpose
716  * @param[in] option Pointer to the option list
717  * @param[in] length Length of the option list, in bytes
718  * @return Error code
719  **/
720 
721 error_t lcpDumpOptions(const PppOption *option, size_t length)
722 {
723  uint32_t value;
724 
725  //Parse options
726  while(length > 0)
727  {
728  //Malformed LCP packet?
729  if(length < sizeof(PppOption))
730  return ERROR_INVALID_LENGTH;
731 
732  //Check option length
733  if(option->length < sizeof(PppOption))
734  return ERROR_INVALID_LENGTH;
735  if(option->length > length)
736  return ERROR_INVALID_LENGTH;
737 
738  //Display the name of the current option
739  if(option->type < arraysize(lcpOptionLabel))
740  {
741  TRACE_DEBUG(" %s option (%" PRIu8 " bytes)\r\n",
742  lcpOptionLabel[option->type], option->length);
743  }
744  else
745  {
746  TRACE_DEBUG(" Option %" PRIu8 " (%" PRIu8 " bytes)\r\n",
747  option->type, option->length);
748  }
749 
750  //Check option code
751  switch(option->type)
752  {
753  //16-bit unsigned value?
754  case LCP_OPTION_MRU:
755  //Check length field
756  if(option->length != (sizeof(PppOption) + sizeof(uint16_t)))
757  return ERROR_INVALID_OPTION;
758  //Retrieve 16-bit value
759  value = LOAD16BE(option->data);
760  //Dump option contents
761  TRACE_DEBUG(" %" PRIu32 "\r\n", value);
762  break;
763 
764  //32-bit unsigned value?
765  case LCP_OPTION_ACCM:
767  //Check length field
768  if(option->length != (sizeof(PppOption) + sizeof(uint32_t)))
769  return ERROR_INVALID_OPTION;
770  //Retrieve 32-bit value
771  value = LOAD32BE(option->data);
772  //Dump option contents
773  TRACE_DEBUG(" 0x%08" PRIX32 "\r\n", value);
774  break;
775 
776  //Raw data?
777  default:
778  //Dump option contents
779  TRACE_DEBUG_ARRAY(" ", option->data, option->length - sizeof(PppOption));
780  break;
781  }
782 
783  //Remaining bytes to process
784  length -= option->length;
785  //Jump to the next option
786  option = (PppOption *) ((uint8_t *) option + option->length);
787  }
788 
789  //No error to report
790  return NO_ERROR;
791 }
792 
793 /**
794  * @brief Dump IPCP options for debugging purpose
795  * @param[in] option Pointer to the option list
796  * @param[in] length Length of the option list, in bytes
797  * @return Error code
798  **/
799 
800 error_t ipcpDumpOptions(const PppOption *option, size_t length)
801 {
802 #if (IPV4_SUPPORT == ENABLED)
804 #endif
805 
806  //Parse options
807  while(length > 0)
808  {
809  //Malformed IPCP packet?
810  if(length < sizeof(PppOption))
811  return ERROR_INVALID_LENGTH;
812 
813  //Check option length
814  if(option->length < sizeof(PppOption))
815  return ERROR_INVALID_LENGTH;
816  if(option->length > length)
817  return ERROR_INVALID_LENGTH;
818 
819  //Display the name of the current option
820  if(option->type < arraysize(ipcpOptionLabel))
821  {
822  TRACE_DEBUG(" %s option (%" PRIu8 " bytes)\r\n",
823  ipcpOptionLabel[option->type], option->length);
824  }
825  else if(option->type >= 128 && option->type < (128 + arraysize(ipcpOptionLabel2)))
826  {
827  TRACE_DEBUG(" %s option (%" PRIu8 " bytes)\r\n",
828  ipcpOptionLabel2[option->type - 128], option->length);
829  }
830  else
831  {
832  TRACE_DEBUG(" Option %" PRIu8 " (%" PRIu8 " bytes)\r\n",
833  option->type, option->length);
834  }
835 
836  //Check option code
837  switch(option->type)
838  {
839 #if (IPV4_SUPPORT == ENABLED)
840  //IP address?
846  //Check length field
847  if(option->length != (sizeof(PppOption) + sizeof(Ipv4Addr)))
848  return ERROR_INVALID_OPTION;
849  //Retrieve IPv4 address
850  ipv4CopyAddr(&ipAddr, option->data);
851  //Dump option contents
852  TRACE_DEBUG(" %s\r\n", ipv4AddrToString(ipAddr, NULL));
853  break;
854 #endif
855  //Raw data?
856  default:
857  //Dump option contents
858  TRACE_DEBUG_ARRAY(" ", option->data, option->length - sizeof(PppOption));
859  break;
860  }
861 
862  //Remaining bytes to process
863  length -= option->length;
864  //Jump to the next option
865  option = (PppOption *) ((uint8_t *) option + option->length);
866  }
867 
868  //No error to report
869  return NO_ERROR;
870 }
871 
872 
873 /**
874  * @brief Dump IPV6CP options for debugging purpose
875  * @param[in] option Pointer to the option list
876  * @param[in] length Length of the option list, in bytes
877  * @return Error code
878  **/
879 
881 {
882  //Parse options
883  while(length > 0)
884  {
885  //Malformed IPV6CP packet?
886  if(length < sizeof(PppOption))
887  return ERROR_INVALID_LENGTH;
888 
889  //Check option length
890  if(option->length < sizeof(PppOption))
891  return ERROR_INVALID_LENGTH;
892  if(option->length > length)
893  return ERROR_INVALID_LENGTH;
894 
895  //Display the name of the current option
896  if(option->type < arraysize(ipv6cpOptionLabel))
897  {
898  TRACE_DEBUG(" %s option (%" PRIu8 " bytes)\r\n",
899  ipv6cpOptionLabel[option->type], option->length);
900  }
901  else
902  {
903  TRACE_DEBUG(" Option %" PRIu8 " (%" PRIu8 " bytes)\r\n",
904  option->type, option->length);
905  }
906 
907  //Check option code
908  switch(option->type)
909  {
910  //Raw data?
911  default:
912  //Dump option contents
913  TRACE_DEBUG_ARRAY(" ", option->data, option->length - sizeof(PppOption));
914  break;
915  }
916 
917  //Remaining bytes to process
918  length -= option->length;
919  //Jump to the next option
920  option = (PppOption *) ((uint8_t *) option + option->length);
921  }
922 
923  //No error to report
924  return NO_ERROR;
925 }
926 
927 #endif
ChapChallengePacket
Definition: chap.h:128
@ CHAP_CODE_RESPONSE
Response.
Definition: chap.h:91
@ CHAP_CODE_SUCCESS
Success.
Definition: chap.h:92
@ CHAP_CODE_CHALLENGE
Challenge.
Definition: chap.h:90
@ CHAP_CODE_FAILURE
Failure.
Definition: chap.h:93
ChapSuccessPacket
Definition: chap.h:155
#define PRIuSIZE
char char_t
Definition: compiler_port.h:48
#define LOAD32BE(p)
Definition: cpu_endian.h:210
#define htonl(value)
Definition: cpu_endian.h:414
#define htons(value)
Definition: cpu_endian.h:413
#define ntohs(value)
Definition: cpu_endian.h:421
#define LOAD16BE(p)
Definition: cpu_endian.h:186
Debugging facilities.
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:108
#define TRACE_DEBUG(...)
Definition: debug.h:107
error_t
Error codes.
Definition: error.h:43
@ ERROR_INVALID_OPTION
Definition: error.h:98
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_INVALID_LENGTH
Definition: error.h:111
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
Ipv4Addr ipAddr
Definition: ipcp.h:105
@ IPCP_OPTION_IP_ADDRESS
IP-Address.
Definition: ipcp.h:55
@ IPCP_OPTION_PRIMARY_NBNS
Primary-NBNS-Server-Address.
Definition: ipcp.h:57
@ IPCP_OPTION_SECONDARY_NBNS
Secondary-NBNS-Server-Address.
Definition: ipcp.h:59
@ IPCP_OPTION_SECONDARY_DNS
Secondary-DNS-Server-Address.
Definition: ipcp.h:58
@ IPCP_OPTION_PRIMARY_DNS
Primary-DNS-Server-Address.
Definition: ipcp.h:56
char_t * ipv4AddrToString(Ipv4Addr ipAddr, char_t *str)
Convert a binary IPv4 address to dot-decimal notation.
Definition: ipv4.c:1636
#define ipv4CopyAddr(destIpAddr, srcIpAddr)
Definition: ipv4.h:148
uint32_t Ipv4Addr
IPv4 network address.
Definition: ipv4.h:267
uint8_t protocol
Definition: ipv4.h:296
@ LCP_OPTION_MAGIC_NUMBER
Magic-Number.
Definition: lcp.h:54
@ LCP_OPTION_ACCM
Async-Control-Character-Map.
Definition: lcp.h:51
@ LCP_OPTION_MRU
Maximum-Receive-Unit.
Definition: lcp.h:50
uint8_t p
Definition: ndp.h:300
TCP/IP stack core.
#define arraysize(a)
Definition: os_port.h:71
@ PAP_CODE_AUTH_REQ
Authenticate-Request.
Definition: pap.h:88
@ PAP_CODE_AUTH_NAK
Authenticate-Nak.
Definition: pap.h:90
@ PAP_CODE_AUTH_ACK
Authenticate-Ack.
Definition: pap.h:89
PapAuthAckPacket
Definition: pap.h:127
PapAuthReqPacket
Definition: pap.h:113
PppConfigurePacket
Definition: ppp.h:274
PppOption
Definition: ppp.h:354
PppProtocolRejPacket
Definition: ppp.h:314
PppProtocol
Protocol field values.
Definition: ppp.h:198
@ PPP_PROTOCOL_IPCP
IP Control Protocol.
Definition: ppp.h:201
@ PPP_PROTOCOL_LCP
Link Control Protocol.
Definition: ppp.h:203
@ 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_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 PppPacket
Definition: ppp.h:37
PppCodeRejPacket
Definition: ppp.h:300
PppEchoPacket
Definition: ppp.h:328
PppTerminatePacket
Definition: ppp.h:287
error_t ipcpDumpOptions(const PppOption *option, size_t length)
Dump IPCP options for debugging purpose.
Definition: ppp_debug.c:800
error_t lcpDumpOptions(const PppOption *option, size_t length)
Dump LCP options for debugging purpose.
Definition: ppp_debug.c:721
error_t lcpDumpPacket(const PppPacket *packet, size_t length)
Dump LCP packet for debugging purpose.
Definition: ppp_debug.c:188
error_t ipv6cpDumpOptions(const PppOption *option, size_t length)
Dump IPV6CP options for debugging purpose.
Definition: ppp_debug.c:880
error_t ncpDumpPacket(const PppPacket *packet, size_t length, PppProtocol protocol)
Dump NCP packet for debugging purpose.
Definition: ppp_debug.c:350
error_t pppDumpPacket(const PppPacket *packet, size_t length, PppProtocol protocol)
Dump LCP/NCP packet for debugging purpose.
Definition: ppp_debug.c:143
error_t chapDumpPacket(const PppPacket *packet, size_t length)
Dump CHAP packet for debugging purpose.
Definition: ppp_debug.c:608
error_t papDumpPacket(const PppPacket *packet, size_t length)
Dump PAP packet for debugging purpose.
Definition: ppp_debug.c:484
Data logging functions for debugging purpose (PPP)
uint8_t length
Definition: tcp.h:368
uint8_t value[]
Definition: tcp.h:369