Sergey Pastor / 1

Dependents:   Nucleo

Committer:
Sergunb
Date:
Sat Feb 04 18:15:49 2017 +0000
Revision:
0:8918a71cdbe9
nothing else

Who changed what in which revision?

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