Webserver+3d print

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 icmpv6.c
Sergunb 0:8918a71cdbe9 3 * @brief ICMPv6 (Internet Control Message Protocol Version 6)
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 * @section Description
Sergunb 0:8918a71cdbe9 26 *
Sergunb 0:8918a71cdbe9 27 * ICMPv6 is used by IPv6 nodes to report errors encountered in
Sergunb 0:8918a71cdbe9 28 * processing packets, and to perform other Internet-layer functions.
Sergunb 0:8918a71cdbe9 29 * ICMPv6 is an integral part of IPv6 and must be fully implemented
Sergunb 0:8918a71cdbe9 30 * by every IPv6 node. Refer to the RFC 2463 for more details
Sergunb 0:8918a71cdbe9 31 *
Sergunb 0:8918a71cdbe9 32 * @author Oryx Embedded SARL (www.oryx-embedded.com)
Sergunb 0:8918a71cdbe9 33 * @version 1.7.6
Sergunb 0:8918a71cdbe9 34 **/
Sergunb 0:8918a71cdbe9 35
Sergunb 0:8918a71cdbe9 36 //Switch to the appropriate trace level
Sergunb 0:8918a71cdbe9 37 #define TRACE_LEVEL ICMPV6_TRACE_LEVEL
Sergunb 0:8918a71cdbe9 38
Sergunb 0:8918a71cdbe9 39 //Dependencies
Sergunb 0:8918a71cdbe9 40 #include <string.h>
Sergunb 0:8918a71cdbe9 41 #include "core/net.h"
Sergunb 0:8918a71cdbe9 42 #include "core/ip.h"
Sergunb 0:8918a71cdbe9 43 #include "ipv6/ipv6.h"
Sergunb 0:8918a71cdbe9 44 #include "ipv6/ipv6_misc.h"
Sergunb 0:8918a71cdbe9 45 #include "ipv6/ipv6_pmtu.h"
Sergunb 0:8918a71cdbe9 46 #include "ipv6/icmpv6.h"
Sergunb 0:8918a71cdbe9 47 #include "ipv6/mld.h"
Sergunb 0:8918a71cdbe9 48 #include "ipv6/ndp.h"
Sergunb 0:8918a71cdbe9 49 #include "ipv6/ndp_router_adv.h"
Sergunb 0:8918a71cdbe9 50 #include "debug.h"
Sergunb 0:8918a71cdbe9 51
Sergunb 0:8918a71cdbe9 52 //Check TCP/IP stack configuration
Sergunb 0:8918a71cdbe9 53 #if (IPV6_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 54
Sergunb 0:8918a71cdbe9 55
Sergunb 0:8918a71cdbe9 56 /**
Sergunb 0:8918a71cdbe9 57 * @brief Enable support for multicast Echo Request messages
Sergunb 0:8918a71cdbe9 58 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 59 * @param[in] enable When the flag is set to TRUE, the host will respond to
Sergunb 0:8918a71cdbe9 60 * multicast Echo Requests. When the flag is set to FALSE, incoming Echo
Sergunb 0:8918a71cdbe9 61 * Request messages destined to a multicast address will be dropped
Sergunb 0:8918a71cdbe9 62 * @return Error code
Sergunb 0:8918a71cdbe9 63 **/
Sergunb 0:8918a71cdbe9 64
Sergunb 0:8918a71cdbe9 65 error_t icmpv6EnableMulticastEchoRequest(NetInterface *interface, bool_t enable)
Sergunb 0:8918a71cdbe9 66 {
Sergunb 0:8918a71cdbe9 67 //Check parameters
Sergunb 0:8918a71cdbe9 68 if(interface == NULL)
Sergunb 0:8918a71cdbe9 69 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 70
Sergunb 0:8918a71cdbe9 71 //Get exclusive access
Sergunb 0:8918a71cdbe9 72 osAcquireMutex(&netMutex);
Sergunb 0:8918a71cdbe9 73 //Enable or disable support for multicast Echo Request messages
Sergunb 0:8918a71cdbe9 74 interface->ipv6Context.enableMulticastEchoReq = enable;
Sergunb 0:8918a71cdbe9 75 //Release exclusive access
Sergunb 0:8918a71cdbe9 76 osReleaseMutex(&netMutex);
Sergunb 0:8918a71cdbe9 77
Sergunb 0:8918a71cdbe9 78 //Successful processing
Sergunb 0:8918a71cdbe9 79 return NO_ERROR;
Sergunb 0:8918a71cdbe9 80 }
Sergunb 0:8918a71cdbe9 81
Sergunb 0:8918a71cdbe9 82
Sergunb 0:8918a71cdbe9 83 /**
Sergunb 0:8918a71cdbe9 84 * @brief Incoming ICMPv6 message processing
Sergunb 0:8918a71cdbe9 85 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 86 * @param[in] pseudoHeader IPv6 pseudo header
Sergunb 0:8918a71cdbe9 87 * @param[in] buffer Multi-part buffer containing the incoming ICMPv6 message
Sergunb 0:8918a71cdbe9 88 * @param[in] offset Offset to the first byte of the ICMPv6 message
Sergunb 0:8918a71cdbe9 89 * @param[in] hopLimit Hop Limit field from IPv6 header
Sergunb 0:8918a71cdbe9 90 **/
Sergunb 0:8918a71cdbe9 91
Sergunb 0:8918a71cdbe9 92 void icmpv6ProcessMessage(NetInterface *interface, Ipv6PseudoHeader *pseudoHeader,
Sergunb 0:8918a71cdbe9 93 const NetBuffer *buffer, size_t offset, uint8_t hopLimit)
Sergunb 0:8918a71cdbe9 94 {
Sergunb 0:8918a71cdbe9 95 size_t length;
Sergunb 0:8918a71cdbe9 96 Icmpv6Header *header;
Sergunb 0:8918a71cdbe9 97
Sergunb 0:8918a71cdbe9 98 //Retrieve the length of the ICMPv6 message
Sergunb 0:8918a71cdbe9 99 length = netBufferGetLength(buffer) - offset;
Sergunb 0:8918a71cdbe9 100
Sergunb 0:8918a71cdbe9 101 //Ensure the message length is correct
Sergunb 0:8918a71cdbe9 102 if(length < sizeof(Icmpv6Header))
Sergunb 0:8918a71cdbe9 103 {
Sergunb 0:8918a71cdbe9 104 //Debug message
Sergunb 0:8918a71cdbe9 105 TRACE_WARNING("ICMPv6 message length is invalid!\r\n");
Sergunb 0:8918a71cdbe9 106 //Exit immediately
Sergunb 0:8918a71cdbe9 107 return;
Sergunb 0:8918a71cdbe9 108 }
Sergunb 0:8918a71cdbe9 109
Sergunb 0:8918a71cdbe9 110 //Point to the ICMPv6 message header
Sergunb 0:8918a71cdbe9 111 header = netBufferAt(buffer, offset);
Sergunb 0:8918a71cdbe9 112
Sergunb 0:8918a71cdbe9 113 //Sanity check
Sergunb 0:8918a71cdbe9 114 if(header == NULL)
Sergunb 0:8918a71cdbe9 115 return;
Sergunb 0:8918a71cdbe9 116
Sergunb 0:8918a71cdbe9 117 //Debug message
Sergunb 0:8918a71cdbe9 118 TRACE_INFO("ICMPv6 message received (%" PRIuSIZE " bytes)...\r\n", length);
Sergunb 0:8918a71cdbe9 119 //Dump message contents for debugging purpose
Sergunb 0:8918a71cdbe9 120 icmpv6DumpMessage(header);
Sergunb 0:8918a71cdbe9 121
Sergunb 0:8918a71cdbe9 122 //Verify checksum value
Sergunb 0:8918a71cdbe9 123 if(ipCalcUpperLayerChecksumEx(pseudoHeader,
Sergunb 0:8918a71cdbe9 124 sizeof(Ipv6PseudoHeader), buffer, offset, length) != 0x0000)
Sergunb 0:8918a71cdbe9 125 {
Sergunb 0:8918a71cdbe9 126 //Debug message
Sergunb 0:8918a71cdbe9 127 TRACE_WARNING("Wrong ICMPv6 header checksum!\r\n");
Sergunb 0:8918a71cdbe9 128 //Exit immediately
Sergunb 0:8918a71cdbe9 129 return;
Sergunb 0:8918a71cdbe9 130 }
Sergunb 0:8918a71cdbe9 131
Sergunb 0:8918a71cdbe9 132 //Check whether the destination address is the tentative address
Sergunb 0:8918a71cdbe9 133 if(ipv6IsTentativeAddr(interface, &pseudoHeader->destAddr))
Sergunb 0:8918a71cdbe9 134 {
Sergunb 0:8918a71cdbe9 135 //The interface must accept Neighbor Solicitation and
Sergunb 0:8918a71cdbe9 136 //Neighbor Advertisement messages
Sergunb 0:8918a71cdbe9 137 if(header->type != ICMPV6_TYPE_NEIGHBOR_SOL &&
Sergunb 0:8918a71cdbe9 138 header->type != ICMPV6_TYPE_NEIGHBOR_ADV)
Sergunb 0:8918a71cdbe9 139 {
Sergunb 0:8918a71cdbe9 140 //Other packets addressed to the tentative address
Sergunb 0:8918a71cdbe9 141 //should be silently discarded
Sergunb 0:8918a71cdbe9 142 return;
Sergunb 0:8918a71cdbe9 143 }
Sergunb 0:8918a71cdbe9 144 }
Sergunb 0:8918a71cdbe9 145
Sergunb 0:8918a71cdbe9 146 //Check the type of message
Sergunb 0:8918a71cdbe9 147 switch(header->type)
Sergunb 0:8918a71cdbe9 148 {
Sergunb 0:8918a71cdbe9 149 //Destination Unreachable message?
Sergunb 0:8918a71cdbe9 150 case ICMPV6_TYPE_DEST_UNREACHABLE:
Sergunb 0:8918a71cdbe9 151 //Process Destination Unreachable message
Sergunb 0:8918a71cdbe9 152 icmpv6ProcessDestUnreachable(interface, pseudoHeader, buffer, offset);
Sergunb 0:8918a71cdbe9 153 break;
Sergunb 0:8918a71cdbe9 154 //Packet Too Big message?
Sergunb 0:8918a71cdbe9 155 case ICMPV6_TYPE_PACKET_TOO_BIG:
Sergunb 0:8918a71cdbe9 156 //Process Packet Too Big message
Sergunb 0:8918a71cdbe9 157 icmpv6ProcessPacketTooBig(interface, pseudoHeader, buffer, offset);
Sergunb 0:8918a71cdbe9 158 break;
Sergunb 0:8918a71cdbe9 159 //Echo Request message?
Sergunb 0:8918a71cdbe9 160 case ICMPV6_TYPE_ECHO_REQUEST:
Sergunb 0:8918a71cdbe9 161 //Process Echo Request message
Sergunb 0:8918a71cdbe9 162 icmpv6ProcessEchoRequest(interface, pseudoHeader, buffer, offset);
Sergunb 0:8918a71cdbe9 163 break;
Sergunb 0:8918a71cdbe9 164 #if (MLD_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 165 //Multicast Listener Query message?
Sergunb 0:8918a71cdbe9 166 case ICMPV6_TYPE_MULTICAST_LISTENER_QUERY:
Sergunb 0:8918a71cdbe9 167 //Process Multicast Listener Query message
Sergunb 0:8918a71cdbe9 168 mldProcessListenerQuery(interface, pseudoHeader, buffer, offset, hopLimit);
Sergunb 0:8918a71cdbe9 169 break;
Sergunb 0:8918a71cdbe9 170 //Version 1 Multicast Listener Report message?
Sergunb 0:8918a71cdbe9 171 case ICMPV6_TYPE_MULTICAST_LISTENER_REPORT_V1:
Sergunb 0:8918a71cdbe9 172 //Process Version 1 Multicast Listener Report message
Sergunb 0:8918a71cdbe9 173 mldProcessListenerReport(interface, pseudoHeader, buffer, offset, hopLimit);
Sergunb 0:8918a71cdbe9 174 break;
Sergunb 0:8918a71cdbe9 175 #endif
Sergunb 0:8918a71cdbe9 176 #if (NDP_ROUTER_ADV_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 177 //Router Solicitation message?
Sergunb 0:8918a71cdbe9 178 case ICMPV6_TYPE_ROUTER_SOL:
Sergunb 0:8918a71cdbe9 179 //Process Router Solicitation message
Sergunb 0:8918a71cdbe9 180 ndpProcessRouterSol(interface, pseudoHeader, buffer, offset, hopLimit);
Sergunb 0:8918a71cdbe9 181 break;
Sergunb 0:8918a71cdbe9 182 #endif
Sergunb 0:8918a71cdbe9 183 #if (NDP_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 184 //Router Advertisement message?
Sergunb 0:8918a71cdbe9 185 case ICMPV6_TYPE_ROUTER_ADV:
Sergunb 0:8918a71cdbe9 186 //Process Router Advertisement message
Sergunb 0:8918a71cdbe9 187 ndpProcessRouterAdv(interface, pseudoHeader, buffer, offset, hopLimit);
Sergunb 0:8918a71cdbe9 188 break;
Sergunb 0:8918a71cdbe9 189 //Neighbor Solicitation message?
Sergunb 0:8918a71cdbe9 190 case ICMPV6_TYPE_NEIGHBOR_SOL:
Sergunb 0:8918a71cdbe9 191 //Process Neighbor Solicitation message
Sergunb 0:8918a71cdbe9 192 ndpProcessNeighborSol(interface, pseudoHeader, buffer, offset, hopLimit);
Sergunb 0:8918a71cdbe9 193 break;
Sergunb 0:8918a71cdbe9 194 //Neighbor Advertisement message?
Sergunb 0:8918a71cdbe9 195 case ICMPV6_TYPE_NEIGHBOR_ADV:
Sergunb 0:8918a71cdbe9 196 //Process Neighbor Advertisement message
Sergunb 0:8918a71cdbe9 197 ndpProcessNeighborAdv(interface, pseudoHeader, buffer, offset, hopLimit);
Sergunb 0:8918a71cdbe9 198 break;
Sergunb 0:8918a71cdbe9 199 //Redirect message?
Sergunb 0:8918a71cdbe9 200 case ICMPV6_TYPE_REDIRECT:
Sergunb 0:8918a71cdbe9 201 //Process Redirect message
Sergunb 0:8918a71cdbe9 202 ndpProcessRedirect(interface, pseudoHeader, buffer, offset, hopLimit);
Sergunb 0:8918a71cdbe9 203 break;
Sergunb 0:8918a71cdbe9 204 #endif
Sergunb 0:8918a71cdbe9 205 //Unknown type?
Sergunb 0:8918a71cdbe9 206 default:
Sergunb 0:8918a71cdbe9 207 //Debug message
Sergunb 0:8918a71cdbe9 208 TRACE_WARNING("Unknown ICMPv6 message type!\r\n");
Sergunb 0:8918a71cdbe9 209 //Discard incoming ICMPv6 message
Sergunb 0:8918a71cdbe9 210 break;
Sergunb 0:8918a71cdbe9 211 }
Sergunb 0:8918a71cdbe9 212 }
Sergunb 0:8918a71cdbe9 213
Sergunb 0:8918a71cdbe9 214
Sergunb 0:8918a71cdbe9 215 /**
Sergunb 0:8918a71cdbe9 216 * @brief Destination Unreachable message processing
Sergunb 0:8918a71cdbe9 217 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 218 * @param[in] pseudoHeader IPv6 pseudo header
Sergunb 0:8918a71cdbe9 219 * @param[in] buffer Multi-part buffer containing the incoming ICMPv6 message
Sergunb 0:8918a71cdbe9 220 * @param[in] offset Offset to the first byte of the ICMPv6 message
Sergunb 0:8918a71cdbe9 221 **/
Sergunb 0:8918a71cdbe9 222
Sergunb 0:8918a71cdbe9 223 void icmpv6ProcessDestUnreachable(NetInterface *interface,
Sergunb 0:8918a71cdbe9 224 Ipv6PseudoHeader *pseudoHeader, const NetBuffer *buffer, size_t offset)
Sergunb 0:8918a71cdbe9 225 {
Sergunb 0:8918a71cdbe9 226 size_t length;
Sergunb 0:8918a71cdbe9 227 Icmpv6DestUnreachableMessage *icmpHeader;
Sergunb 0:8918a71cdbe9 228
Sergunb 0:8918a71cdbe9 229 //Retrieve the length of the Destination Unreachable message
Sergunb 0:8918a71cdbe9 230 length = netBufferGetLength(buffer) - offset;
Sergunb 0:8918a71cdbe9 231
Sergunb 0:8918a71cdbe9 232 //Ensure the packet length is correct
Sergunb 0:8918a71cdbe9 233 if(length < sizeof(Icmpv6DestUnreachableMessage))
Sergunb 0:8918a71cdbe9 234 return;
Sergunb 0:8918a71cdbe9 235
Sergunb 0:8918a71cdbe9 236 //Point to the ICMPv6 header
Sergunb 0:8918a71cdbe9 237 icmpHeader = netBufferAt(buffer, offset);
Sergunb 0:8918a71cdbe9 238
Sergunb 0:8918a71cdbe9 239 //Sanity check
Sergunb 0:8918a71cdbe9 240 if(icmpHeader == NULL)
Sergunb 0:8918a71cdbe9 241 return;
Sergunb 0:8918a71cdbe9 242
Sergunb 0:8918a71cdbe9 243 //Debug message
Sergunb 0:8918a71cdbe9 244 TRACE_INFO("ICMPv6 Destination Unreachable message received (%" PRIuSIZE " bytes)...\r\n", length);
Sergunb 0:8918a71cdbe9 245 //Dump message contents for debugging purpose
Sergunb 0:8918a71cdbe9 246 icmpv6DumpDestUnreachableMessage(icmpHeader);
Sergunb 0:8918a71cdbe9 247 }
Sergunb 0:8918a71cdbe9 248
Sergunb 0:8918a71cdbe9 249
Sergunb 0:8918a71cdbe9 250 /**
Sergunb 0:8918a71cdbe9 251 * @brief Packet Too Big message processing
Sergunb 0:8918a71cdbe9 252 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 253 * @param[in] pseudoHeader IPv6 pseudo header
Sergunb 0:8918a71cdbe9 254 * @param[in] buffer Multi-part buffer containing the incoming ICMPv6 message
Sergunb 0:8918a71cdbe9 255 * @param[in] offset Offset to the first byte of the ICMPv6 message
Sergunb 0:8918a71cdbe9 256 **/
Sergunb 0:8918a71cdbe9 257
Sergunb 0:8918a71cdbe9 258 void icmpv6ProcessPacketTooBig(NetInterface *interface,
Sergunb 0:8918a71cdbe9 259 Ipv6PseudoHeader *pseudoHeader, const NetBuffer *buffer, size_t offset)
Sergunb 0:8918a71cdbe9 260 {
Sergunb 0:8918a71cdbe9 261 size_t length;
Sergunb 0:8918a71cdbe9 262 Icmpv6PacketTooBigMessage *icmpHeader;
Sergunb 0:8918a71cdbe9 263
Sergunb 0:8918a71cdbe9 264 #if (IPV6_PMTU_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 265 uint32_t tentativePathMtu;
Sergunb 0:8918a71cdbe9 266 Ipv6Header* ipHeader;
Sergunb 0:8918a71cdbe9 267 #endif
Sergunb 0:8918a71cdbe9 268
Sergunb 0:8918a71cdbe9 269 //Retrieve the length of the Packet Too Big message
Sergunb 0:8918a71cdbe9 270 length = netBufferGetLength(buffer) - offset;
Sergunb 0:8918a71cdbe9 271
Sergunb 0:8918a71cdbe9 272 //Ensure the packet length is correct
Sergunb 0:8918a71cdbe9 273 if(length < sizeof(Icmpv6PacketTooBigMessage))
Sergunb 0:8918a71cdbe9 274 return;
Sergunb 0:8918a71cdbe9 275
Sergunb 0:8918a71cdbe9 276 //Point to the ICMPv6 header
Sergunb 0:8918a71cdbe9 277 icmpHeader = netBufferAt(buffer, offset);
Sergunb 0:8918a71cdbe9 278
Sergunb 0:8918a71cdbe9 279 //Sanity check
Sergunb 0:8918a71cdbe9 280 if(icmpHeader == NULL)
Sergunb 0:8918a71cdbe9 281 return;
Sergunb 0:8918a71cdbe9 282
Sergunb 0:8918a71cdbe9 283 //Debug message
Sergunb 0:8918a71cdbe9 284 TRACE_INFO("ICMPv6 Packet Too Big message received (%" PRIuSIZE " bytes)...\r\n", length);
Sergunb 0:8918a71cdbe9 285 //Dump message contents for debugging purpose
Sergunb 0:8918a71cdbe9 286 icmpv6DumpPacketTooBigMessage(icmpHeader);
Sergunb 0:8918a71cdbe9 287
Sergunb 0:8918a71cdbe9 288 #if (IPV6_PMTU_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 289 //Move to the beginning of the original IPv6 packet
Sergunb 0:8918a71cdbe9 290 offset += sizeof(Icmpv6PacketTooBigMessage);
Sergunb 0:8918a71cdbe9 291 length -= sizeof(Icmpv6PacketTooBigMessage);
Sergunb 0:8918a71cdbe9 292
Sergunb 0:8918a71cdbe9 293 //Ensure the packet length is correct
Sergunb 0:8918a71cdbe9 294 if(length < sizeof(Ipv6Header))
Sergunb 0:8918a71cdbe9 295 return;
Sergunb 0:8918a71cdbe9 296
Sergunb 0:8918a71cdbe9 297 //Point to the original IPv6 header
Sergunb 0:8918a71cdbe9 298 ipHeader = netBufferAt(buffer, offset);
Sergunb 0:8918a71cdbe9 299
Sergunb 0:8918a71cdbe9 300 //Sanity check
Sergunb 0:8918a71cdbe9 301 if(ipHeader == NULL)
Sergunb 0:8918a71cdbe9 302 return;
Sergunb 0:8918a71cdbe9 303
Sergunb 0:8918a71cdbe9 304 //The node uses the value in the MTU field in the Packet Too Big
Sergunb 0:8918a71cdbe9 305 //message as a tentative PMTU value
Sergunb 0:8918a71cdbe9 306 tentativePathMtu = ntohl(icmpHeader->mtu);
Sergunb 0:8918a71cdbe9 307
Sergunb 0:8918a71cdbe9 308 //Update the PMTU for the specified destination address
Sergunb 0:8918a71cdbe9 309 ipv6UpdatePathMtu(interface, &ipHeader->destAddr, tentativePathMtu);
Sergunb 0:8918a71cdbe9 310 #endif
Sergunb 0:8918a71cdbe9 311 }
Sergunb 0:8918a71cdbe9 312
Sergunb 0:8918a71cdbe9 313
Sergunb 0:8918a71cdbe9 314 /**
Sergunb 0:8918a71cdbe9 315 * @brief Echo Request message processing
Sergunb 0:8918a71cdbe9 316 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 317 * @param[in] requestPseudoHeader IPv6 pseudo header
Sergunb 0:8918a71cdbe9 318 * @param[in] request Multi-part buffer containing the incoming ICMPv6 message
Sergunb 0:8918a71cdbe9 319 * @param[in] requestOffset Offset to the first byte of the ICMPv6 message
Sergunb 0:8918a71cdbe9 320 **/
Sergunb 0:8918a71cdbe9 321
Sergunb 0:8918a71cdbe9 322 void icmpv6ProcessEchoRequest(NetInterface *interface, Ipv6PseudoHeader *requestPseudoHeader,
Sergunb 0:8918a71cdbe9 323 const NetBuffer *request, size_t requestOffset)
Sergunb 0:8918a71cdbe9 324 {
Sergunb 0:8918a71cdbe9 325 error_t error;
Sergunb 0:8918a71cdbe9 326 size_t requestLength;
Sergunb 0:8918a71cdbe9 327 size_t replyOffset;
Sergunb 0:8918a71cdbe9 328 size_t replyLength;
Sergunb 0:8918a71cdbe9 329 NetBuffer *reply;
Sergunb 0:8918a71cdbe9 330 Icmpv6EchoMessage *requestHeader;
Sergunb 0:8918a71cdbe9 331 Icmpv6EchoMessage *replyHeader;
Sergunb 0:8918a71cdbe9 332 Ipv6PseudoHeader replyPseudoHeader;
Sergunb 0:8918a71cdbe9 333
Sergunb 0:8918a71cdbe9 334 //Retrieve the length of the Echo Request message
Sergunb 0:8918a71cdbe9 335 requestLength = netBufferGetLength(request) - requestOffset;
Sergunb 0:8918a71cdbe9 336
Sergunb 0:8918a71cdbe9 337 //Ensure the packet length is correct
Sergunb 0:8918a71cdbe9 338 if(requestLength < sizeof(Icmpv6EchoMessage))
Sergunb 0:8918a71cdbe9 339 return;
Sergunb 0:8918a71cdbe9 340
Sergunb 0:8918a71cdbe9 341 //Point to the Echo Request header
Sergunb 0:8918a71cdbe9 342 requestHeader = netBufferAt(request, requestOffset);
Sergunb 0:8918a71cdbe9 343
Sergunb 0:8918a71cdbe9 344 //Sanity check
Sergunb 0:8918a71cdbe9 345 if(requestHeader == NULL)
Sergunb 0:8918a71cdbe9 346 return;
Sergunb 0:8918a71cdbe9 347
Sergunb 0:8918a71cdbe9 348 //Debug message
Sergunb 0:8918a71cdbe9 349 TRACE_INFO("ICMPv6 Echo Request message received (%" PRIuSIZE " bytes)...\r\n", requestLength);
Sergunb 0:8918a71cdbe9 350 //Dump message contents for debugging purpose
Sergunb 0:8918a71cdbe9 351 icmpv6DumpEchoMessage(requestHeader);
Sergunb 0:8918a71cdbe9 352
Sergunb 0:8918a71cdbe9 353 //Check whether the destination address of the Echo Request
Sergunb 0:8918a71cdbe9 354 //message is a multicast address
Sergunb 0:8918a71cdbe9 355 if(ipv6IsMulticastAddr(&requestPseudoHeader->destAddr))
Sergunb 0:8918a71cdbe9 356 {
Sergunb 0:8918a71cdbe9 357 //If support for multicast Echo Request messages has been explicitly
Sergunb 0:8918a71cdbe9 358 //disabled, then the host shall not respond to the incoming request
Sergunb 0:8918a71cdbe9 359 if(!interface->ipv6Context.enableMulticastEchoReq)
Sergunb 0:8918a71cdbe9 360 return;
Sergunb 0:8918a71cdbe9 361
Sergunb 0:8918a71cdbe9 362 //The source address of the reply must be a unicast address belonging to
Sergunb 0:8918a71cdbe9 363 //the interface on which the multicast Echo Request message was received
Sergunb 0:8918a71cdbe9 364 error = ipv6SelectSourceAddr(&interface,
Sergunb 0:8918a71cdbe9 365 &requestPseudoHeader->srcAddr, &replyPseudoHeader.srcAddr);
Sergunb 0:8918a71cdbe9 366
Sergunb 0:8918a71cdbe9 367 //Any error to report?
Sergunb 0:8918a71cdbe9 368 if(error)
Sergunb 0:8918a71cdbe9 369 return;
Sergunb 0:8918a71cdbe9 370 }
Sergunb 0:8918a71cdbe9 371 else
Sergunb 0:8918a71cdbe9 372 {
Sergunb 0:8918a71cdbe9 373 //The destination address of the Echo Request message is a unicast address
Sergunb 0:8918a71cdbe9 374 replyPseudoHeader.srcAddr = requestPseudoHeader->destAddr;
Sergunb 0:8918a71cdbe9 375 }
Sergunb 0:8918a71cdbe9 376
Sergunb 0:8918a71cdbe9 377 //Allocate memory to hold the Echo Reply message
Sergunb 0:8918a71cdbe9 378 reply = ipAllocBuffer(sizeof(Icmpv6EchoMessage), &replyOffset);
Sergunb 0:8918a71cdbe9 379
Sergunb 0:8918a71cdbe9 380 //Failed to allocate memory?
Sergunb 0:8918a71cdbe9 381 if(reply == NULL)
Sergunb 0:8918a71cdbe9 382 return;
Sergunb 0:8918a71cdbe9 383
Sergunb 0:8918a71cdbe9 384 //Point to the Echo Reply header
Sergunb 0:8918a71cdbe9 385 replyHeader = netBufferAt(reply, replyOffset);
Sergunb 0:8918a71cdbe9 386
Sergunb 0:8918a71cdbe9 387 //Format Echo Reply header
Sergunb 0:8918a71cdbe9 388 replyHeader->type = ICMPV6_TYPE_ECHO_REPLY;
Sergunb 0:8918a71cdbe9 389 replyHeader->code = 0;
Sergunb 0:8918a71cdbe9 390 replyHeader->checksum = 0;
Sergunb 0:8918a71cdbe9 391 replyHeader->identifier = requestHeader->identifier;
Sergunb 0:8918a71cdbe9 392 replyHeader->sequenceNumber = requestHeader->sequenceNumber;
Sergunb 0:8918a71cdbe9 393
Sergunb 0:8918a71cdbe9 394 //Point to the first data byte
Sergunb 0:8918a71cdbe9 395 requestOffset += sizeof(Icmpv6EchoMessage);
Sergunb 0:8918a71cdbe9 396 requestLength -= sizeof(Icmpv6EchoMessage);
Sergunb 0:8918a71cdbe9 397
Sergunb 0:8918a71cdbe9 398 //The data received in the ICMPv6 Echo Request message must be returned
Sergunb 0:8918a71cdbe9 399 //entirely and unmodified in the ICMPv6 Echo Reply message
Sergunb 0:8918a71cdbe9 400 error = netBufferConcat(reply, request, requestOffset, requestLength);
Sergunb 0:8918a71cdbe9 401
Sergunb 0:8918a71cdbe9 402 //Check status code
Sergunb 0:8918a71cdbe9 403 if(!error)
Sergunb 0:8918a71cdbe9 404 {
Sergunb 0:8918a71cdbe9 405 //Get the length of the resulting message
Sergunb 0:8918a71cdbe9 406 replyLength = netBufferGetLength(reply) - replyOffset;
Sergunb 0:8918a71cdbe9 407
Sergunb 0:8918a71cdbe9 408 //Format IPv6 pseudo header
Sergunb 0:8918a71cdbe9 409 replyPseudoHeader.destAddr = requestPseudoHeader->srcAddr;
Sergunb 0:8918a71cdbe9 410 replyPseudoHeader.length = htonl(replyLength);
Sergunb 0:8918a71cdbe9 411 replyPseudoHeader.reserved = 0;
Sergunb 0:8918a71cdbe9 412 replyPseudoHeader.nextHeader = IPV6_ICMPV6_HEADER;
Sergunb 0:8918a71cdbe9 413
Sergunb 0:8918a71cdbe9 414 //Message checksum calculation
Sergunb 0:8918a71cdbe9 415 replyHeader->checksum = ipCalcUpperLayerChecksumEx(&replyPseudoHeader,
Sergunb 0:8918a71cdbe9 416 sizeof(Ipv6PseudoHeader), reply, replyOffset, replyLength);
Sergunb 0:8918a71cdbe9 417
Sergunb 0:8918a71cdbe9 418 //Debug message
Sergunb 0:8918a71cdbe9 419 TRACE_INFO("Sending ICMPv6 Echo Reply message (%" PRIuSIZE " bytes)...\r\n", replyLength);
Sergunb 0:8918a71cdbe9 420 //Dump message contents for debugging purpose
Sergunb 0:8918a71cdbe9 421 icmpv6DumpEchoMessage(replyHeader);
Sergunb 0:8918a71cdbe9 422
Sergunb 0:8918a71cdbe9 423 //Send Echo Reply message
Sergunb 0:8918a71cdbe9 424 ipv6SendDatagram(interface, &replyPseudoHeader, reply, replyOffset, 0);
Sergunb 0:8918a71cdbe9 425 }
Sergunb 0:8918a71cdbe9 426
Sergunb 0:8918a71cdbe9 427 //Free previously allocated memory block
Sergunb 0:8918a71cdbe9 428 netBufferFree(reply);
Sergunb 0:8918a71cdbe9 429 }
Sergunb 0:8918a71cdbe9 430
Sergunb 0:8918a71cdbe9 431
Sergunb 0:8918a71cdbe9 432 /**
Sergunb 0:8918a71cdbe9 433 * @brief Send an ICMPv6 Error message
Sergunb 0:8918a71cdbe9 434 * @param[in] interface Underlying network interface
Sergunb 0:8918a71cdbe9 435 * @param[in] type Message type
Sergunb 0:8918a71cdbe9 436 * @param[in] code Specific message code
Sergunb 0:8918a71cdbe9 437 * @param[in] parameter Specific message parameter
Sergunb 0:8918a71cdbe9 438 * @param[in] ipPacket Multi-part buffer that holds the invoking IPv6 packet
Sergunb 0:8918a71cdbe9 439 * @param[in] ipPacketOffset Offset to the first byte of the IPv6 packet
Sergunb 0:8918a71cdbe9 440 * @return Error code
Sergunb 0:8918a71cdbe9 441 **/
Sergunb 0:8918a71cdbe9 442
Sergunb 0:8918a71cdbe9 443 error_t icmpv6SendErrorMessage(NetInterface *interface, uint8_t type, uint8_t code,
Sergunb 0:8918a71cdbe9 444 uint32_t parameter, const NetBuffer *ipPacket, size_t ipPacketOffset)
Sergunb 0:8918a71cdbe9 445 {
Sergunb 0:8918a71cdbe9 446 error_t error;
Sergunb 0:8918a71cdbe9 447 size_t offset;
Sergunb 0:8918a71cdbe9 448 size_t length;
Sergunb 0:8918a71cdbe9 449 NetBuffer *icmpMessage;
Sergunb 0:8918a71cdbe9 450 Icmpv6ErrorMessage *icmpHeader;
Sergunb 0:8918a71cdbe9 451 Ipv6Header *ipHeader;
Sergunb 0:8918a71cdbe9 452 Ipv6PseudoHeader pseudoHeader;
Sergunb 0:8918a71cdbe9 453
Sergunb 0:8918a71cdbe9 454 //Retrieve the length of the invoking IPv6 packet
Sergunb 0:8918a71cdbe9 455 length = netBufferGetLength(ipPacket) - ipPacketOffset;
Sergunb 0:8918a71cdbe9 456
Sergunb 0:8918a71cdbe9 457 //Check the length of the IPv6 packet
Sergunb 0:8918a71cdbe9 458 if(length < sizeof(Ipv6Header))
Sergunb 0:8918a71cdbe9 459 return ERROR_INVALID_LENGTH;
Sergunb 0:8918a71cdbe9 460
Sergunb 0:8918a71cdbe9 461 //Point to the header of the invoking packet
Sergunb 0:8918a71cdbe9 462 ipHeader = netBufferAt(ipPacket, ipPacketOffset);
Sergunb 0:8918a71cdbe9 463
Sergunb 0:8918a71cdbe9 464 //Sanity check
Sergunb 0:8918a71cdbe9 465 if(ipHeader == NULL)
Sergunb 0:8918a71cdbe9 466 return ERROR_FAILURE;
Sergunb 0:8918a71cdbe9 467
Sergunb 0:8918a71cdbe9 468 //Check the type of the invoking packet
Sergunb 0:8918a71cdbe9 469 if(ipHeader->nextHeader == IPV6_ICMPV6_HEADER)
Sergunb 0:8918a71cdbe9 470 {
Sergunb 0:8918a71cdbe9 471 //Make sure the ICMPv6 message is valid
Sergunb 0:8918a71cdbe9 472 if(length >= (sizeof(Ipv6Header) + sizeof(Icmpv6Header)))
Sergunb 0:8918a71cdbe9 473 {
Sergunb 0:8918a71cdbe9 474 //Point to the ICMPv6 header
Sergunb 0:8918a71cdbe9 475 icmpHeader = netBufferAt(ipPacket, ipPacketOffset + sizeof(Ipv6Header));
Sergunb 0:8918a71cdbe9 476
Sergunb 0:8918a71cdbe9 477 //Sanity check
Sergunb 0:8918a71cdbe9 478 if(icmpHeader != NULL)
Sergunb 0:8918a71cdbe9 479 {
Sergunb 0:8918a71cdbe9 480 //An ICMPv6 error message must not be originated as a result
Sergunb 0:8918a71cdbe9 481 //of receiving an ICMPv6 error or redirect message
Sergunb 0:8918a71cdbe9 482 if(icmpHeader->type == ICMPV6_TYPE_DEST_UNREACHABLE ||
Sergunb 0:8918a71cdbe9 483 icmpHeader->type == ICMPV6_TYPE_PACKET_TOO_BIG ||
Sergunb 0:8918a71cdbe9 484 icmpHeader->type == ICMPV6_TYPE_TIME_EXCEEDED ||
Sergunb 0:8918a71cdbe9 485 icmpHeader->type == ICMPV6_TYPE_PARAM_PROBLEM ||
Sergunb 0:8918a71cdbe9 486 icmpHeader->type == ICMPV6_TYPE_REDIRECT)
Sergunb 0:8918a71cdbe9 487 {
Sergunb 0:8918a71cdbe9 488 //Do not send the ICMPv6 error message...
Sergunb 0:8918a71cdbe9 489 return ERROR_INVALID_TYPE;
Sergunb 0:8918a71cdbe9 490 }
Sergunb 0:8918a71cdbe9 491 }
Sergunb 0:8918a71cdbe9 492 }
Sergunb 0:8918a71cdbe9 493 }
Sergunb 0:8918a71cdbe9 494
Sergunb 0:8918a71cdbe9 495 //An ICMPv6 error message must not be originated as a result of
Sergunb 0:8918a71cdbe9 496 //receiving a packet destined to an IPv6 multicast address
Sergunb 0:8918a71cdbe9 497 if(ipv6IsMulticastAddr(&ipHeader->destAddr))
Sergunb 0:8918a71cdbe9 498 {
Sergunb 0:8918a71cdbe9 499 //There are two exceptions to this rule
Sergunb 0:8918a71cdbe9 500 if(type == ICMPV6_TYPE_PACKET_TOO_BIG)
Sergunb 0:8918a71cdbe9 501 {
Sergunb 0:8918a71cdbe9 502 //The Packet Too Big Message to allow Path MTU discovery to
Sergunb 0:8918a71cdbe9 503 //work for IPv6 multicast
Sergunb 0:8918a71cdbe9 504 }
Sergunb 0:8918a71cdbe9 505 else if(type == ICMPV6_TYPE_PARAM_PROBLEM &&
Sergunb 0:8918a71cdbe9 506 code == ICMPV6_CODE_UNKNOWN_IPV6_OPTION)
Sergunb 0:8918a71cdbe9 507 {
Sergunb 0:8918a71cdbe9 508 //The Parameter Problem Message, reporting an unrecognized IPv6
Sergunb 0:8918a71cdbe9 509 //option that has the Option Type highest-order two bits set to 10
Sergunb 0:8918a71cdbe9 510 }
Sergunb 0:8918a71cdbe9 511 else
Sergunb 0:8918a71cdbe9 512 {
Sergunb 0:8918a71cdbe9 513 //Do not send the ICMPv6 error message...
Sergunb 0:8918a71cdbe9 514 return ERROR_INVALID_ADDRESS;
Sergunb 0:8918a71cdbe9 515 }
Sergunb 0:8918a71cdbe9 516 }
Sergunb 0:8918a71cdbe9 517
Sergunb 0:8918a71cdbe9 518 //An ICMPv6 error message must not be originated as a result of receiving a
Sergunb 0:8918a71cdbe9 519 //packet whose source address does not uniquely identify a single node (e.g.
Sergunb 0:8918a71cdbe9 520 //the IPv6 unspecified address, an IPv6 multicast address, or an address
Sergunb 0:8918a71cdbe9 521 //known by the ICMPv6 message originator to be an IPv6 anycast address)
Sergunb 0:8918a71cdbe9 522 if(ipv6IsAnycastAddr(interface, &ipHeader->srcAddr))
Sergunb 0:8918a71cdbe9 523 return ERROR_INVALID_ADDRESS;
Sergunb 0:8918a71cdbe9 524
Sergunb 0:8918a71cdbe9 525 //Return as much of invoking IPv6 packet as possible without
Sergunb 0:8918a71cdbe9 526 //the ICMPv6 packet exceeding the minimum IPv6 MTU
Sergunb 0:8918a71cdbe9 527 length = MIN(length, IPV6_DEFAULT_MTU -
Sergunb 0:8918a71cdbe9 528 sizeof(Ipv6Header) - sizeof(Icmpv6ErrorMessage));
Sergunb 0:8918a71cdbe9 529
Sergunb 0:8918a71cdbe9 530 //Allocate a memory buffer to hold the ICMPv6 message
Sergunb 0:8918a71cdbe9 531 icmpMessage = ipAllocBuffer(sizeof(Icmpv6ErrorMessage), &offset);
Sergunb 0:8918a71cdbe9 532
Sergunb 0:8918a71cdbe9 533 //Failed to allocate memory?
Sergunb 0:8918a71cdbe9 534 if(icmpMessage == NULL)
Sergunb 0:8918a71cdbe9 535 return ERROR_OUT_OF_MEMORY;
Sergunb 0:8918a71cdbe9 536
Sergunb 0:8918a71cdbe9 537 //Point to the ICMPv6 header
Sergunb 0:8918a71cdbe9 538 icmpHeader = netBufferAt(icmpMessage, offset);
Sergunb 0:8918a71cdbe9 539
Sergunb 0:8918a71cdbe9 540 //Format ICMPv6 Error message
Sergunb 0:8918a71cdbe9 541 icmpHeader->type = type;
Sergunb 0:8918a71cdbe9 542 icmpHeader->code = code;
Sergunb 0:8918a71cdbe9 543 icmpHeader->checksum = 0;
Sergunb 0:8918a71cdbe9 544 icmpHeader->parameter = htonl(parameter);
Sergunb 0:8918a71cdbe9 545
Sergunb 0:8918a71cdbe9 546 //Copy incoming IPv6 packet contents
Sergunb 0:8918a71cdbe9 547 error = netBufferConcat(icmpMessage, ipPacket, ipPacketOffset, length);
Sergunb 0:8918a71cdbe9 548
Sergunb 0:8918a71cdbe9 549 //Check status code
Sergunb 0:8918a71cdbe9 550 if(!error)
Sergunb 0:8918a71cdbe9 551 {
Sergunb 0:8918a71cdbe9 552 //Get the length of the resulting message
Sergunb 0:8918a71cdbe9 553 length = netBufferGetLength(icmpMessage) - offset;
Sergunb 0:8918a71cdbe9 554
Sergunb 0:8918a71cdbe9 555 //Format IPv6 pseudo header
Sergunb 0:8918a71cdbe9 556 pseudoHeader.destAddr = ipHeader->srcAddr;
Sergunb 0:8918a71cdbe9 557 pseudoHeader.length = htonl(length);
Sergunb 0:8918a71cdbe9 558 pseudoHeader.reserved = 0;
Sergunb 0:8918a71cdbe9 559 pseudoHeader.nextHeader = IPV6_ICMPV6_HEADER;
Sergunb 0:8918a71cdbe9 560
Sergunb 0:8918a71cdbe9 561 //Select the relevant source address
Sergunb 0:8918a71cdbe9 562 error = ipv6SelectSourceAddr(&interface,
Sergunb 0:8918a71cdbe9 563 &pseudoHeader.destAddr, &pseudoHeader.srcAddr);
Sergunb 0:8918a71cdbe9 564
Sergunb 0:8918a71cdbe9 565 //Check status code
Sergunb 0:8918a71cdbe9 566 if(!error)
Sergunb 0:8918a71cdbe9 567 {
Sergunb 0:8918a71cdbe9 568 //Message checksum calculation
Sergunb 0:8918a71cdbe9 569 icmpHeader->checksum = ipCalcUpperLayerChecksumEx(&pseudoHeader,
Sergunb 0:8918a71cdbe9 570 sizeof(Ipv6PseudoHeader), icmpMessage, offset, length);
Sergunb 0:8918a71cdbe9 571
Sergunb 0:8918a71cdbe9 572 //Debug message
Sergunb 0:8918a71cdbe9 573 TRACE_INFO("Sending ICMPv6 Error message (%" PRIuSIZE " bytes)...\r\n", length);
Sergunb 0:8918a71cdbe9 574 //Dump message contents for debugging purpose
Sergunb 0:8918a71cdbe9 575 icmpv6DumpErrorMessage(icmpHeader);
Sergunb 0:8918a71cdbe9 576
Sergunb 0:8918a71cdbe9 577 //Send ICMPv6 Error message
Sergunb 0:8918a71cdbe9 578 error = ipv6SendDatagram(interface, &pseudoHeader, icmpMessage, offset, 0);
Sergunb 0:8918a71cdbe9 579 }
Sergunb 0:8918a71cdbe9 580 }
Sergunb 0:8918a71cdbe9 581
Sergunb 0:8918a71cdbe9 582 //Free previously allocated memory
Sergunb 0:8918a71cdbe9 583 netBufferFree(icmpMessage);
Sergunb 0:8918a71cdbe9 584
Sergunb 0:8918a71cdbe9 585 //Return status code
Sergunb 0:8918a71cdbe9 586 return error;
Sergunb 0:8918a71cdbe9 587 }
Sergunb 0:8918a71cdbe9 588
Sergunb 0:8918a71cdbe9 589
Sergunb 0:8918a71cdbe9 590 /**
Sergunb 0:8918a71cdbe9 591 * @brief Dump ICMPv6 message for debugging purpose
Sergunb 0:8918a71cdbe9 592 * @param[in] message Pointer to the ICMP message
Sergunb 0:8918a71cdbe9 593 **/
Sergunb 0:8918a71cdbe9 594
Sergunb 0:8918a71cdbe9 595 void icmpv6DumpMessage(const Icmpv6Header *message)
Sergunb 0:8918a71cdbe9 596 {
Sergunb 0:8918a71cdbe9 597 //Dump ICMPv6 message
Sergunb 0:8918a71cdbe9 598 TRACE_DEBUG(" Type = %" PRIu8 "\r\n", message->type);
Sergunb 0:8918a71cdbe9 599 TRACE_DEBUG(" Code = %" PRIu8 "\r\n", message->code);
Sergunb 0:8918a71cdbe9 600 TRACE_DEBUG(" Checksum = 0x%04" PRIX16 "\r\n", ntohs(message->checksum));
Sergunb 0:8918a71cdbe9 601 }
Sergunb 0:8918a71cdbe9 602
Sergunb 0:8918a71cdbe9 603
Sergunb 0:8918a71cdbe9 604 /**
Sergunb 0:8918a71cdbe9 605 * @brief Dump ICMPv6 Destination Unreachable message
Sergunb 0:8918a71cdbe9 606 * @param[in] message Pointer to the ICMPv6 message
Sergunb 0:8918a71cdbe9 607 **/
Sergunb 0:8918a71cdbe9 608
Sergunb 0:8918a71cdbe9 609 void icmpv6DumpDestUnreachableMessage(const Icmpv6DestUnreachableMessage *message)
Sergunb 0:8918a71cdbe9 610 {
Sergunb 0:8918a71cdbe9 611 //Dump ICMPv6 message
Sergunb 0:8918a71cdbe9 612 TRACE_DEBUG(" Type = %" PRIu8 "\r\n", message->type);
Sergunb 0:8918a71cdbe9 613 TRACE_DEBUG(" Code = %" PRIu8 "\r\n", message->code);
Sergunb 0:8918a71cdbe9 614 TRACE_DEBUG(" Checksum = 0x%04" PRIX16 "\r\n", ntohs(message->checksum));
Sergunb 0:8918a71cdbe9 615 }
Sergunb 0:8918a71cdbe9 616
Sergunb 0:8918a71cdbe9 617
Sergunb 0:8918a71cdbe9 618 /**
Sergunb 0:8918a71cdbe9 619 * @brief Dump ICMPv6 Packet Too Big message
Sergunb 0:8918a71cdbe9 620 * @param[in] message Pointer to the ICMPv6 message
Sergunb 0:8918a71cdbe9 621 **/
Sergunb 0:8918a71cdbe9 622
Sergunb 0:8918a71cdbe9 623 void icmpv6DumpPacketTooBigMessage(const Icmpv6PacketTooBigMessage *message)
Sergunb 0:8918a71cdbe9 624 {
Sergunb 0:8918a71cdbe9 625 //Dump ICMPv6 message
Sergunb 0:8918a71cdbe9 626 TRACE_DEBUG(" Type = %" PRIu8 "\r\n", message->type);
Sergunb 0:8918a71cdbe9 627 TRACE_DEBUG(" Code = %" PRIu8 "\r\n", message->code);
Sergunb 0:8918a71cdbe9 628 TRACE_DEBUG(" Checksum = 0x%04" PRIX16 "\r\n", ntohs(message->checksum));
Sergunb 0:8918a71cdbe9 629 TRACE_DEBUG(" MTU = %" PRIu32 "\r\n", ntohl(message->mtu));
Sergunb 0:8918a71cdbe9 630 }
Sergunb 0:8918a71cdbe9 631
Sergunb 0:8918a71cdbe9 632
Sergunb 0:8918a71cdbe9 633 /**
Sergunb 0:8918a71cdbe9 634 * @brief Dump ICMPv6 Echo Request or Echo Reply message
Sergunb 0:8918a71cdbe9 635 * @param[in] message Pointer to the ICMPv6 message
Sergunb 0:8918a71cdbe9 636 **/
Sergunb 0:8918a71cdbe9 637
Sergunb 0:8918a71cdbe9 638 void icmpv6DumpEchoMessage(const Icmpv6EchoMessage *message)
Sergunb 0:8918a71cdbe9 639 {
Sergunb 0:8918a71cdbe9 640 //Dump ICMPv6 message
Sergunb 0:8918a71cdbe9 641 TRACE_DEBUG(" Type = %" PRIu8 "\r\n", message->type);
Sergunb 0:8918a71cdbe9 642 TRACE_DEBUG(" Code = %" PRIu8 "\r\n", message->code);
Sergunb 0:8918a71cdbe9 643 TRACE_DEBUG(" Checksum = 0x%04" PRIX16 "\r\n", ntohs(message->checksum));
Sergunb 0:8918a71cdbe9 644 TRACE_DEBUG(" Identifier = 0x%04" PRIX16 "\r\n", ntohs(message->identifier));
Sergunb 0:8918a71cdbe9 645 TRACE_DEBUG(" Sequence Number = 0x%04" PRIX16 "\r\n", ntohs(message->sequenceNumber));
Sergunb 0:8918a71cdbe9 646 }
Sergunb 0:8918a71cdbe9 647
Sergunb 0:8918a71cdbe9 648
Sergunb 0:8918a71cdbe9 649 /**
Sergunb 0:8918a71cdbe9 650 * @brief Dump generic ICMPv6 Error message
Sergunb 0:8918a71cdbe9 651 * @param[in] message Pointer to the ICMPv6 message
Sergunb 0:8918a71cdbe9 652 **/
Sergunb 0:8918a71cdbe9 653
Sergunb 0:8918a71cdbe9 654 void icmpv6DumpErrorMessage(const Icmpv6ErrorMessage *message)
Sergunb 0:8918a71cdbe9 655 {
Sergunb 0:8918a71cdbe9 656 //Dump ICMP message
Sergunb 0:8918a71cdbe9 657 TRACE_DEBUG(" Type = %" PRIu8 "\r\n", message->type);
Sergunb 0:8918a71cdbe9 658 TRACE_DEBUG(" Code = %" PRIu8 "\r\n", message->code);
Sergunb 0:8918a71cdbe9 659 TRACE_DEBUG(" Checksum = 0x%04" PRIX16 "\r\n", ntohs(message->checksum));
Sergunb 0:8918a71cdbe9 660 TRACE_DEBUG(" Parameter = %" PRIu32 "\r\n", ntohl(message->parameter));
Sergunb 0:8918a71cdbe9 661 }
Sergunb 0:8918a71cdbe9 662
Sergunb 0:8918a71cdbe9 663 #endif
Sergunb 0:8918a71cdbe9 664