dhcpv6_debug.c
Go to the documentation of this file.
1 /**
2  * @file dhcpv6_debug.c
3  * @brief Data logging functions for debugging purpose (DHCPv6)
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.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL DHCPV6_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/net.h"
36 #include "dhcpv6/dhcpv6_debug.h"
37 #include "debug.h"
38 
39 //Check TCP/IP stack configuration
40 #if (IPV6_SUPPORT == ENABLED && DHCPV6_TRACE_LEVEL >= TRACE_LEVEL_DEBUG)
41 
42 //DHCPv6 message types
43 static const char_t *const messageLabel[] =
44 {
45  "",
46  "SOLICIT",
47  "ADVERTISE",
48  "REQUEST",
49  "CONFIRM",
50  "RENEW",
51  "REBIND",
52  "REPLY",
53  "RELEASE",
54  "DECLINE",
55  "RECONFIGURE",
56  "INFO-REQUEST",
57  "RELAY-FORW",
58  "RELAY-REPL"
59 };
60 
61 //DHCPv6 options
62 static const char_t *const optionLabel[] =
63 {
64  "",
65  "Client Identifier",
66  "Server Identifier",
67  "IA_NA",
68  "IA_TA",
69  "IA Address",
70  "Option Request",
71  "Preference",
72  "Elapsed time",
73  "Relay Message",
74  "",
75  "Authentication",
76  "Server Unicast",
77  "Status Code",
78  "Rapid Commit",
79  "User Class",
80  "Vendor Class",
81  "Vendor Specific Information",
82  "Interface ID",
83  "Reconfigure Message",
84  "Reconfigure Accept",
85  "",
86  "",
87  "DNS Recursive Name Server",
88  "Domain Search List"
89 };
90 
91 //DHCPv6 status codes
92 static const char_t *const statusLabel[] =
93 {
94  "Success",
95  "Unspecified Failure",
96  "No Address Available",
97  "No Binding",
98  "Not On Link",
99  "Use Multicast",
100 };
101 
102 //Prefix used to format the structure
103 static const char_t *const prefix[8] =
104 {
105  "",
106  " ",
107  " ",
108  " ",
109  " ",
110  " ",
111  " ",
112  " "
113 };
114 
115 
116 /**
117  * @brief Dump DHCPv6 message for debugging purpose
118  * @param[in] message Pointer to the DHCPv6 message to dump
119  * @param[in] length Length of the message
120  * @return Error code
121  **/
122 
124 {
125  error_t error;
126  uint8_t type;
127  const char_t *label;
128 
129  //Empty message?
130  if(!length)
131  return ERROR_INVALID_LENGTH;
132 
133  //Retrieve the message type
134  type = *((uint8_t *) message);
135  //Get the corresponding label
136  label = (type < arraysize(messageLabel)) ? messageLabel[type] : "Unknown";
137 
138  //Relay agent/server message?
140  {
141  //Ensure the length of the DHCPv6 message is acceptable
142  if(length < sizeof(Dhcpv6RelayMessage))
143  {
144  //Report an error
145  error = ERROR_INVALID_LENGTH;
146  }
147  else
148  {
149  //Point to the DHCPv6 message
150  const Dhcpv6RelayMessage *relayMessage = message;
151 
152  //Dump message header
153  TRACE_DEBUG(" Message Type = %" PRIu8 " (%s)\r\n", relayMessage->msgType, label);
154  TRACE_DEBUG(" Hop Count = %" PRIu8 "\r\n", relayMessage->hopCount);
155  TRACE_DEBUG(" Link Address = %s\r\n", ipv6AddrToString(&relayMessage->linkAddress, NULL));
156  TRACE_DEBUG(" Peer Address = %s\r\n", ipv6AddrToString(&relayMessage->peerAddress, NULL));
157 
158  //Dump message options
159  error = dhcpv6DumpOptions(relayMessage->options, length - sizeof(Dhcpv6RelayMessage), 1);
160  }
161 
162  }
163  //Client/server message?
164  else
165  {
166  //Ensure the length of the DHCPv6 message is acceptable
167  if(length < sizeof(Dhcpv6Message))
168  {
169  //Report an error
170  error = ERROR_INVALID_LENGTH;
171  }
172  else
173  {
174  //Point to the DHCPv6 message
175  const Dhcpv6Message *clientMessage = message;
176 
177  //Dump message header
178  TRACE_DEBUG(" Message Type = %" PRIu8 " (%s)\r\n", clientMessage->msgType, label);
179  TRACE_DEBUG(" Transaction ID = 0x%06" PRIX32 "\r\n", LOAD24BE(clientMessage->transactionId));
180 
181  //Dump message options
182  error = dhcpv6DumpOptions(clientMessage->options, length - sizeof(Dhcpv6Message), 1);
183  }
184  }
185 
186  //Did we encounter an error?
187  if(error)
188  {
189  //Debug message
190  TRACE_WARNING("DHCPv6 message is not valid!\r\n");
191  //Dump message contents for debugging purpose
193  }
194 
195  //Return status code
196  return error;
197 }
198 
199 
200 /**
201  * @brief Dump DHCPv6 options for debugging purpose
202  * @param[in] options Pointer to the DHCPv6 options to dump
203  * @param[in] length Length of the options
204  * @param[in] level Current level of recursion
205  * @return Error code
206  **/
207 
208 error_t dhcpv6DumpOptions(const uint8_t *options, size_t length, uint_t level)
209 {
210  error_t error;
211  size_t i;
212  Dhcpv6Option *option;
213 
214  //Check whether the maximum level of recursion is reached
215  if(level >= 6)
216  {
217  //If the maximum level of recursion is reached, then dump contents
218  TRACE_DEBUG("%sOptions (%" PRIuSIZE " bytes)\r\n", prefix[level], length);
219  TRACE_DEBUG_ARRAY(prefix[level + 1], options, length);
220  //Exit immediately
221  return NO_ERROR;
222  }
223 
224  //Parse DHCPv6 options
225  for(i = 0; i < length; )
226  {
227  //Point to the current option
228  option = (Dhcpv6Option *) (options + i);
229 
230  //Make sure the option is valid
231  if((i + sizeof(Dhcpv6Option)) > length)
232  return ERROR_INVALID_OPTION;
233  //Check the length of the option data
234  if((i + sizeof(Dhcpv6Option) + ntohs(option->length)) > length)
235  return ERROR_INVALID_OPTION;
236 
237  //Check option code
238  switch(ntohs(option->code))
239  {
240  //Client Identifier option
242  error = dhcpv6DumpClientIdOption(option, level);
243  break;
244  //Server Identifier option
246  error = dhcpv6DumpServerIdOption(option, level);
247  break;
248  //IA_NA option
249  case DHCPV6_OPT_IA_NA:
250  error = dhcpv6DumpIaNaOption(option, level);
251  break;
252  //IA_TA option
253  case DHCPV6_OPT_IA_TA:
254  error = dhcpv6DumpIaTaOption(option, level);
255  break;
256  //IA Address option
257  case DHCPV6_OPT_IA_ADDR:
258  error = dhcpv6DumpIaAddrOption(option, level);
259  break;
260  //Option Request option
261  case DHCPV6_OPT_ORO:
262  error = dhcpv6DumpOroOption(option, level);
263  break;
264  //Preference option
266  error = dhcpv6DumpPreferenceOption(option, level);
267  break;
268  //Elapsed Time option
270  error = dhcpv6DumpElapsedTimeOption(option, level);
271  break;
272  //Relay Message option
274  error = dhcpv6DumpRelayMessageOption(option, level);
275  break;
276  //Authentication option
277  case DHCPV6_OPT_AUTH:
278  error = dhcpv6DumpAuthOption(option, level);
279  break;
280  //Server Unicast option
281  case DHCPV6_OPT_UNICAST:
282  error = dhcpv6DumpServerUnicastOption(option, level);
283  break;
284  //Status Code option
286  error = dhcpv6DumpStatusCodeOption(option, level);
287  break;
288  //Rapid Commit option
290  error = dhcpv6DumpRapidCommitOption(option, level);
291  break;
292  //User Class option
294  error = dhcpv6DumpUserClassOption(option, level);
295  break;
296  //Vendor Class option
298  error = dhcpv6DumpVendorClassOption(option, level);
299  break;
300  //Vendor Specific Information option
302  error = dhcpv6DumpVendorSpecificInfoOption(option, level);
303  break;
304  //Interface ID option
306  error = dhcpv6DumpInterfaceIdOption(option, level);
307  break;
308  //Reconfigure Message option
310  error = dhcpv6DumpReconfMessageOption(option, level);
311  break;
312  //Reconfigure Accept option
314  error = dhcpv6DumpReconfAcceptOption(option, level);
315  break;
316  //DNS Recursive Name Server option
318  error = dhcpv6DumpDnsServersOption(option, level);
319  break;
320  //Domain Search List option
322  error = dhcpv6DumpDomainListOption(option, level);
323  break;
324  //Unknown option
325  default:
326  error = dhcpv6DumpGenericOption(option, level);
327  break;
328  }
329 
330  //Failed to parse current option?
331  if(error)
332  return error;
333 
334  //Jump to the next option
335  i += sizeof(Dhcpv6Option) + ntohs(option->length);
336  }
337 
338  //No error to report
339  return NO_ERROR;
340 
341 }
342 
343 
344 /**
345  * @brief Dump generic DHCPv6 option
346  * @param[in] option Pointer to the option to dump
347  * @param[in] level Current level of recursion
348  * @return Error code
349  **/
350 
352 {
353  //Dump contents
354  TRACE_DEBUG("%sOption %" PRIu16 " (%" PRIu16 " bytes)\r\n", prefix[level], ntohs(option->code), ntohs(option->length));
355  TRACE_DEBUG_ARRAY(prefix[level + 1], option->value, ntohs(option->length));
356 
357  //No error to report
358  return NO_ERROR;
359 }
360 
361 
362 /**
363  * @brief Dump Client Identifier option
364  * @param[in] option Pointer to the option to dump
365  * @param[in] level Current level of recursion
366  * @return Error code
367  **/
368 
370 {
371  //Dump contents
372  TRACE_DEBUG("%sClient Identifier option (%" PRIu16 " bytes)\r\n", prefix[level], ntohs(option->length));
373  TRACE_DEBUG_ARRAY(prefix[level + 1], option->value, ntohs(option->length));
374 
375  //No error to report
376  return NO_ERROR;
377 }
378 
379 
380 /**
381  * @brief Dump Server Identifier option
382  * @param[in] option Pointer to the option to dump
383  * @param[in] level Current level of recursion
384  * @return Error code
385  **/
386 
388 {
389  //Dump contents
390  TRACE_DEBUG("%sServer Identifier option (%" PRIu16 " bytes)\r\n", prefix[level], ntohs(option->length));
391  TRACE_DEBUG_ARRAY(prefix[level + 1], option->value, ntohs(option->length));
392 
393  //No error to report
394  return NO_ERROR;
395 }
396 
397 
398 /**
399  * @brief Dump IA_NA option
400  * @param[in] option Pointer to the option to dump
401  * @param[in] level Current level of recursion
402  * @return Error code
403  **/
404 
406 {
407  Dhcpv6IaNaOption *iaNaOption;
408 
409  //Check the length of the option
410  if(ntohs(option->length) < sizeof(Dhcpv6IaNaOption))
411  return ERROR_INVALID_OPTION;
412 
413  //Point to the option contents
414  iaNaOption = (Dhcpv6IaNaOption *) option->value;
415 
416  //Dump contents
417  TRACE_DEBUG("%sIA_NA option (%" PRIu16 " bytes)\r\n", prefix[level], ntohs(option->length));
418  TRACE_DEBUG("%sIA ID = 0x%08" PRIX32 "\r\n", prefix[level + 1], ntohl(iaNaOption->iaId));
419  TRACE_DEBUG("%sT1 = %" PRIu32 "s\r\n", prefix[level + 1], ntohl(iaNaOption->t1));
420  TRACE_DEBUG("%sT2 = %" PRIu32 "s\r\n", prefix[level + 1], ntohl(iaNaOption->t2));
421 
422  //Dump the options associated with this IA_NA
423  dhcpv6DumpOptions(iaNaOption->options, ntohs(option->length) - sizeof(Dhcpv6IaNaOption), level + 1);
424 
425  //No error to report
426  return NO_ERROR;
427 }
428 
429 
430 /**
431  * @brief Dump IA_TA option
432  * @param[in] option Pointer to the option to dump
433  * @param[in] level Current level of recursion
434  * @return Error code
435  **/
436 
438 {
439  Dhcpv6IaTaOption *iaTaOption;
440 
441  //Check the length of the option
442  if(ntohs(option->length) < sizeof(Dhcpv6IaTaOption))
443  return ERROR_INVALID_OPTION;
444 
445  //Point to the option contents
446  iaTaOption = (Dhcpv6IaTaOption *) option->value;
447 
448  //Dump contents
449  TRACE_DEBUG("%sIA_TA option (%" PRIu16 " bytes)\r\n", prefix[level], ntohs(option->length));
450  TRACE_DEBUG("%sIA ID = 0x%08" PRIX32 "\r\n", prefix[level + 1], ntohl(iaTaOption->iaId));
451 
452  //Dump the options associated with this IA_TA
453  dhcpv6DumpOptions(iaTaOption->options, ntohs(option->length) - sizeof(Dhcpv6IaTaOption), level + 1);
454 
455  //No error to report
456  return NO_ERROR;
457 }
458 
459 
460 /**
461  * @brief Dump IA Address option
462  * @param[in] option Pointer to the option to dump
463  * @param[in] level Current level of recursion
464  * @return Error code
465  **/
466 
468 {
469  Dhcpv6IaAddrOption *iaAddrOption;
470 
471  //Check the length of the option
472  if(ntohs(option->length) < sizeof(Dhcpv6IaAddrOption))
473  return ERROR_INVALID_OPTION;
474 
475  //Point to the option contents
476  iaAddrOption = (Dhcpv6IaAddrOption *) option->value;
477 
478  //Dump contents
479  TRACE_DEBUG("%sIA Address option (%" PRIu16 " bytes)\r\n", prefix[level], ntohs(option->length));
480  TRACE_DEBUG("%sIPv6 Address = %s\r\n", prefix[level + 1], ipv6AddrToString(&iaAddrOption->address, NULL));
481  TRACE_DEBUG("%sPreferred Lifetime = %" PRIu32 "s\r\n", prefix[level + 1], ntohl(iaAddrOption->preferredLifetime));
482  TRACE_DEBUG("%sValid Lifetime = %" PRIu32 "s\r\n", prefix[level + 1], ntohl(iaAddrOption->validLifetime));
483 
484  //Dump the options associated with this IA address
485  dhcpv6DumpOptions(iaAddrOption->options, ntohs(option->length) - sizeof(Dhcpv6IaAddrOption), level + 1);
486 
487  //No error to report
488  return NO_ERROR;
489 }
490 
491 
492 /**
493  * @brief Dump Option Request option
494  * @param[in] option Pointer to the option to dump
495  * @param[in] level Current level of recursion
496  * @return Error code
497  **/
498 
500 {
501  uint_t i;
502  uint_t n;
503  uint16_t code;
504  const char_t *label;
505  Dhcpv6OroOption *oroOption;
506 
507  //Check the length of the option
508  if(ntohs(option->length) % 2)
509  return ERROR_INVALID_OPTION;
510 
511  //Point to the option contents
512  oroOption = (Dhcpv6OroOption *) option->value;
513  //Get the number of requested options
514  n = ntohs(option->length) / 2;
515 
516  //Dump contents
517  TRACE_DEBUG("%sOption Request option (%" PRIu16 " bytes)\r\n", prefix[level], ntohs(option->length));
518 
519  //Parse the list of requested options
520  for(i = 0; i < n; i++)
521  {
522  //Get current option code
523  code = ntohs(oroOption->requestedOption[i]);
524  //Find the name associated with this option code
525  label = (code < arraysize(optionLabel)) ? optionLabel[code] : "Unknown";
526  //Display option code and option name
527  TRACE_DEBUG("%s%" PRIu16 " (%s option)\r\n", prefix[level + 1], code, label);
528  }
529 
530  //No error to report
531  return NO_ERROR;
532 }
533 
534 
535 /**
536  * @brief Dump Preference option
537  * @param[in] option Pointer to the option to dump
538  * @param[in] level Current level of recursion
539  * @return Error code
540  **/
541 
543 {
544  Dhcpv6PreferenceOption *preferenceOption;
545 
546  //Check the length of the option
547  if(ntohs(option->length) != sizeof(Dhcpv6PreferenceOption))
548  return ERROR_INVALID_OPTION;
549 
550  //Point to the option contents
551  preferenceOption = (Dhcpv6PreferenceOption *) option->value;
552 
553  //Dump contents
554  TRACE_DEBUG("%sPreference option (%" PRIu16 " bytes)\r\n", prefix[level], ntohs(option->length));
555  TRACE_DEBUG("%s%" PRIu8 "\r\n", prefix[level + 1], preferenceOption->value);
556 
557  //No error to report
558  return NO_ERROR;
559 }
560 
561 
562 /**
563  * @brief Dump Elapsed Time option
564  * @param[in] option Pointer to the option to dump
565  * @param[in] level Current level of recursion
566  * @return Error code
567  **/
568 
570 {
571  uint32_t value;
572  Dhcpv6ElapsedTimeOption *elapsedTimeOption;
573 
574  //Check the length of the option
575  if(ntohs(option->length) != sizeof(Dhcpv6ElapsedTimeOption))
576  return ERROR_INVALID_OPTION;
577 
578  //Point to the option contents
579  elapsedTimeOption = (Dhcpv6ElapsedTimeOption *) option->value;
580  //Convert the value to milliseconds
581  value = ntohs(elapsedTimeOption->value) * 10;
582 
583  //Dump contents
584  TRACE_DEBUG("%sElapsed Time option (%" PRIu16 " bytes)\r\n", prefix[level], ntohs(option->length));
585  TRACE_DEBUG("%s%" PRIu32 "ms\r\n", prefix[level + 1], value);
586 
587  //No error to report
588  return NO_ERROR;
589 }
590 
591 
592 /**
593  * @brief Dump Relay Message option
594  * @param[in] option Pointer to the option to dump
595  * @param[in] level Current level of recursion
596  * @return Error code
597  **/
598 
600 {
601  uint8_t type;
602  const char_t *label;
603 
604  //Check the length of the option
605  if(!ntohs(option->length))
606  return ERROR_INVALID_OPTION;
607 
608  //Retrieve the message type
609  type = option->value[0];
610  //Get the corresponding label
611  label = (type < arraysize(messageLabel)) ? messageLabel[type] : "Unknown";
612 
613  //Relay agent/server message?
615  {
616  //Get the inner message
617  const Dhcpv6RelayMessage *message = (Dhcpv6RelayMessage *) option->value;
618 
619  //Ensure the length of the DHCPv6 message is acceptable
620  if(ntohs(option->length) < sizeof(Dhcpv6RelayMessage))
621  return ERROR_INVALID_OPTION;
622 
623  //Dump message header
624  TRACE_DEBUG("%sRelay Message option (%" PRIu16 " bytes)\r\n", prefix[level], ntohs(option->length));
625  TRACE_DEBUG("%sMessage Type = %" PRIu8 " (%s)\r\n", prefix[level + 1], message->msgType, label);
626  TRACE_DEBUG("%sHop Count = %" PRIu8 "\r\n", prefix[level + 1], message->hopCount);
627  TRACE_DEBUG("%sLink Address = %s\r\n", prefix[level + 1], ipv6AddrToString(&message->linkAddress, NULL));
628  TRACE_DEBUG("%sPeer Address = %s\r\n", prefix[level + 1], ipv6AddrToString(&message->peerAddress, NULL));
629 
630  //Dump message options
631  return dhcpv6DumpOptions(message->options, ntohs(option->length) - sizeof(Dhcpv6RelayMessage), level + 1);
632  }
633  //Client/server message?
634  else
635  {
636  //Get the inner message
637  const Dhcpv6Message *message = (Dhcpv6Message *) option->value;
638 
639  //Ensure the length of the DHCPv6 message is acceptable
640  if(ntohs(option->length) < sizeof(Dhcpv6Message))
641  return ERROR_INVALID_OPTION;
642 
643  //Dump message header
644  TRACE_DEBUG("%sRelay Message option (%" PRIu16 " bytes)\r\n", prefix[level], ntohs(option->length));
645  TRACE_DEBUG("%sMessage Type = %" PRIu8 " (%s)\r\n", prefix[level + 1], message->msgType, label);
646  TRACE_DEBUG("%sTransaction ID = 0x%06" PRIX32 "\r\n", prefix[level + 1], LOAD24BE(message->transactionId));
647 
648  //Dump message options
649  return dhcpv6DumpOptions(message->options, ntohs(option->length) - sizeof(Dhcpv6Message), level + 1);
650  }
651 }
652 
653 
654 /**
655  * @brief Dump Authentication option
656  * @param[in] option Pointer to the option to dump
657  * @param[in] level Current level of recursion
658  * @return Error code
659  **/
660 
662 {
663  size_t n;
664  Dhcpv6AuthOption *authOption;
665 
666  //Check the length of the option
667  if(ntohs(option->length) < sizeof(Dhcpv6AuthOption))
668  return ERROR_INVALID_OPTION;
669 
670  //Point to the option contents
671  authOption = (Dhcpv6AuthOption *) option->value;
672  //Get the length of the authentication information
673  n = ntohs(option->length) - sizeof(Dhcpv6AuthOption);
674 
675  //Dump contents
676  TRACE_DEBUG("%sAuthentication option (%" PRIu16 " bytes)\r\n", prefix[level], ntohs(option->length));
677  TRACE_DEBUG("%sProtocol = %" PRIu8 "\r\n", prefix[level + 1], authOption->protocol);
678  TRACE_DEBUG("%sAlgorithm = %" PRIu8 "\r\n", prefix[level + 1], authOption->algorithm);
679  TRACE_DEBUG("%sRDM = %" PRIu8 "\r\n", prefix[level + 1], authOption->rdm);
680  TRACE_DEBUG("%sReplay Detection\r\n", prefix[level + 1]);
681  TRACE_DEBUG_ARRAY(prefix[level + 2], authOption->replayDetection, 8);
682  TRACE_DEBUG("%sAuthentication Information (%" PRIuSIZE " bytes)\r\n", prefix[level + 1], n);
683  TRACE_DEBUG_ARRAY(prefix[level + 2], authOption->authInfo, n);
684 
685  //No error to report
686  return NO_ERROR;
687 }
688 
689 
690 /**
691  * @brief Dump Server Unicast option
692  * @param[in] option Pointer to the option to dump
693  * @param[in] level Current level of recursion
694  * @return Error code
695  **/
696 
698 {
699  Dhcpv6ServerUnicastOption *serverUnicastOption;
700 
701  //Check the length of the option
702  if(ntohs(option->length) != sizeof(Dhcpv6ServerUnicastOption))
703  return ERROR_INVALID_OPTION;
704 
705  //Point to the option contents
706  serverUnicastOption = (Dhcpv6ServerUnicastOption *) option->value;
707 
708  //Dump contents
709  TRACE_DEBUG("%sServer Unicast option (%" PRIu16 " bytes)\r\n", prefix[level], ntohs(option->length));
710  TRACE_DEBUG("%s%s\r\n", prefix[level + 1], ipv6AddrToString(&serverUnicastOption->serverAddr, NULL));
711 
712  //No error to report
713  return NO_ERROR;
714 }
715 
716 
717 /**
718  * @brief Dump Status Code option
719  * @param[in] option Pointer to the option to dump
720  * @param[in] level Current level of recursion
721  * @return Error code
722  **/
723 
725 {
726  uint16_t code;
727  const char_t *label;
728  Dhcpv6StatusCodeOption *statusCodeOption;
729 
730  //Check the length of the option
731  if(ntohs(option->length) < sizeof(Dhcpv6StatusCodeOption))
732  return ERROR_INVALID_OPTION;
733 
734  //Point to the option contents
735  statusCodeOption = (Dhcpv6StatusCodeOption *) option->value;
736  //Get the status code
737  code = ntohs(statusCodeOption->statusCode);
738  //Get the label associated with the status code
739  label = (code < arraysize(statusLabel)) ? statusLabel[code] : "Unknown";
740 
741  //Dump contents
742  TRACE_DEBUG("%sStatus Code option (%" PRIu16 " bytes)\r\n", prefix[level], ntohs(option->length));
743  TRACE_DEBUG("%sCode = %" PRIu16 " (%s)\r\n", prefix[level + 1], code, label);
744  TRACE_DEBUG("%sMessage = %s\r\n", prefix[level + 1], statusCodeOption->statusMessage);
745 
746  //No error to report
747  return NO_ERROR;
748 }
749 
750 
751 /**
752  * @brief Dump Rapid Commit option
753  * @param[in] option Pointer to the option to dump
754  * @param[in] level Current level of recursion
755  * @return Error code
756  **/
757 
759 {
760  //Check the length of the option
761  if(ntohs(option->length) != 0)
762  return ERROR_INVALID_OPTION;
763 
764  //Dump contents
765  TRACE_DEBUG("%sRapid Commit option (%" PRIu16 " bytes)\r\n", prefix[level], ntohs(option->length));
766 
767  //No error to report
768  return NO_ERROR;
769 }
770 
771 
772 /**
773  * @brief Dump User Class option
774  * @param[in] option Pointer to the option to dump
775  * @param[in] level Current level of recursion
776  * @return Error code
777  **/
778 
780 {
781  //Dump contents
782  TRACE_DEBUG("%sUser Class option (%" PRIu16 " bytes)\r\n", prefix[level], ntohs(option->length));
783  TRACE_DEBUG_ARRAY(prefix[level + 1], option->value, ntohs(option->length));
784 
785  //No error to report
786  return NO_ERROR;
787 }
788 
789 
790 /**
791  * @brief Dump Vendor Class option
792  * @param[in] option Pointer to the option to dump
793  * @param[in] level Current level of recursion
794  * @return Error code
795  **/
796 
798 {
799  //Dump contents
800  TRACE_DEBUG("%sVendor Class option (%" PRIu16 " bytes)\r\n", prefix[level], ntohs(option->length));
801  TRACE_DEBUG_ARRAY(prefix[level + 1], option->value, ntohs(option->length));
802 
803  //No error to report
804  return NO_ERROR;
805 }
806 
807 
808 /**
809  * @brief Dump Vendor Specific Information option
810  * @param[in] option Pointer to the option to dump
811  * @param[in] level Current level of recursion
812  * @return Error code
813  **/
814 
816 {
817  //Dump contents
818  TRACE_DEBUG("%sVendor Specific Information option (%" PRIu16 " bytes)\r\n", prefix[level], ntohs(option->length));
819  TRACE_DEBUG_ARRAY(prefix[level + 1], option->value, ntohs(option->length));
820 
821  //No error to report
822  return NO_ERROR;
823 }
824 
825 
826 /**
827  * @brief Dump Interface ID option
828  * @param[in] option Pointer to the option to dump
829  * @param[in] level Current level of recursion
830  * @return Error code
831  **/
832 
834 {
835  //Dump contents
836  TRACE_DEBUG("%sInterface ID option (%" PRIu16 " bytes)\r\n", prefix[level], ntohs(option->length));
837  TRACE_DEBUG_ARRAY(prefix[level + 1], option->value, ntohs(option->length));
838 
839  //No error to report
840  return NO_ERROR;
841 }
842 
843 
844 /**
845  * @brief Dump Reconfigure Message option
846  * @param[in] option Pointer to the option to dump
847  * @param[in] level Current level of recursion
848  * @return Error code
849  **/
850 
852 {
853  Dhcpv6ReconfMessageOption *reconfMessageOption;
854 
855  //Check the length of the option
856  if(ntohs(option->length) != sizeof(Dhcpv6ReconfMessageOption))
857  return ERROR_INVALID_OPTION;
858 
859  //Point to the option contents
860  reconfMessageOption = (Dhcpv6ReconfMessageOption *) option->value;
861 
862  //Dump contents
863  TRACE_DEBUG("%sReconfigure Message option (%" PRIu16 " bytes)\r\n", prefix[level], ntohs(option->length));
864  TRACE_DEBUG("%sMessage Type = %" PRIu8 "\r\n", prefix[level + 1], reconfMessageOption->msgType);
865 
866  //No error to report
867  return NO_ERROR;
868 }
869 
870 
871 /**
872  * @brief Dump Reconfigure Accept option
873  * @param[in] option Pointer to the option to dump
874  * @param[in] level Current level of recursion
875  * @return Error code
876  **/
877 
879 {
880  //Check the length of the option
881  if(ntohs(option->length) != 0)
882  return ERROR_INVALID_OPTION;
883 
884  //Dump contents
885  TRACE_DEBUG("%sReconfigure Accept option (%" PRIu16 " bytes)\r\n", prefix[level], ntohs(option->length));
886 
887  //No error to report
888  return NO_ERROR;
889 }
890 
891 
892 /**
893  * @brief Dump DNS Recursive Name Server option
894  * @param[in] option Pointer to the option to dump
895  * @param[in] level Current level of recursion
896  * @return Error code
897  **/
898 
900 {
901  uint_t i;
902  uint_t n;
903  Dhcpv6DnsServersOption *dnsServersOption;
904 
905  //Check the length of the option
906  if(ntohs(option->length) % sizeof(Ipv6Addr))
907  return ERROR_INVALID_OPTION;
908 
909  //Point to the option contents
910  dnsServersOption = (Dhcpv6DnsServersOption *) option->value;
911  //Calculate the number of IPv6 addresses in the list
912  n = ntohs(option->length) / sizeof(Ipv6Addr);
913 
914  //Dump contents
915  TRACE_DEBUG("%sDNS Recursive Name Server option (%" PRIu16 " bytes)\r\n",
916  prefix[level], ntohs(option->length));
917 
918  //Diplay the DNS servers
919  for(i = 0; i < n; i++)
920  {
921  TRACE_DEBUG("%s%s\r\n", prefix[level + 1], ipv6AddrToString(dnsServersOption->address + i, NULL));
922  }
923 
924  //No error to report
925  return NO_ERROR;
926 }
927 
928 
929 /**
930  * @brief Dump Domain Search List option
931  * @param[in] option Pointer to the option to dump
932  * @param[in] level Current level of recursion
933  * @return Error code
934  **/
935 
937 {
938  //Dump contents
939  TRACE_DEBUG("%sDomain Search List option (%" PRIu16 " bytes)\r\n", prefix[level], ntohs(option->length));
940  TRACE_DEBUG_ARRAY(prefix[level + 1], option->value, ntohs(option->length));
941 
942  //No error to report
943  return NO_ERROR;
944 }
945 
946 #endif
char_t * ipv6AddrToString(const Ipv6Addr *ipAddr, char_t *str)
Convert a binary IPv6 address to a string representation.
Definition: ipv6.c:2329
error_t dhcpv6DumpVendorClassOption(const Dhcpv6Option *option, uint_t level)
Dump Vendor Class option.
Definition: dhcpv6_debug.c:797
error_t dhcpv6DumpGenericOption(const Dhcpv6Option *option, uint_t level)
Dump generic DHCPv6 option.
Definition: dhcpv6_debug.c:351
error_t dhcpv6DumpUserClassOption(const Dhcpv6Option *option, uint_t level)
Dump User Class option.
Definition: dhcpv6_debug.c:779
error_t dhcpv6DumpDomainListOption(const Dhcpv6Option *option, uint_t level)
Dump Domain Search List option.
Definition: dhcpv6_debug.c:936
uint8_t code
Definition: coap_common.h:179
error_t dhcpv6DumpAuthOption(const Dhcpv6Option *option, uint_t level)
Dump Authentication option.
Definition: dhcpv6_debug.c:661
Dhcpv6OroOption
@ DHCPV6_OPT_IA_ADDR
@ DHCPV6_OPT_IA_NA
uint8_t message[]
Definition: chap.h:154
error_t dhcpv6DumpRapidCommitOption(const Dhcpv6Option *option, uint_t level)
Dump Rapid Commit option.
Definition: dhcpv6_debug.c:758
@ DHCPV6_OPT_IA_TA
@ DHCPV6_MSG_TYPE_RELAY_FORW
Dhcpv6DnsServersOption
Ipv6Addr
Definition: ipv6.h:260
uint8_t type
Definition: coap_common.h:176
Dhcpv6Message
error_t dhcpv6DumpClientIdOption(const Dhcpv6Option *option, uint_t level)
Dump Client Identifier option.
Definition: dhcpv6_debug.c:369
error_t dhcpv6DumpIaNaOption(const Dhcpv6Option *option, uint_t level)
Dump IA_NA option.
Definition: dhcpv6_debug.c:405
@ DHCPV6_OPT_AUTH
Dhcpv6ServerUnicastOption
Ipv6Addr prefix
error_t dhcpv6DumpReconfMessageOption(const Dhcpv6Option *option, uint_t level)
Dump Reconfigure Message option.
Definition: dhcpv6_debug.c:851
Dhcpv6RelayMessage
@ DHCPV6_OPT_DOMAIN_LIST
error_t dhcpv6DumpRelayMessageOption(const Dhcpv6Option *option, uint_t level)
Dump Relay Message option.
Definition: dhcpv6_debug.c:599
error_t dhcpv6DumpIaTaOption(const Dhcpv6Option *option, uint_t level)
Dump IA_TA option.
Definition: dhcpv6_debug.c:437
error_t dhcpv6DumpStatusCodeOption(const Dhcpv6Option *option, uint_t level)
Dump Status Code option.
Definition: dhcpv6_debug.c:724
@ DHCPV6_OPT_CLIENT_ID
error_t dhcpv6DumpOroOption(const Dhcpv6Option *option, uint_t level)
Dump Option Request option.
Definition: dhcpv6_debug.c:499
error_t dhcpv6DumpVendorSpecificInfoOption(const Dhcpv6Option *option, uint_t level)
Dump Vendor Specific Information option.
Definition: dhcpv6_debug.c:815
@ DHCPV6_OPT_ELAPSED_TIME
error_t dhcpv6DumpServerIdOption(const Dhcpv6Option *option, uint_t level)
Dump Server Identifier option.
Definition: dhcpv6_debug.c:387
error_t
Error codes.
Definition: error.h:43
Dhcpv6Option
Dhcpv6ElapsedTimeOption
Dhcpv6AuthOption
Dhcpv6PreferenceOption
@ ERROR_INVALID_LENGTH
Definition: error.h:111
error_t dhcpv6DumpDnsServersOption(const Dhcpv6Option *option, uint_t level)
Dump DNS Recursive Name Server option.
Definition: dhcpv6_debug.c:899
@ DHCPV6_OPT_INTERFACE_ID
Dhcpv6StatusCodeOption
uint8_t length
Definition: tcp.h:368
error_t dhcpv6DumpPreferenceOption(const Dhcpv6Option *option, uint_t level)
Dump Preference option.
Definition: dhcpv6_debug.c:542
@ DHCPV6_OPT_UNICAST
error_t dhcpv6DumpReconfAcceptOption(const Dhcpv6Option *option, uint_t level)
Dump Reconfigure Accept option.
Definition: dhcpv6_debug.c:878
@ DHCPV6_MSG_TYPE_RELAY_REPL
#define ntohs(value)
Definition: cpu_endian.h:421
Dhcpv6IaTaOption
error_t dhcpv6DumpElapsedTimeOption(const Dhcpv6Option *option, uint_t level)
Dump Elapsed Time option.
Definition: dhcpv6_debug.c:569
#define TRACE_WARNING(...)
Definition: debug.h:85
#define TRACE_DEBUG(...)
Definition: debug.h:107
Dhcpv6ReconfMessageOption
error_t dhcpv6DumpOptions(const uint8_t *options, size_t length, uint_t level)
Dump DHCPv6 options for debugging purpose.
Definition: dhcpv6_debug.c:208
char char_t
Definition: compiler_port.h:48
@ DHCPV6_OPT_USER_CLASS
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:108
@ DHCPV6_OPT_VENDOR_CLASS
Dhcpv6IaAddrOption
uint8_t n
error_t dhcpv6DumpIaAddrOption(const Dhcpv6Option *option, uint_t level)
Dump IA Address option.
Definition: dhcpv6_debug.c:467
@ DHCPV6_OPT_RELAY_MSG
error_t dhcpv6DumpMessage(const void *message, size_t length)
Dump DHCPv6 message for debugging purpose.
Definition: dhcpv6_debug.c:123
@ DHCPV6_OPT_RECONF_ACCEPT
@ DHCPV6_OPT_PREFERENCE
#define LOAD24BE(p)
Definition: cpu_endian.h:197
uint8_t value[]
Definition: tcp.h:369
error_t dhcpv6DumpServerUnicastOption(const Dhcpv6Option *option, uint_t level)
Dump Server Unicast option.
Definition: dhcpv6_debug.c:697
@ DHCPV6_OPT_DNS_SERVERS
Dhcpv6IaNaOption
uint8_t options[]
Definition: tcp.h:357
@ ERROR_INVALID_OPTION
Definition: error.h:98
@ DHCPV6_OPT_ORO
@ DHCPV6_OPT_SERVER_ID
#define PRIuSIZE
unsigned int uint_t
Definition: compiler_port.h:50
TCP/IP stack core.
@ DHCPV6_OPT_RECONF_MSG
error_t dhcpv6DumpInterfaceIdOption(const Dhcpv6Option *option, uint_t level)
Dump Interface ID option.
Definition: dhcpv6_debug.c:833
@ DHCPV6_OPT_STATUS_CODE
#define ntohl(value)
Definition: cpu_endian.h:422
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
Data logging functions for debugging purpose (DHCPv6)
#define arraysize(a)
Definition: os_port.h:71
@ DHCPV6_OPT_RAPID_COMMIT
@ DHCPV6_OPT_VENDOR_OPTS