Embed:
(wiki syntax)
Show/hide line numbers
icmpv6.c
Go to the documentation of this file.
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
