dhcp_debug.c
Go to the documentation of this file.
1 /**
2  * @file dhcp_debug.c
3  * @brief Data logging functions for debugging purpose (DHCP)
4  *
5  * @section License
6  *
7  * Copyright (C) 2010-2018 Oryx Embedded SARL. All rights reserved.
8  *
9  * This file is part of CycloneTCP Open.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @author Oryx Embedded SARL (www.oryx-embedded.com)
26  * @version 1.9.0
27  **/
28 
29 //Switch to the appropriate trace level
30 #define TRACE_LEVEL DHCP_TRACE_LEVEL
31 
32 //Dependencies
33 #include "core/net.h"
34 #include "dhcp/dhcp_debug.h"
35 #include "debug.h"
36 
37 //Check TCP/IP stack configuration
38 #if (IPV4_SUPPORT == ENABLED && DHCP_TRACE_LEVEL >= TRACE_LEVEL_DEBUG)
39 
40 //DHCP message opcodes
41 static const char_t *opcodeLabel[] =
42 {
43  "", //0
44  "BOOTREQUEST", //1
45  "BOOTREPLY" //2
46 };
47 
48 //DHCP message types
49 static const char_t *messageLabel[] =
50 {
51  "", //0
52  "DHCPDISCOVER", //1
53  "DHCPOFFER", //2
54  "DHCPREQUEST", //3
55  "DHCPDECLINE", //4
56  "DHCPACK", //5
57  "DHCPNAK", //6
58  "DHCPRELEASE", //7
59  "DHCPINFORM" //8
60 };
61 
62 //DHCP options
63 static const char_t *optionLabel[] =
64 {
65  "Pad", //0
66  "Subnet Mask", //1
67  "Time Offset", //2
68  "Router", //3
69  "Time Server", //4
70  "Name Server", //5
71  "DNS Server", //6
72  "Log Server", //7
73  "Cookie Server", //8
74  "LPR Server", //9
75  "Impress Server", //10
76  "Resource Location Server", //11
77  "Host Name", //12
78  "Boot File Size", //13
79  "Merit Dump File", //14
80  "Domain Name", //15
81  "Swap Server", //16
82  "Root Path", //17
83  "Extensions Path", //18
84  "IP Forwarding", //19
85  "Non-Local Source Routing", //20
86  "Policy Filter", //21
87  "Max Datagram Reassembly Size", //22
88  "Default IP TTL", //23
89  "Path MTU Aging Timeout", //24
90  "Path MTU Plateau Table", //25
91  "Interface MTU", //26
92  "All Subnets Are Local", //27
93  "Broadcast Address", //28
94  "Perform Mask Discovery", //29
95  "Mask Supplier", //30
96  "Perform Router Discovery", //31
97  "Router Solicitation Address", //32
98  "Static Route", //33
99  "Trailer Encapsulation", //34
100  "ARP Cache Timeout", //35
101  "Ethernet Encapsulation", //36
102  "TCP Default TTL", //37
103  "TCP Keepalive Interval", //38
104  "TCP Keepalive Garbage", //39
105  "NIS Domain", //40
106  "NIS Server", //41
107  "NTP Server", //42
108  "Vendor Specific Information", //43
109  "NetBIOS NBNS Server", //44
110  "NetBIOS NBDD Server", //45
111  "NetBIOS Node Type", //46
112  "NetBIOS Scope", //47
113  "X11 Font Server", //48
114  "X11 Display Manager", //49
115  "Requested IP Address", //50
116  "IP Address Lease Time", //51
117  "Option Overload", //52
118  "DHCP Message Type", //53
119  "Server Identifier", //54
120  "Parameter Request List", //55
121  "Message", //56
122  "Max DHCP Message Size", //57
123  "Renewal (T1) Time Value", //58
124  "Rebinding (T2) Time Value", //59
125  "Vendor Class Identifier", //60
126  "Client Identifier", //61
127  "", //62
128  "", //63
129  "NISP Domain", //64
130  "NISP Server", //65
131  "TFTP Server Name", //66
132  "Bootfile Name", //67
133  "Mobile IP Home Agent", //68
134  "SMTP Server", //69
135  "POP3 Server", //70
136  "NNTP Server", //71
137  "Default WWW Server", //72
138  "Default Finger Server", //73
139  "Default IRC Server", //74
140  "StreetTalk Server", //75
141  "STDA Server", //76
142  "", //77
143  "", //78
144  "", //79
145  "Rapid Commit" //80
146 };
147 
148 
149 /**
150  * @brief Dump DHCP message for debugging purpose
151  * @param[in] message Pointer to the DHCP message to dump
152  * @param[in] length Length of the message
153  * @return Error code
154  **/
155 
157 {
158  error_t error;
159  uint_t i;
160  const char_t *label;
161  DhcpOption *option;
162 
163  //Ensure the length of the DHCP message is acceptable
164  if(length < sizeof(DhcpMessage))
165  {
166  //Report a warning
167  TRACE_WARNING("DHCP message length is invalid!\r\n");
168  //Dump message contents for debugging purpose
170  //Report an error
171  return ERROR_INVALID_LENGTH;
172  }
173 
174  //Retrieve the name associated with the opcode
175  label = (message->op < arraysize(opcodeLabel)) ? opcodeLabel[message->op] : "";
176 
177  //Dump DHCP message contents
178  TRACE_DEBUG(" Op Code (op) = %" PRIu8 " (%s)\r\n", message->op, label);
179  TRACE_DEBUG(" Hardware Type (htype) = %" PRIu8 "\r\n", message->htype);
180  TRACE_DEBUG(" Hardware Address Length (hlen) = %" PRIu8 "\r\n", message->hlen);
181  TRACE_DEBUG(" Hops (hops) = %" PRIu8 "\r\n", message->hops);
182  TRACE_DEBUG(" Transaction ID (xid) = 0x%08" PRIX32 "\r\n", ntohl(message->xid));
183  TRACE_DEBUG(" Seconds (secs) = %" PRIu16 "s\r\n", ntohs(message->secs));
184  TRACE_DEBUG(" Flags (flags) = 0x%04" PRIX16 "\r\n", ntohs(message->flags));
185  TRACE_DEBUG(" Client IP Address (ciaddr) = %s\r\n", ipv4AddrToString(message->ciaddr, NULL));
186  TRACE_DEBUG(" Your IP Address (yiaddr) = %s\r\n", ipv4AddrToString(message->yiaddr, NULL));
187  TRACE_DEBUG(" Server IP Address (siaddr) = %s\r\n", ipv4AddrToString(message->siaddr, NULL));
188  TRACE_DEBUG(" Relay IP Address (giaddr) = %s\r\n", ipv4AddrToString(message->giaddr, NULL));
189  TRACE_DEBUG(" Client Hardware Address (chaddr) = %s\r\n", macAddrToString(&message->chaddr, NULL));
190  TRACE_DEBUG(" Magic Cookie = 0x%08" PRIX32 "\r\n", ntohl(message->magicCookie));
191 
192  //Get the length of the options field
193  length -= sizeof(DhcpMessage);
194 
195  //Parse DHCP options
196  for(i = 0; i < length; i++)
197  {
198  //Point to the current option
199  option = (DhcpOption *) (message->options + i);
200 
201  //Pad option detected?
202  if(option->code == DHCP_OPT_PAD)
203  continue;
204  //End option detected?
205  if(option->code == DHCP_OPT_END)
206  break;
207  //Check option length
208  if((i + 1) >= length || (i + 1 + option->length) >= length)
209  {
210  //Report a warning
211  TRACE_WARNING("DHCP option length is invalid!\r\n");
212  //Dump message contents for debugging purpose
214  //Report an error
215  return ERROR_INVALID_LENGTH;
216  }
217 
218  //Display the name of the current option
219  if(option->code < arraysize(optionLabel))
220  TRACE_DEBUG(" %s option (%" PRIu8 " bytes)\r\n", optionLabel[option->code], option->length);
221  else
222  TRACE_DEBUG(" Option %" PRIu8 " (%" PRIu8 " bytes)\r\n", option->code, option->length);
223 
224  //Check option code
225  switch(option->code)
226  {
227  //Message type?
229  error = dhcpDumpMessageType(option);
230  break;
231  //Parameter Request List option
233  error = dhcpDumpParamRequestList(option);
234  break;
235  //Boolean value?
245  error = dhcpDumpBoolean(option);
246  break;
247  //8-bit unsigned integer?
252  error = dhcpDumpInt8(option);
253  break;
254  //16-bit unsigned integer?
259  error = dhcpDumpInt16(option);
260  break;
261  //32-bit unsigned integer?
268  error = dhcpDumpInt32(option);
269  break;
270  //Character strings?
271  case DHCP_OPT_HOST_NAME:
274  case DHCP_OPT_ROOT_PATH:
276  case DHCP_OPT_NIS_DOMAIN:
277  case DHCP_OPT_MESSAGE:
281  error = dhcpDumpString(option);
282  break;
283  //IPv4 address?
290  error = dhcpDumpIpv4Addr(option);
291  break;
292  //List of IPv4 addresses?
293  case DHCP_OPT_ROUTER:
296  case DHCP_OPT_DNS_SERVER:
297  case DHCP_OPT_LOG_SERVER:
299  case DHCP_OPT_LPR_SERVER:
302  case DHCP_OPT_NIS_SERVER:
303  case DHCP_OPT_NTP_SERVER:
318  error = dhcpDumpIpv4AddrList(option);
319  break;
320  //Raw data?
321  default:
322  error = dhcpDumpRawData(option);
323  break;
324  }
325 
326  //Failed to parse current option?
327  if(error)
328  {
329  //Report a warning
330  TRACE_WARNING("Failed to parse DHCP options!\r\n");
331  //Dump message contents for debugging purpose
333  }
334 
335  //Jump to the next option
336  i += option->length + 1;
337  }
338 
339  //No error to report
340  return NO_ERROR;
341 }
342 
343 
344 /**
345  * @brief Dump Message Type option
346  * @param[in] option Pointer to the option to dump
347  * @return Error code
348  **/
349 
351 {
352  uint8_t type;
353  const char_t *label;
354 
355  //Check option length
356  if(option->length != 1)
357  return ERROR_INVALID_OPTION;
358 
359  //Get the message type
360  type = option->value[0];
361  //Retrieve the name of the current DHCP message
362  label = (type < arraysize(messageLabel)) ? messageLabel[type] : "Unknown";
363  //Display message type
364  TRACE_DEBUG(" %" PRIu8 " (%s)\r\n", type, label);
365 
366  //No error to report
367  return NO_ERROR;
368 }
369 
370 
371 /**
372  * @brief Dump Parameter Request List option
373  * @param[in] option Pointer to the option to dump
374  * @return Error code
375  **/
376 
378 {
379  size_t i;
380  uint8_t code;
381  const char_t *label;
382 
383  //Parse the list of requested options
384  for(i = 0; i < option->length; i++)
385  {
386  //Get current option code
387  code = option->value[i];
388  //Find the name associated with this option code
389  label = (code < arraysize(optionLabel)) ? optionLabel[code] : "Unknown";
390  //Display option code and option name
391  TRACE_DEBUG(" %" PRIu8 " (%s option)\r\n", code, label);
392  }
393 
394  //No error to report
395  return NO_ERROR;
396 }
397 
398 
399 /**
400  * @brief Dump an option containing a boolean
401  * @param[in] option Pointer to the option to dump
402  * @return Error code
403  **/
404 
406 {
407  //Check option length
408  if(option->length != 1)
409  return ERROR_INVALID_OPTION;
410 
411  //Dump option contents
412  TRACE_DEBUG(" %" PRIu8 " (%s)\r\n", option->value[0], option->value[0] ? "True" : "False");
413 
414  //No error to report
415  return NO_ERROR;
416 }
417 
418 
419 /**
420  * @brief Dump an option containing a 8-bit integer
421  * @param[in] option Pointer to the option to dump
422  * @return Error code
423  **/
424 
426 {
427  //Check option length
428  if(option->length != 1)
429  return ERROR_INVALID_OPTION;
430 
431  //Dump option contents
432  TRACE_DEBUG(" %" PRIu8 "\r\n", option->value[0]);
433 
434  //No error to report
435  return NO_ERROR;
436 }
437 
438 
439 /**
440  * @brief Dump an option containing a 16-bit integer
441  * @param[in] option Pointer to the option to dump
442  * @return Error code
443  **/
444 
446 {
447  uint16_t value;
448 
449  //Check option length
450  if(option->length != 2)
451  return ERROR_INVALID_OPTION;
452 
453  //Retrieve 16-bit value
454  value = LOAD16BE(option->value);
455  //Dump option contents
456  TRACE_DEBUG(" %" PRIu16 "\r\n", value);
457 
458  //No error to report
459  return NO_ERROR;
460 }
461 
462 
463 /**
464  * @brief Dump an option containing a 32-bit integer
465  * @param[in] option Pointer to the option to dump
466  * @return Error code
467  **/
468 
470 {
471  uint32_t value;
472 
473  //Check option length
474  if(option->length != 4)
475  return ERROR_INVALID_OPTION;
476 
477  //Retrieve 32-bit value
478  value = LOAD32BE(option->value);
479  //Dump option contents
480  TRACE_DEBUG(" %" PRIu32 "\r\n", value);
481 
482  //No error to report
483  return NO_ERROR;
484 }
485 
486 
487 /**
488  * @brief Dump an option containing a string
489  * @param[in] option Pointer to the option to dump
490  * @return Error code
491  **/
492 
494 {
495  size_t i;
496 
497  //Append prefix
498  TRACE_DEBUG(" ");
499  //Dump option contents
500  for(i = 0; i < option->length; i++)
501  TRACE_DEBUG("%c", option->value[i]);
502  //Add a line feed
503  TRACE_DEBUG("\r\n");
504 
505  //No error to report
506  return NO_ERROR;
507 }
508 
509 
510 /**
511  * @brief Dump an option containing an IPv4 address
512  * @param[in] option Pointer to the option to dump
513  * @return Error code
514  **/
515 
517 {
519 
520  //Check option length
521  if(option->length != sizeof(Ipv4Addr))
522  return ERROR_INVALID_OPTION;
523 
524  //Retrieve IPv4 address
525  ipv4CopyAddr(&ipAddr, option->value);
526  //Dump option contents
527  TRACE_DEBUG(" %s\r\n", ipv4AddrToString(ipAddr, NULL));
528 
529  //No error to report
530  return NO_ERROR;
531 }
532 
533 
534 /**
535  * @brief Dump an option containing a list of IPv4 addresses
536  * @param[in] option Pointer to the option to dump
537  * @return Error code
538  **/
539 
541 {
542  size_t i;
544 
545  //Check option length
546  if((option->length % sizeof(Ipv4Addr)) != 0)
547  return ERROR_INVALID_OPTION;
548 
549  //Parse the list of IPv4 addresses
550  for(i = 0; i < option->length; i += sizeof(Ipv4Addr))
551  {
552  //Retrieve the current IPv4 address
553  ipv4CopyAddr(&ipAddr, option->value + i);
554  //Display current address
555  TRACE_DEBUG(" %s\r\n", ipv4AddrToString(ipAddr, NULL));
556  }
557 
558  //No error to report
559  return NO_ERROR;
560 }
561 
562 
563 /**
564  * @brief Dump an option containing raw data
565  * @param[in] option Pointer to the option to dump
566  * @return Error code
567  **/
568 
570 {
571  //Dump option contents
572  TRACE_DEBUG_ARRAY(" ", option->value, option->length);
573 
574  //No error to report
575  return NO_ERROR;
576 }
577 
578 #endif
uint32_t Ipv4Addr
IPv4 network address.
Definition: ipv4.h:232
error_t dhcpDumpRawData(const DhcpOption *option)
Dump an option containing raw data.
Definition: dhcp_debug.c:569
char char_t
Definition: compiler_port.h:41
char_t * ipv4AddrToString(Ipv4Addr ipAddr, char_t *str)
Convert a binary IPv4 address to dot-decimal notation.
Definition: ipv4.c:1785
TCP/IP stack core.
error_t dhcpDumpIpv4Addr(const DhcpOption *option)
Dump an option containing an IPv4 address.
Definition: dhcp_debug.c:516
Debugging facilities.
uint8_t message[]
Definition: chap.h:150
__start_packed struct @128 DhcpOption
DHCP option.
char_t type
#define LOAD32BE(p)
Definition: cpu_endian.h:192
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:99
error_t dhcpDumpInt16(const DhcpOption *option)
Dump an option containing a 16-bit integer.
Definition: dhcp_debug.c:445
error_t dhcpDumpMessageType(const DhcpOption *option)
Dump Message Type option.
Definition: dhcp_debug.c:350
#define arraysize(a)
Definition: os_port.h:68
uint8_t ipAddr[4]
Definition: mib_common.h:185
#define ntohl(value)
Definition: cpu_endian.h:397
#define ntohs(value)
Definition: cpu_endian.h:396
error_t dhcpDumpMessage(const DhcpMessage *message, size_t length)
Dump DHCP message for debugging purpose.
Definition: dhcp_debug.c:156
#define LOAD16BE(p)
Definition: cpu_endian.h:168
error_t dhcpDumpIpv4AddrList(const DhcpOption *option)
Dump an option containing a list of IPv4 addresses.
Definition: dhcp_debug.c:540
error_t dhcpDumpParamRequestList(const DhcpOption *option)
Dump Parameter Request List option.
Definition: dhcp_debug.c:377
Success.
Definition: error.h:42
error_t dhcpDumpInt8(const DhcpOption *option)
Dump an option containing a 8-bit integer.
Definition: dhcp_debug.c:425
error_t
Error codes.
Definition: error.h:40
#define TRACE_WARNING(...)
Definition: debug.h:78
uint8_t code
Definition: coap_common.h:179
error_t dhcpDumpInt32(const DhcpOption *option)
Dump an option containing a 32-bit integer.
Definition: dhcp_debug.c:469
unsigned int uint_t
Definition: compiler_port.h:43
uint8_t value[]
Definition: dtls_misc.h:141
__start_packed struct @127 DhcpMessage
DHCP message.
error_t dhcpDumpBoolean(const DhcpOption *option)
Dump an option containing a boolean.
Definition: dhcp_debug.c:405
char_t * macAddrToString(const MacAddr *macAddr, char_t *str)
Convert a MAC address to a dash delimited string.
Definition: ethernet.c:1243
error_t dhcpDumpString(const DhcpOption *option)
Dump an option containing a string.
Definition: dhcp_debug.c:493
Data logging functions for debugging purpose (DHCP)
uint8_t length
Definition: dtls_misc.h:140
#define ipv4CopyAddr(destIpAddr, srcIpAddr)
Definition: ipv4.h:133
#define TRACE_DEBUG(...)
Definition: debug.h:98