Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers dhcp_debug.c Source File

dhcp_debug.c

Go to the documentation of this file.
00001 /**
00002  * @file dhcp_debug.c
00003  * @brief Data logging functions for debugging purpose (DHCP)
00004  *
00005  * @section License
00006  *
00007  * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved.
00008  *
00009  * This file is part of CycloneTCP Open.
00010  *
00011  * This program is free software; you can redistribute it and/or
00012  * modify it under the terms of the GNU General Public License
00013  * as published by the Free Software Foundation; either version 2
00014  * of the License, or (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software Foundation,
00023  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00024  *
00025  * @author Oryx Embedded SARL (www.oryx-embedded.com)
00026  * @version 1.7.6
00027  **/
00028 
00029 //Switch to the appropriate trace level
00030 #define TRACE_LEVEL DHCP_TRACE_LEVEL
00031 
00032 //Dependencies
00033 #include "core/net.h"
00034 #include "dhcp/dhcp_debug.h"
00035 #include "debug.h"
00036 
00037 //Check TCP/IP stack configuration
00038 #if (IPV4_SUPPORT == ENABLED && DHCP_TRACE_LEVEL >= TRACE_LEVEL_DEBUG)
00039 
00040 //DHCP message opcodes
00041 static const char_t *opcodeLabel[] =
00042 {
00043    "",            //0
00044    "BOOTREQUEST", //1
00045    "BOOTREPLY"    //2
00046 };
00047 
00048 //DHCP message types
00049 static const char_t *messageLabel[] =
00050 {
00051    "",             //0
00052    "DHCPDISCOVER", //1
00053    "DHCPOFFER",    //2
00054    "DHCPREQUEST",  //3
00055    "DHCPDECLINE",  //4
00056    "DHCPACK",      //5
00057    "DHCPNAK",      //6
00058    "DHCPRELEASE",  //7
00059    "DHCPINFORM"    //8
00060 };
00061 
00062 //DHCP options
00063 static const char_t *optionLabel[] =
00064 {
00065    "Pad",                          //0
00066    "Subnet Mask",                  //1
00067    "Time Offset",                  //2
00068    "Router",                       //3
00069    "Time Server",                  //4
00070    "Name Server",                  //5
00071    "DNS Server",                   //6
00072    "Log Server",                   //7
00073    "Cookie Server",                //8
00074    "LPR Server",                   //9
00075    "Impress Server",               //10
00076    "Resource Location Server",     //11
00077    "Host Name",                    //12
00078    "Boot File Size",               //13
00079    "Merit Dump File",              //14
00080    "Domain Name",                  //15
00081    "Swap Server",                  //16
00082    "Root Path",                    //17
00083    "Extensions Path",              //18
00084    "IP Forwarding",                //19
00085    "Non-Local Source Routing",     //20
00086    "Policy Filter",                //21
00087    "Max Datagram Reassembly Size", //22
00088    "Default IP TTL",               //23
00089    "Path MTU Aging Timeout",       //24
00090    "Path MTU Plateau Table",       //25
00091    "Interface MTU",                //26
00092    "All Subnets Are Local",        //27
00093    "Broadcast Address",            //28
00094    "Perform Mask Discovery",       //29
00095    "Mask Supplier",                //30
00096    "Perform Router Discovery",     //31
00097    "Router Solicitation Address",  //32
00098    "Static Route",                 //33
00099    "Trailer Encapsulation",        //34
00100    "ARP Cache Timeout",            //35
00101    "Ethernet Encapsulation",       //36
00102    "TCP Default TTL",              //37
00103    "TCP Keepalive Interval",       //38
00104    "TCP Keepalive Garbage",        //39
00105    "NIS Domain",                   //40
00106    "NIS Server",                   //41
00107    "NTP Server",                   //42
00108    "Vendor Specific Information",  //43
00109    "NetBIOS NBNS Server",          //44
00110    "NetBIOS NBDD Server",          //45
00111    "NetBIOS Node Type",            //46
00112    "NetBIOS Scope",                //47
00113    "X11 Font Server",              //48
00114    "X11 Display Manager",          //49
00115    "Requested IP Address",         //50
00116    "IP Address Lease Time",        //51
00117    "Option Overload",              //52
00118    "DHCP Message Type",            //53
00119    "Server Identifier",            //54
00120    "Parameter Request List",       //55
00121    "Message",                      //56
00122    "Max DHCP Message Size",        //57
00123    "Renewal (T1) Time Value",      //58
00124    "Rebinding (T2) Time Value",    //59
00125    "Vendor Class Identifier",      //60
00126    "Client Identifier",            //61
00127    "",                             //62
00128    "",                             //63
00129    "NISP Domain",                  //64
00130    "NISP Server",                  //65
00131    "TFTP Server Name",             //66
00132    "Bootfile Name",                //67
00133    "Mobile IP Home Agent",         //68
00134    "SMTP Server",                  //69
00135    "POP3 Server",                  //70
00136    "NNTP Server",                  //71
00137    "Default WWW Server",           //72
00138    "Default Finger Server",        //73
00139    "Default IRC Server",           //74
00140    "StreetTalk Server",            //75
00141    "STDA Server",                  //76
00142    "",                             //77
00143    "",                             //78
00144    "",                             //79
00145    "Rapid Commit"                  //80
00146 };
00147 
00148 
00149 /**
00150  * @brief Dump DHCP message for debugging purpose
00151  * @param[in] message Pointer to the DHCP message to dump
00152  * @param[in] length Length of the message
00153  * @return Error code
00154  **/
00155 
00156 error_t dhcpDumpMessage(const DhcpMessage *message, size_t length)
00157 {
00158    error_t error;
00159    uint_t i;
00160    const char_t *label;
00161    DhcpOption *option;
00162 
00163    //Ensure the length of the DHCP message is acceptable
00164    if(length < sizeof(DhcpMessage))
00165    {
00166       //Report a warning
00167       TRACE_WARNING("DHCP message length is invalid!\r\n");
00168       //Dump message contents for debugging purpose
00169       TRACE_DEBUG_ARRAY("  ", message, length);
00170       //Report an error
00171       return ERROR_INVALID_LENGTH;
00172    }
00173 
00174    //Retrieve the name associated with the opcode
00175    label = (message->op < arraysize(opcodeLabel)) ? opcodeLabel[message->op] : "";
00176 
00177    //Dump DHCP message contents
00178    TRACE_DEBUG("  Op Code (op) = %" PRIu8 " (%s)\r\n", message->op, label);
00179    TRACE_DEBUG("  Hardware Type (htype) = %" PRIu8 "\r\n", message->htype);
00180    TRACE_DEBUG("  Hardware Address Length (hlen) = %" PRIu8 "\r\n", message->hlen);
00181    TRACE_DEBUG("  Hops (hops) = %" PRIu8 "\r\n", message->hops);
00182    TRACE_DEBUG("  Transaction ID (xid) = 0x%08" PRIX32 "\r\n", ntohl(message->xid));
00183    TRACE_DEBUG("  Seconds (secs) = %" PRIu16 "s\r\n", ntohs(message->secs));
00184    TRACE_DEBUG("  Flags (flags) = 0x%04" PRIX16 "\r\n", ntohs(message->flags));
00185    TRACE_DEBUG("  Client IP Address (ciaddr) = %s\r\n", ipv4AddrToString(message->ciaddr, NULL));
00186    TRACE_DEBUG("  Your IP Address (yiaddr) = %s\r\n", ipv4AddrToString(message->yiaddr, NULL));
00187    TRACE_DEBUG("  Server IP Address (siaddr) = %s\r\n", ipv4AddrToString(message->siaddr, NULL));
00188    TRACE_DEBUG("  Relay IP Address (giaddr) = %s\r\n", ipv4AddrToString(message->giaddr, NULL));
00189    TRACE_DEBUG("  Client Hardware Address (chaddr) = %s\r\n", macAddrToString(&message->chaddr, NULL));
00190    TRACE_DEBUG("  Magic Cookie = 0x%08" PRIX32 "\r\n", ntohl(message->magicCookie));
00191 
00192    //Get the length of the options field
00193    length -= sizeof(DhcpMessage);
00194 
00195    //Parse DHCP options
00196    for(i = 0; i < length; i++)
00197    {
00198       //Point to the current option
00199       option = (DhcpOption *) (message->options + i);
00200 
00201       //Pad option detected?
00202       if(option->code == DHCP_OPT_PAD)
00203          continue;
00204       //End option detected?
00205       if(option->code == DHCP_OPT_END)
00206          break;
00207       //Check option length
00208       if((i + 1) >= length || (i + 1 + option->length) >= length)
00209       {
00210          //Report a warning
00211          TRACE_WARNING("DHCP option length is invalid!\r\n");
00212          //Dump message contents for debugging purpose
00213          TRACE_DEBUG_ARRAY("  ", message, length);
00214          //Report an error
00215          return ERROR_INVALID_LENGTH;
00216       }
00217 
00218       //Display the name of the current option
00219       if(option->code < arraysize(optionLabel))
00220          TRACE_DEBUG("  %s option (%" PRIu8 " bytes)\r\n", optionLabel[option->code], option->length);
00221       else
00222          TRACE_DEBUG("  Option %" PRIu8 " (%" PRIu8 " bytes)\r\n", option->code, option->length);
00223 
00224       //Check option code
00225       switch(option->code)
00226       {
00227       //Message type?
00228       case DHCP_OPT_DHCP_MESSAGE_TYPE:
00229          error = dhcpDumpMessageType(option);
00230          break;
00231       //Parameter Request List option
00232       case DHCP_OPT_PARAM_REQUEST_LIST:
00233          error = dhcpDumpParamRequestList(option);
00234          break;
00235       //Boolean value?
00236       case DHCP_OPT_IP_FORWARDING:
00237       case DHCP_OPT_NON_LOCAL_SOURCE_ROUTING:
00238       case DHCP_OPT_ALL_SUBNETS_ARE_LOCAL:
00239       case DHCP_OPT_PERFORM_MASK_DISCOVERY:
00240       case DHCP_OPT_MASK_SUPPLIER:
00241       case DHCP_OPT_PERFORM_ROUTER_DISCOVERY:
00242       case DHCP_OPT_TRAILER_ENCAPSULATION:
00243       case DHCP_OPT_ETHERNET_ENCAPSULATION:
00244       case DHCP_OPT_TCP_KEEPALIVE_GARBAGE:
00245          error = dhcpDumpBoolean(option);
00246          break;
00247       //8-bit unsigned integer?
00248       case DHCP_OPT_DEFAULT_IP_TTL:
00249       case DHCP_OPT_TCP_DEFAULT_TTL:
00250       case DHCP_OPT_NETBIOS_NODE_TYPE:
00251       case DHCP_OPT_OPTION_OVERLOAD:
00252          error = dhcpDumpInt8(option);
00253          break;
00254       //16-bit unsigned integer?
00255       case DHCP_OPT_BOOT_FILE_SIZE:
00256       case DHCP_OPT_MAX_DATAGRAM_REASSEMBLY_SIZE:
00257       case DHCP_OPT_INTERFACE_MTU:
00258       case DHCP_OPT_MAX_DHCP_MESSAGE_SIZE:
00259          error = dhcpDumpInt16(option);
00260          break;
00261       //32-bit unsigned integer?
00262       case DHCP_OPT_PATH_MTU_AGING_TIMEOUT:
00263       case DHCP_OPT_ARP_CACHE_TIMEOUT:
00264       case DHCP_OPT_TCP_KEEPALIVE_INTERVAL:
00265       case DHCP_OPT_IP_ADDRESS_LEASE_TIME:
00266       case DHCP_OPT_RENEWAL_TIME_VALUE:
00267       case DHCP_OPT_REBINDING_TIME_VALUE:
00268          error = dhcpDumpInt32(option);
00269          break;
00270       //Character strings?
00271       case DHCP_OPT_HOST_NAME:
00272       case DHCP_OPT_MERIT_DUMP_FILE:
00273       case DHCP_OPT_DOMAIN_NAME:
00274       case DHCP_OPT_ROOT_PATH:
00275       case DHCP_OPT_EXTENSIONS_PATH:
00276       case DHCP_OPT_NIS_DOMAIN:
00277       case DHCP_OPT_MESSAGE:
00278       case DHCP_OPT_NISP_DOMAIN:
00279       case DHCP_OPT_TFTP_SERVER_NAME:
00280       case DHCP_OPT_BOOTFILE_NAME:
00281          error = dhcpDumpString(option);
00282          break;
00283       //IPv4 address?
00284       case DHCP_OPT_SUBNET_MASK:
00285       case DHCP_OPT_SWAP_SERVER:
00286       case DHCP_OPT_BROADCAST_ADDRESS:
00287       case DHCP_OPT_ROUTER_SOLICITATION_ADDRESS:
00288       case DHCP_OPT_REQUESTED_IP_ADDRESS:
00289       case DHCP_OPT_SERVER_IDENTIFIER:
00290          error = dhcpDumpIpv4Addr(option);
00291          break;
00292       //List of IPv4 addresses?
00293       case DHCP_OPT_ROUTER:
00294       case DHCP_OPT_TIME_SERVER:
00295       case DHCP_OPT_NAME_SERVER:
00296       case DHCP_OPT_DNS_SERVER:
00297       case DHCP_OPT_LOG_SERVER:
00298       case DHCP_OPT_COOKIE_SERVER:
00299       case DHCP_OPT_LPR_SERVER:
00300       case DHCP_OPT_IMPRESS_SERVER:
00301       case DHCP_OPT_RESOURCE_LOCATION_SERVER:
00302       case DHCP_OPT_NIS_SERVER:
00303       case DHCP_OPT_NTP_SERVER:
00304       case DHCP_OPT_NETBIOS_NBNS_SERVER:
00305       case DHCP_OPT_NETBIOS_NBDD_SERVER:
00306       case DHCP_OPT_X11_FONT_SERVER:
00307       case DHCP_OPT_X11_DISPLAY_MANAGER:
00308       case DHCP_OPT_NISP_SERVER:
00309       case DHCP_OPT_MOBILE_IP_HOME_AGENT:
00310       case DHCP_OPT_SMTP_SERVER:
00311       case DHCP_OPT_POP3_SERVER:
00312       case DHCP_OPT_NNTP_SERVER:
00313       case DHCP_OPT_DEFAULT_WWW_SERVER:
00314       case DHCP_OPT_DEFAULT_FINGER_SERVER:
00315       case DHCP_OPT_DEFAULT_IRC_SERVER:
00316       case DHCP_OPT_STREETTALK_SERVER:
00317       case DHCP_OPT_STDA_SERVER:
00318          error = dhcpDumpIpv4AddrList(option);
00319          break;
00320       //Raw data?
00321       default:
00322          error = dhcpDumpRawData(option);
00323          break;
00324       }
00325 
00326       //Failed to parse current option?
00327       if(error)
00328       {
00329          //Report a warning
00330          TRACE_WARNING("Failed to parse DHCP options!\r\n");
00331          //Dump message contents for debugging purpose
00332          TRACE_DEBUG_ARRAY("  ", message, length);
00333       }
00334 
00335       //Jump to the next option
00336       i += option->length + 1;
00337    }
00338 
00339    //No error to report
00340    return NO_ERROR;
00341 }
00342 
00343 
00344 /**
00345  * @brief Dump Message Type option
00346  * @param[in] option Pointer to the option to dump
00347  * @return Error code
00348  **/
00349 
00350 error_t dhcpDumpMessageType(const DhcpOption *option)
00351 {
00352    uint8_t type;
00353    const char_t *label;
00354 
00355    //Check option length
00356    if(option->length != 1)
00357       return ERROR_INVALID_OPTION;
00358 
00359    //Get the message type
00360    type = option->value[0];
00361    //Retrieve the name of the current DHCP message
00362    label = (type < arraysize(messageLabel)) ? messageLabel[type] : "Unknown";
00363    //Display message type
00364    TRACE_DEBUG("    %" PRIu8 " (%s)\r\n", type, label);
00365 
00366    //No error to report
00367    return NO_ERROR;
00368 }
00369 
00370 
00371 /**
00372  * @brief Dump Parameter Request List option
00373  * @param[in] option Pointer to the option to dump
00374  * @return Error code
00375  **/
00376 
00377 error_t dhcpDumpParamRequestList(const DhcpOption *option)
00378 {
00379    size_t i;
00380    uint8_t code;
00381    const char_t *label;
00382 
00383    //Parse the list of requested options
00384    for(i = 0; i < option->length; i++)
00385    {
00386       //Get current option code
00387       code = option->value[i];
00388       //Find the name associated with this option code
00389       label = (code < arraysize(optionLabel)) ? optionLabel[code] : "Unknown";
00390       //Display option code and option name
00391       TRACE_DEBUG("    %" PRIu8 " (%s option)\r\n", code, label);
00392    }
00393 
00394    //No error to report
00395    return NO_ERROR;
00396 }
00397 
00398 
00399 /**
00400  * @brief Dump an option containing a boolean
00401  * @param[in] option Pointer to the option to dump
00402  * @return Error code
00403  **/
00404 
00405 error_t dhcpDumpBoolean(const DhcpOption *option)
00406 {
00407    //Check option length
00408    if(option->length != 1)
00409       return ERROR_INVALID_OPTION;
00410 
00411    //Dump option contents
00412    TRACE_DEBUG("    %" PRIu8 " (%s)\r\n", option->value[0], option->value[0] ? "True" : "False");
00413 
00414    //No error to report
00415    return NO_ERROR;
00416 }
00417 
00418 
00419 /**
00420  * @brief Dump an option containing a 8-bit integer
00421  * @param[in] option Pointer to the option to dump
00422  * @return Error code
00423  **/
00424 
00425 error_t dhcpDumpInt8(const DhcpOption *option)
00426 {
00427    //Check option length
00428    if(option->length != 1)
00429       return ERROR_INVALID_OPTION;
00430 
00431    //Dump option contents
00432    TRACE_DEBUG("    %" PRIu8 "\r\n", option->value[0]);
00433 
00434    //No error to report
00435    return NO_ERROR;
00436 }
00437 
00438 
00439 /**
00440  * @brief Dump an option containing a 16-bit integer
00441  * @param[in] option Pointer to the option to dump
00442  * @return Error code
00443  **/
00444 
00445 error_t dhcpDumpInt16(const DhcpOption *option)
00446 {
00447    uint16_t value;
00448 
00449    //Check option length
00450    if(option->length != 2)
00451       return ERROR_INVALID_OPTION;
00452 
00453    //Retrieve 16-bit value
00454    value = LOAD16BE(option->value);
00455    //Dump option contents
00456    TRACE_DEBUG("    %" PRIu16 "\r\n", value);
00457 
00458    //No error to report
00459    return NO_ERROR;
00460 }
00461 
00462 
00463 /**
00464  * @brief Dump an option containing a 32-bit integer
00465  * @param[in] option Pointer to the option to dump
00466  * @return Error code
00467  **/
00468 
00469 error_t dhcpDumpInt32(const DhcpOption *option)
00470 {
00471    uint32_t value;
00472 
00473    //Check option length
00474    if(option->length != 4)
00475       return ERROR_INVALID_OPTION;
00476 
00477    //Retrieve 32-bit value
00478    value = LOAD32BE(option->value);
00479    //Dump option contents
00480    TRACE_DEBUG("    %" PRIu32 "\r\n", value);
00481 
00482    //No error to report
00483    return NO_ERROR;
00484 }
00485 
00486 
00487 /**
00488  * @brief Dump an option containing a string
00489  * @param[in] option Pointer to the option to dump
00490  * @return Error code
00491  **/
00492 
00493 error_t dhcpDumpString(const DhcpOption *option)
00494 {
00495    size_t i;
00496 
00497    //Append prefix
00498    TRACE_DEBUG("    ");
00499    //Dump option contents
00500    for(i = 0; i < option->length; i++)
00501       TRACE_DEBUG("%c", option->value[i]);
00502    //Add a line feed
00503    TRACE_DEBUG("\r\n");
00504 
00505    //No error to report
00506    return NO_ERROR;
00507 }
00508 
00509 
00510 /**
00511  * @brief Dump an option containing an IPv4 address
00512  * @param[in] option Pointer to the option to dump
00513  * @return Error code
00514  **/
00515 
00516 error_t dhcpDumpIpv4Addr(const DhcpOption *option)
00517 {
00518    Ipv4Addr ipAddr;
00519 
00520    //Check option length
00521    if(option->length != sizeof(Ipv4Addr))
00522       return ERROR_INVALID_OPTION;
00523 
00524    //Retrieve IPv4 address
00525    ipv4CopyAddr(&ipAddr, option->value);
00526    //Dump option contents
00527    TRACE_DEBUG("    %s\r\n", ipv4AddrToString(ipAddr, NULL));
00528 
00529    //No error to report
00530    return NO_ERROR;
00531 }
00532 
00533 
00534 /**
00535  * @brief Dump an option containing a list of IPv4 addresses
00536  * @param[in] option Pointer to the option to dump
00537  * @return Error code
00538  **/
00539 
00540 error_t dhcpDumpIpv4AddrList(const DhcpOption *option)
00541 {
00542    size_t i;
00543    Ipv4Addr ipAddr;
00544 
00545    //Check option length
00546    if((option->length % sizeof(Ipv4Addr)) != 0)
00547       return ERROR_INVALID_OPTION;
00548 
00549    //Parse the list of IPv4 addresses
00550    for(i = 0; i < option->length; i += sizeof(Ipv4Addr))
00551    {
00552       //Retrieve the current IPv4 address
00553       ipv4CopyAddr(&ipAddr, option->value + i);
00554       //Display current address
00555       TRACE_DEBUG("    %s\r\n", ipv4AddrToString(ipAddr, NULL));
00556    }
00557 
00558    //No error to report
00559    return NO_ERROR;
00560 }
00561 
00562 
00563 /**
00564  * @brief Dump an option containing raw data
00565  * @param[in] option Pointer to the option to dump
00566  * @return Error code
00567  **/
00568 
00569 error_t dhcpDumpRawData(const DhcpOption *option)
00570 {
00571    //Dump option contents
00572    TRACE_DEBUG_ARRAY("    ", option->value, option->length);
00573 
00574    //No error to report
00575    return NO_ERROR;
00576 }
00577 
00578 #endif
00579