Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
icmpv6.c
00001 /** 00002 * @file icmpv6.c 00003 * @brief ICMPv6 (Internet Control Message Protocol Version 6) 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 * @section Description 00026 * 00027 * ICMPv6 is used by IPv6 nodes to report errors encountered in 00028 * processing packets, and to perform other Internet-layer functions. 00029 * ICMPv6 is an integral part of IPv6 and must be fully implemented 00030 * by every IPv6 node. Refer to the RFC 2463 for more details 00031 * 00032 * @author Oryx Embedded SARL (www.oryx-embedded.com) 00033 * @version 1.7.6 00034 **/ 00035 00036 //Switch to the appropriate trace level 00037 #define TRACE_LEVEL ICMPV6_TRACE_LEVEL 00038 00039 //Dependencies 00040 #include <string.h> 00041 #include "core/net.h" 00042 #include "core/ip.h" 00043 #include "ipv6/ipv6.h" 00044 #include "ipv6/ipv6_misc.h" 00045 #include "ipv6/ipv6_pmtu.h" 00046 #include "ipv6/icmpv6.h" 00047 #include "ipv6/mld.h" 00048 #include "ipv6/ndp.h" 00049 #include "ipv6/ndp_router_adv.h" 00050 #include "debug.h" 00051 00052 //Check TCP/IP stack configuration 00053 #if (IPV6_SUPPORT == ENABLED) 00054 00055 00056 /** 00057 * @brief Enable support for multicast Echo Request messages 00058 * @param[in] interface Underlying network interface 00059 * @param[in] enable When the flag is set to TRUE, the host will respond to 00060 * multicast Echo Requests. When the flag is set to FALSE, incoming Echo 00061 * Request messages destined to a multicast address will be dropped 00062 * @return Error code 00063 **/ 00064 00065 error_t icmpv6EnableMulticastEchoRequest(NetInterface *interface, bool_t enable) 00066 { 00067 //Check parameters 00068 if(interface == NULL) 00069 return ERROR_INVALID_PARAMETER; 00070 00071 //Get exclusive access 00072 osAcquireMutex(&netMutex); 00073 //Enable or disable support for multicast Echo Request messages 00074 interface->ipv6Context.enableMulticastEchoReq = enable; 00075 //Release exclusive access 00076 osReleaseMutex(&netMutex); 00077 00078 //Successful processing 00079 return NO_ERROR; 00080 } 00081 00082 00083 /** 00084 * @brief Incoming ICMPv6 message processing 00085 * @param[in] interface Underlying network interface 00086 * @param[in] pseudoHeader IPv6 pseudo header 00087 * @param[in] buffer Multi-part buffer containing the incoming ICMPv6 message 00088 * @param[in] offset Offset to the first byte of the ICMPv6 message 00089 * @param[in] hopLimit Hop Limit field from IPv6 header 00090 **/ 00091 00092 void icmpv6ProcessMessage(NetInterface *interface, Ipv6PseudoHeader *pseudoHeader, 00093 const NetBuffer *buffer, size_t offset, uint8_t hopLimit) 00094 { 00095 size_t length; 00096 Icmpv6Header *header; 00097 00098 //Retrieve the length of the ICMPv6 message 00099 length = netBufferGetLength(buffer) - offset; 00100 00101 //Ensure the message length is correct 00102 if(length < sizeof(Icmpv6Header)) 00103 { 00104 //Debug message 00105 TRACE_WARNING("ICMPv6 message length is invalid!\r\n"); 00106 //Exit immediately 00107 return; 00108 } 00109 00110 //Point to the ICMPv6 message header 00111 header = netBufferAt(buffer, offset); 00112 00113 //Sanity check 00114 if(header == NULL) 00115 return; 00116 00117 //Debug message 00118 TRACE_INFO("ICMPv6 message received (%" PRIuSIZE " bytes)...\r\n", length); 00119 //Dump message contents for debugging purpose 00120 icmpv6DumpMessage(header); 00121 00122 //Verify checksum value 00123 if(ipCalcUpperLayerChecksumEx(pseudoHeader, 00124 sizeof(Ipv6PseudoHeader), buffer, offset, length) != 0x0000) 00125 { 00126 //Debug message 00127 TRACE_WARNING("Wrong ICMPv6 header checksum!\r\n"); 00128 //Exit immediately 00129 return; 00130 } 00131 00132 //Check whether the destination address is the tentative address 00133 if(ipv6IsTentativeAddr(interface, &pseudoHeader->destAddr)) 00134 { 00135 //The interface must accept Neighbor Solicitation and 00136 //Neighbor Advertisement messages 00137 if(header->type != ICMPV6_TYPE_NEIGHBOR_SOL && 00138 header->type != ICMPV6_TYPE_NEIGHBOR_ADV) 00139 { 00140 //Other packets addressed to the tentative address 00141 //should be silently discarded 00142 return; 00143 } 00144 } 00145 00146 //Check the type of message 00147 switch(header->type) 00148 { 00149 //Destination Unreachable message? 00150 case ICMPV6_TYPE_DEST_UNREACHABLE: 00151 //Process Destination Unreachable message 00152 icmpv6ProcessDestUnreachable(interface, pseudoHeader, buffer, offset); 00153 break; 00154 //Packet Too Big message? 00155 case ICMPV6_TYPE_PACKET_TOO_BIG: 00156 //Process Packet Too Big message 00157 icmpv6ProcessPacketTooBig(interface, pseudoHeader, buffer, offset); 00158 break; 00159 //Echo Request message? 00160 case ICMPV6_TYPE_ECHO_REQUEST: 00161 //Process Echo Request message 00162 icmpv6ProcessEchoRequest(interface, pseudoHeader, buffer, offset); 00163 break; 00164 #if (MLD_SUPPORT == ENABLED) 00165 //Multicast Listener Query message? 00166 case ICMPV6_TYPE_MULTICAST_LISTENER_QUERY: 00167 //Process Multicast Listener Query message 00168 mldProcessListenerQuery(interface, pseudoHeader, buffer, offset, hopLimit); 00169 break; 00170 //Version 1 Multicast Listener Report message? 00171 case ICMPV6_TYPE_MULTICAST_LISTENER_REPORT_V1: 00172 //Process Version 1 Multicast Listener Report message 00173 mldProcessListenerReport(interface, pseudoHeader, buffer, offset, hopLimit); 00174 break; 00175 #endif 00176 #if (NDP_ROUTER_ADV_SUPPORT == ENABLED) 00177 //Router Solicitation message? 00178 case ICMPV6_TYPE_ROUTER_SOL: 00179 //Process Router Solicitation message 00180 ndpProcessRouterSol(interface, pseudoHeader, buffer, offset, hopLimit); 00181 break; 00182 #endif 00183 #if (NDP_SUPPORT == ENABLED) 00184 //Router Advertisement message? 00185 case ICMPV6_TYPE_ROUTER_ADV: 00186 //Process Router Advertisement message 00187 ndpProcessRouterAdv(interface, pseudoHeader, buffer, offset, hopLimit); 00188 break; 00189 //Neighbor Solicitation message? 00190 case ICMPV6_TYPE_NEIGHBOR_SOL: 00191 //Process Neighbor Solicitation message 00192 ndpProcessNeighborSol(interface, pseudoHeader, buffer, offset, hopLimit); 00193 break; 00194 //Neighbor Advertisement message? 00195 case ICMPV6_TYPE_NEIGHBOR_ADV: 00196 //Process Neighbor Advertisement message 00197 ndpProcessNeighborAdv(interface, pseudoHeader, buffer, offset, hopLimit); 00198 break; 00199 //Redirect message? 00200 case ICMPV6_TYPE_REDIRECT: 00201 //Process Redirect message 00202 ndpProcessRedirect(interface, pseudoHeader, buffer, offset, hopLimit); 00203 break; 00204 #endif 00205 //Unknown type? 00206 default: 00207 //Debug message 00208 TRACE_WARNING("Unknown ICMPv6 message type!\r\n"); 00209 //Discard incoming ICMPv6 message 00210 break; 00211 } 00212 } 00213 00214 00215 /** 00216 * @brief Destination Unreachable message processing 00217 * @param[in] interface Underlying network interface 00218 * @param[in] pseudoHeader IPv6 pseudo header 00219 * @param[in] buffer Multi-part buffer containing the incoming ICMPv6 message 00220 * @param[in] offset Offset to the first byte of the ICMPv6 message 00221 **/ 00222 00223 void icmpv6ProcessDestUnreachable(NetInterface *interface, 00224 Ipv6PseudoHeader *pseudoHeader, const NetBuffer *buffer, size_t offset) 00225 { 00226 size_t length; 00227 Icmpv6DestUnreachableMessage *icmpHeader; 00228 00229 //Retrieve the length of the Destination Unreachable message 00230 length = netBufferGetLength(buffer) - offset; 00231 00232 //Ensure the packet length is correct 00233 if(length < sizeof(Icmpv6DestUnreachableMessage)) 00234 return; 00235 00236 //Point to the ICMPv6 header 00237 icmpHeader = netBufferAt(buffer, offset); 00238 00239 //Sanity check 00240 if(icmpHeader == NULL) 00241 return; 00242 00243 //Debug message 00244 TRACE_INFO("ICMPv6 Destination Unreachable message received (%" PRIuSIZE " bytes)...\r\n", length); 00245 //Dump message contents for debugging purpose 00246 icmpv6DumpDestUnreachableMessage(icmpHeader); 00247 } 00248 00249 00250 /** 00251 * @brief Packet Too Big message processing 00252 * @param[in] interface Underlying network interface 00253 * @param[in] pseudoHeader IPv6 pseudo header 00254 * @param[in] buffer Multi-part buffer containing the incoming ICMPv6 message 00255 * @param[in] offset Offset to the first byte of the ICMPv6 message 00256 **/ 00257 00258 void icmpv6ProcessPacketTooBig(NetInterface *interface, 00259 Ipv6PseudoHeader *pseudoHeader, const NetBuffer *buffer, size_t offset) 00260 { 00261 size_t length; 00262 Icmpv6PacketTooBigMessage *icmpHeader; 00263 00264 #if (IPV6_PMTU_SUPPORT == ENABLED) 00265 uint32_t tentativePathMtu; 00266 Ipv6Header* ipHeader; 00267 #endif 00268 00269 //Retrieve the length of the Packet Too Big message 00270 length = netBufferGetLength(buffer) - offset; 00271 00272 //Ensure the packet length is correct 00273 if(length < sizeof(Icmpv6PacketTooBigMessage)) 00274 return; 00275 00276 //Point to the ICMPv6 header 00277 icmpHeader = netBufferAt(buffer, offset); 00278 00279 //Sanity check 00280 if(icmpHeader == NULL) 00281 return; 00282 00283 //Debug message 00284 TRACE_INFO("ICMPv6 Packet Too Big message received (%" PRIuSIZE " bytes)...\r\n", length); 00285 //Dump message contents for debugging purpose 00286 icmpv6DumpPacketTooBigMessage(icmpHeader); 00287 00288 #if (IPV6_PMTU_SUPPORT == ENABLED) 00289 //Move to the beginning of the original IPv6 packet 00290 offset += sizeof(Icmpv6PacketTooBigMessage); 00291 length -= sizeof(Icmpv6PacketTooBigMessage); 00292 00293 //Ensure the packet length is correct 00294 if(length < sizeof(Ipv6Header)) 00295 return; 00296 00297 //Point to the original IPv6 header 00298 ipHeader = netBufferAt(buffer, offset); 00299 00300 //Sanity check 00301 if(ipHeader == NULL) 00302 return; 00303 00304 //The node uses the value in the MTU field in the Packet Too Big 00305 //message as a tentative PMTU value 00306 tentativePathMtu = ntohl(icmpHeader->mtu); 00307 00308 //Update the PMTU for the specified destination address 00309 ipv6UpdatePathMtu(interface, &ipHeader->destAddr, tentativePathMtu); 00310 #endif 00311 } 00312 00313 00314 /** 00315 * @brief Echo Request message processing 00316 * @param[in] interface Underlying network interface 00317 * @param[in] requestPseudoHeader IPv6 pseudo header 00318 * @param[in] request Multi-part buffer containing the incoming ICMPv6 message 00319 * @param[in] requestOffset Offset to the first byte of the ICMPv6 message 00320 **/ 00321 00322 void icmpv6ProcessEchoRequest(NetInterface *interface, Ipv6PseudoHeader *requestPseudoHeader, 00323 const NetBuffer *request, size_t requestOffset) 00324 { 00325 error_t error; 00326 size_t requestLength; 00327 size_t replyOffset; 00328 size_t replyLength; 00329 NetBuffer *reply; 00330 Icmpv6EchoMessage *requestHeader; 00331 Icmpv6EchoMessage *replyHeader; 00332 Ipv6PseudoHeader replyPseudoHeader; 00333 00334 //Retrieve the length of the Echo Request message 00335 requestLength = netBufferGetLength(request) - requestOffset; 00336 00337 //Ensure the packet length is correct 00338 if(requestLength < sizeof(Icmpv6EchoMessage)) 00339 return; 00340 00341 //Point to the Echo Request header 00342 requestHeader = netBufferAt(request, requestOffset); 00343 00344 //Sanity check 00345 if(requestHeader == NULL) 00346 return; 00347 00348 //Debug message 00349 TRACE_INFO("ICMPv6 Echo Request message received (%" PRIuSIZE " bytes)...\r\n", requestLength); 00350 //Dump message contents for debugging purpose 00351 icmpv6DumpEchoMessage(requestHeader); 00352 00353 //Check whether the destination address of the Echo Request 00354 //message is a multicast address 00355 if(ipv6IsMulticastAddr(&requestPseudoHeader->destAddr)) 00356 { 00357 //If support for multicast Echo Request messages has been explicitly 00358 //disabled, then the host shall not respond to the incoming request 00359 if(!interface->ipv6Context.enableMulticastEchoReq) 00360 return; 00361 00362 //The source address of the reply must be a unicast address belonging to 00363 //the interface on which the multicast Echo Request message was received 00364 error = ipv6SelectSourceAddr(&interface, 00365 &requestPseudoHeader->srcAddr, &replyPseudoHeader.srcAddr); 00366 00367 //Any error to report? 00368 if(error) 00369 return; 00370 } 00371 else 00372 { 00373 //The destination address of the Echo Request message is a unicast address 00374 replyPseudoHeader.srcAddr = requestPseudoHeader->destAddr; 00375 } 00376 00377 //Allocate memory to hold the Echo Reply message 00378 reply = ipAllocBuffer(sizeof(Icmpv6EchoMessage), &replyOffset); 00379 00380 //Failed to allocate memory? 00381 if(reply == NULL) 00382 return; 00383 00384 //Point to the Echo Reply header 00385 replyHeader = netBufferAt(reply, replyOffset); 00386 00387 //Format Echo Reply header 00388 replyHeader->type = ICMPV6_TYPE_ECHO_REPLY; 00389 replyHeader->code = 0; 00390 replyHeader->checksum = 0; 00391 replyHeader->identifier = requestHeader->identifier; 00392 replyHeader->sequenceNumber = requestHeader->sequenceNumber; 00393 00394 //Point to the first data byte 00395 requestOffset += sizeof(Icmpv6EchoMessage); 00396 requestLength -= sizeof(Icmpv6EchoMessage); 00397 00398 //The data received in the ICMPv6 Echo Request message must be returned 00399 //entirely and unmodified in the ICMPv6 Echo Reply message 00400 error = netBufferConcat(reply, request, requestOffset, requestLength); 00401 00402 //Check status code 00403 if(!error) 00404 { 00405 //Get the length of the resulting message 00406 replyLength = netBufferGetLength(reply) - replyOffset; 00407 00408 //Format IPv6 pseudo header 00409 replyPseudoHeader.destAddr = requestPseudoHeader->srcAddr; 00410 replyPseudoHeader.length = htonl(replyLength); 00411 replyPseudoHeader.reserved = 0; 00412 replyPseudoHeader.nextHeader = IPV6_ICMPV6_HEADER; 00413 00414 //Message checksum calculation 00415 replyHeader->checksum = ipCalcUpperLayerChecksumEx(&replyPseudoHeader, 00416 sizeof(Ipv6PseudoHeader), reply, replyOffset, replyLength); 00417 00418 //Debug message 00419 TRACE_INFO("Sending ICMPv6 Echo Reply message (%" PRIuSIZE " bytes)...\r\n", replyLength); 00420 //Dump message contents for debugging purpose 00421 icmpv6DumpEchoMessage(replyHeader); 00422 00423 //Send Echo Reply message 00424 ipv6SendDatagram(interface, &replyPseudoHeader, reply, replyOffset, 0); 00425 } 00426 00427 //Free previously allocated memory block 00428 netBufferFree(reply); 00429 } 00430 00431 00432 /** 00433 * @brief Send an ICMPv6 Error message 00434 * @param[in] interface Underlying network interface 00435 * @param[in] type Message type 00436 * @param[in] code Specific message code 00437 * @param[in] parameter Specific message parameter 00438 * @param[in] ipPacket Multi-part buffer that holds the invoking IPv6 packet 00439 * @param[in] ipPacketOffset Offset to the first byte of the IPv6 packet 00440 * @return Error code 00441 **/ 00442 00443 error_t icmpv6SendErrorMessage(NetInterface *interface, uint8_t type, uint8_t code, 00444 uint32_t parameter, const NetBuffer *ipPacket, size_t ipPacketOffset) 00445 { 00446 error_t error; 00447 size_t offset; 00448 size_t length; 00449 NetBuffer *icmpMessage; 00450 Icmpv6ErrorMessage *icmpHeader; 00451 Ipv6Header *ipHeader; 00452 Ipv6PseudoHeader pseudoHeader; 00453 00454 //Retrieve the length of the invoking IPv6 packet 00455 length = netBufferGetLength(ipPacket) - ipPacketOffset; 00456 00457 //Check the length of the IPv6 packet 00458 if(length < sizeof(Ipv6Header)) 00459 return ERROR_INVALID_LENGTH; 00460 00461 //Point to the header of the invoking packet 00462 ipHeader = netBufferAt(ipPacket, ipPacketOffset); 00463 00464 //Sanity check 00465 if(ipHeader == NULL) 00466 return ERROR_FAILURE; 00467 00468 //Check the type of the invoking packet 00469 if(ipHeader->nextHeader == IPV6_ICMPV6_HEADER) 00470 { 00471 //Make sure the ICMPv6 message is valid 00472 if(length >= (sizeof(Ipv6Header) + sizeof(Icmpv6Header))) 00473 { 00474 //Point to the ICMPv6 header 00475 icmpHeader = netBufferAt(ipPacket, ipPacketOffset + sizeof(Ipv6Header)); 00476 00477 //Sanity check 00478 if(icmpHeader != NULL) 00479 { 00480 //An ICMPv6 error message must not be originated as a result 00481 //of receiving an ICMPv6 error or redirect message 00482 if(icmpHeader->type == ICMPV6_TYPE_DEST_UNREACHABLE || 00483 icmpHeader->type == ICMPV6_TYPE_PACKET_TOO_BIG || 00484 icmpHeader->type == ICMPV6_TYPE_TIME_EXCEEDED || 00485 icmpHeader->type == ICMPV6_TYPE_PARAM_PROBLEM || 00486 icmpHeader->type == ICMPV6_TYPE_REDIRECT) 00487 { 00488 //Do not send the ICMPv6 error message... 00489 return ERROR_INVALID_TYPE; 00490 } 00491 } 00492 } 00493 } 00494 00495 //An ICMPv6 error message must not be originated as a result of 00496 //receiving a packet destined to an IPv6 multicast address 00497 if(ipv6IsMulticastAddr(&ipHeader->destAddr)) 00498 { 00499 //There are two exceptions to this rule 00500 if(type == ICMPV6_TYPE_PACKET_TOO_BIG) 00501 { 00502 //The Packet Too Big Message to allow Path MTU discovery to 00503 //work for IPv6 multicast 00504 } 00505 else if(type == ICMPV6_TYPE_PARAM_PROBLEM && 00506 code == ICMPV6_CODE_UNKNOWN_IPV6_OPTION) 00507 { 00508 //The Parameter Problem Message, reporting an unrecognized IPv6 00509 //option that has the Option Type highest-order two bits set to 10 00510 } 00511 else 00512 { 00513 //Do not send the ICMPv6 error message... 00514 return ERROR_INVALID_ADDRESS; 00515 } 00516 } 00517 00518 //An ICMPv6 error message must not be originated as a result of receiving a 00519 //packet whose source address does not uniquely identify a single node (e.g. 00520 //the IPv6 unspecified address, an IPv6 multicast address, or an address 00521 //known by the ICMPv6 message originator to be an IPv6 anycast address) 00522 if(ipv6IsAnycastAddr(interface, &ipHeader->srcAddr)) 00523 return ERROR_INVALID_ADDRESS; 00524 00525 //Return as much of invoking IPv6 packet as possible without 00526 //the ICMPv6 packet exceeding the minimum IPv6 MTU 00527 length = MIN(length, IPV6_DEFAULT_MTU - 00528 sizeof(Ipv6Header) - sizeof(Icmpv6ErrorMessage)); 00529 00530 //Allocate a memory buffer to hold the ICMPv6 message 00531 icmpMessage = ipAllocBuffer(sizeof(Icmpv6ErrorMessage), &offset); 00532 00533 //Failed to allocate memory? 00534 if(icmpMessage == NULL) 00535 return ERROR_OUT_OF_MEMORY; 00536 00537 //Point to the ICMPv6 header 00538 icmpHeader = netBufferAt(icmpMessage, offset); 00539 00540 //Format ICMPv6 Error message 00541 icmpHeader->type = type; 00542 icmpHeader->code = code; 00543 icmpHeader->checksum = 0; 00544 icmpHeader->parameter = htonl(parameter); 00545 00546 //Copy incoming IPv6 packet contents 00547 error = netBufferConcat(icmpMessage, ipPacket, ipPacketOffset, length); 00548 00549 //Check status code 00550 if(!error) 00551 { 00552 //Get the length of the resulting message 00553 length = netBufferGetLength(icmpMessage) - offset; 00554 00555 //Format IPv6 pseudo header 00556 pseudoHeader.destAddr = ipHeader->srcAddr; 00557 pseudoHeader.length = htonl(length); 00558 pseudoHeader.reserved = 0; 00559 pseudoHeader.nextHeader = IPV6_ICMPV6_HEADER; 00560 00561 //Select the relevant source address 00562 error = ipv6SelectSourceAddr(&interface, 00563 &pseudoHeader.destAddr, &pseudoHeader.srcAddr); 00564 00565 //Check status code 00566 if(!error) 00567 { 00568 //Message checksum calculation 00569 icmpHeader->checksum = ipCalcUpperLayerChecksumEx(&pseudoHeader, 00570 sizeof(Ipv6PseudoHeader), icmpMessage, offset, length); 00571 00572 //Debug message 00573 TRACE_INFO("Sending ICMPv6 Error message (%" PRIuSIZE " bytes)...\r\n", length); 00574 //Dump message contents for debugging purpose 00575 icmpv6DumpErrorMessage(icmpHeader); 00576 00577 //Send ICMPv6 Error message 00578 error = ipv6SendDatagram(interface, &pseudoHeader, icmpMessage, offset, 0); 00579 } 00580 } 00581 00582 //Free previously allocated memory 00583 netBufferFree(icmpMessage); 00584 00585 //Return status code 00586 return error; 00587 } 00588 00589 00590 /** 00591 * @brief Dump ICMPv6 message for debugging purpose 00592 * @param[in] message Pointer to the ICMP message 00593 **/ 00594 00595 void icmpv6DumpMessage(const Icmpv6Header *message) 00596 { 00597 //Dump ICMPv6 message 00598 TRACE_DEBUG(" Type = %" PRIu8 "\r\n", message->type); 00599 TRACE_DEBUG(" Code = %" PRIu8 "\r\n", message->code); 00600 TRACE_DEBUG(" Checksum = 0x%04" PRIX16 "\r\n", ntohs(message->checksum)); 00601 } 00602 00603 00604 /** 00605 * @brief Dump ICMPv6 Destination Unreachable message 00606 * @param[in] message Pointer to the ICMPv6 message 00607 **/ 00608 00609 void icmpv6DumpDestUnreachableMessage(const Icmpv6DestUnreachableMessage *message) 00610 { 00611 //Dump ICMPv6 message 00612 TRACE_DEBUG(" Type = %" PRIu8 "\r\n", message->type); 00613 TRACE_DEBUG(" Code = %" PRIu8 "\r\n", message->code); 00614 TRACE_DEBUG(" Checksum = 0x%04" PRIX16 "\r\n", ntohs(message->checksum)); 00615 } 00616 00617 00618 /** 00619 * @brief Dump ICMPv6 Packet Too Big message 00620 * @param[in] message Pointer to the ICMPv6 message 00621 **/ 00622 00623 void icmpv6DumpPacketTooBigMessage(const Icmpv6PacketTooBigMessage *message) 00624 { 00625 //Dump ICMPv6 message 00626 TRACE_DEBUG(" Type = %" PRIu8 "\r\n", message->type); 00627 TRACE_DEBUG(" Code = %" PRIu8 "\r\n", message->code); 00628 TRACE_DEBUG(" Checksum = 0x%04" PRIX16 "\r\n", ntohs(message->checksum)); 00629 TRACE_DEBUG(" MTU = %" PRIu32 "\r\n", ntohl(message->mtu)); 00630 } 00631 00632 00633 /** 00634 * @brief Dump ICMPv6 Echo Request or Echo Reply message 00635 * @param[in] message Pointer to the ICMPv6 message 00636 **/ 00637 00638 void icmpv6DumpEchoMessage(const Icmpv6EchoMessage *message) 00639 { 00640 //Dump ICMPv6 message 00641 TRACE_DEBUG(" Type = %" PRIu8 "\r\n", message->type); 00642 TRACE_DEBUG(" Code = %" PRIu8 "\r\n", message->code); 00643 TRACE_DEBUG(" Checksum = 0x%04" PRIX16 "\r\n", ntohs(message->checksum)); 00644 TRACE_DEBUG(" Identifier = 0x%04" PRIX16 "\r\n", ntohs(message->identifier)); 00645 TRACE_DEBUG(" Sequence Number = 0x%04" PRIX16 "\r\n", ntohs(message->sequenceNumber)); 00646 } 00647 00648 00649 /** 00650 * @brief Dump generic ICMPv6 Error message 00651 * @param[in] message Pointer to the ICMPv6 message 00652 **/ 00653 00654 void icmpv6DumpErrorMessage(const Icmpv6ErrorMessage *message) 00655 { 00656 //Dump ICMP message 00657 TRACE_DEBUG(" Type = %" PRIu8 "\r\n", message->type); 00658 TRACE_DEBUG(" Code = %" PRIu8 "\r\n", message->code); 00659 TRACE_DEBUG(" Checksum = 0x%04" PRIX16 "\r\n", ntohs(message->checksum)); 00660 TRACE_DEBUG(" Parameter = %" PRIu32 "\r\n", ntohl(message->parameter)); 00661 } 00662 00663 #endif 00664
Generated on Tue Jul 12 2022 17:10:13 by
1.7.2