icmp.c
Go to the documentation of this file.
1 /**
2  * @file icmp.c
3  * @brief ICMP (Internet Control Message Protocol)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2023 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.2.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL ICMP_TRACE_LEVEL
33 
34 //Dependencies
35 #include <string.h>
36 #include "core/net.h"
37 #include "core/ip.h"
38 #include "ipv4/ipv4.h"
39 #include "ipv4/ipv4_misc.h"
40 #include "ipv4/icmp.h"
41 #include "mibs/mib2_module.h"
42 #include "mibs/ip_mib_module.h"
43 #include "debug.h"
44 
45 //Check TCP/IP stack configuration
46 #if (IPV4_SUPPORT == ENABLED)
47 
48 
49 /**
50  * @brief Enable support for Echo Request messages
51  * @param[in] interface Underlying network interface
52  * @param[in] enable When the flag is set to TRUE, the host will respond to
53  * Echo Requests. When the flag is set to FALSE, incoming Echo Request
54  * messages will be dropped
55  * @return Error code
56  **/
57 
59 {
60  //Check parameters
61  if(interface == NULL)
63 
64  //Get exclusive access
66  //Enable or disable support for Echo Request messages
67  interface->ipv4Context.enableEchoReq = enable;
68  //Release exclusive access
70 
71  //Successful processing
72  return NO_ERROR;
73 }
74 
75 
76 /**
77  * @brief Enable support for broadcast Echo Request messages
78  * @param[in] interface Underlying network interface
79  * @param[in] enable When the flag is set to TRUE, the host will respond to
80  * broadcast Echo Requests. When the flag is set to FALSE, incoming Echo
81  * Request messages destined to a broadcast address will be dropped
82  * @return Error code
83  **/
84 
86 {
87  //Check parameters
88  if(interface == NULL)
90 
91  //Get exclusive access
93  //Enable or disable support for broadcast Echo Request messages
94  interface->ipv4Context.enableBroadcastEchoReq = enable;
95  //Release exclusive access
97 
98  //Successful processing
99  return NO_ERROR;
100 }
101 
102 
103 /**
104  * @brief Incoming ICMP message processing
105  * @param[in] interface Underlying network interface
106  * @param[in] requestPseudoHeader IPv4 pseudo header
107  * @param[in] buffer Multi-part buffer containing the incoming ICMP message
108  * @param[in] offset Offset to the first byte of the ICMP message
109  **/
110 
112  Ipv4PseudoHeader *requestPseudoHeader, const NetBuffer *buffer,
113  size_t offset)
114 {
115  size_t length;
116  IcmpHeader *header;
117 
118  //Total number of ICMP messages which the entity received
119  MIB2_ICMP_INC_COUNTER32(icmpInMsgs, 1);
120  IP_MIB_INC_COUNTER32(icmpStats.icmpStatsInMsgs, 1);
121 
122  //Retrieve the length of the ICMP message
123  length = netBufferGetLength(buffer) - offset;
124 
125  //Ensure the message length is correct
126  if(length < sizeof(IcmpHeader))
127  {
128  //Number of ICMP messages which the entity received but determined
129  //as having ICMP-specific errors
130  MIB2_ICMP_INC_COUNTER32(icmpInErrors, 1);
131  IP_MIB_INC_COUNTER32(icmpStats.icmpStatsInErrors, 1);
132 
133  //Silently discard incoming message
134  return;
135  }
136 
137  //Point to the ICMP message header
138  header = netBufferAt(buffer, offset);
139  //Sanity check
140  if(header == NULL)
141  return;
142 
143  //Debug message
144  TRACE_INFO("ICMP message received (%" PRIuSIZE " bytes)...\r\n", length);
145  //Dump message contents for debugging purpose
146  icmpDumpMessage(header);
147 
148  //Verify checksum value
149  if(ipCalcChecksumEx(buffer, offset, length) != 0x0000)
150  {
151  //Debug message
152  TRACE_WARNING("Wrong ICMP header checksum!\r\n");
153 
154  //Number of ICMP messages which the entity received but determined
155  //as having ICMP-specific errors
156  MIB2_ICMP_INC_COUNTER32(icmpInErrors, 1);
157  IP_MIB_INC_COUNTER32(icmpStats.icmpStatsInErrors, 1);
158 
159  //Drop incoming message
160  return;
161  }
162 
163  //Update ICMP statistics
164  icmpUpdateInStats(header->type);
165 
166  //Check the type of ICMP message
167  switch(header->type)
168  {
169  //Echo Request?
171  //Process Echo Request message
172  icmpProcessEchoRequest(interface, requestPseudoHeader, buffer, offset);
173  break;
174  //Unknown type?
175  default:
176  //Debug message
177  TRACE_WARNING("Unknown ICMP message type!\r\n");
178  //Discard incoming ICMP message
179  break;
180  }
181 }
182 
183 
184 /**
185  * @brief Echo Request message processing
186  * @param[in] interface Underlying network interface
187  * @param[in] requestPseudoHeader IPv4 pseudo header
188  * @param[in] request Multi-part buffer containing the incoming Echo Request message
189  * @param[in] requestOffset Offset to the first byte of the Echo Request message
190  **/
191 
193  Ipv4PseudoHeader *requestPseudoHeader, const NetBuffer *request,
194  size_t requestOffset)
195 {
196  error_t error;
197  size_t requestLength;
198  size_t replyOffset;
199  size_t replyLength;
200  NetBuffer *reply;
201  IcmpEchoMessage *requestHeader;
202  IcmpEchoMessage *replyHeader;
203  Ipv4PseudoHeader replyPseudoHeader;
204 
205  //Retrieve the length of the Echo Request message
206  requestLength = netBufferGetLength(request) - requestOffset;
207 
208  //Ensure the packet length is correct
209  if(requestLength < sizeof(IcmpEchoMessage))
210  return;
211 
212  //Point to the Echo Request header
213  requestHeader = netBufferAt(request, requestOffset);
214  //Sanity check
215  if(requestHeader == NULL)
216  return;
217 
218  //Debug message
219  TRACE_INFO("ICMP Echo Request message received (%" PRIuSIZE " bytes)...\r\n", requestLength);
220  //Dump message contents for debugging purpose
221  icmpDumpEchoMessage(requestHeader);
222 
223  //If support for Echo Request messages has been explicitly disabled, then
224  //the host shall not respond to the incoming request
225  if(!interface->ipv4Context.enableEchoReq)
226  return;
227 
228  //Check whether the destination address of the Echo Request message is
229  //a broadcast or a multicast address
230  if(ipv4IsBroadcastAddr(interface, requestPseudoHeader->destAddr) ||
231  ipv4IsMulticastAddr(requestPseudoHeader->destAddr))
232  {
234 
235  //If support for broadcast Echo Request messages has been explicitly
236  //disabled, then the host shall not respond to the incoming request
237  if(!interface->ipv4Context.enableBroadcastEchoReq)
238  return;
239 
240  //The source address of the reply must be a unicast address belonging to
241  //the interface on which the broadcast Echo Request message was received
242  error = ipv4SelectSourceAddr(&interface, requestPseudoHeader->srcAddr,
243  &ipAddr);
244  //Any error to report?
245  if(error)
246  return;
247 
248  //Copy the resulting source IP address
249  replyPseudoHeader.srcAddr = ipAddr;
250  }
251  else
252  {
253  //The destination address of the Echo Request message is a unicast address
254  replyPseudoHeader.srcAddr = requestPseudoHeader->destAddr;
255  }
256 
257  //Allocate memory to hold the Echo Reply message
258  reply = ipAllocBuffer(sizeof(IcmpEchoMessage), &replyOffset);
259  //Failed to allocate memory?
260  if(reply == NULL)
261  return;
262 
263  //Point to the Echo Reply header
264  replyHeader = netBufferAt(reply, replyOffset);
265 
266  //Format Echo Reply header
267  replyHeader->type = ICMP_TYPE_ECHO_REPLY;
268  replyHeader->code = 0;
269  replyHeader->checksum = 0;
270  replyHeader->identifier = requestHeader->identifier;
271  replyHeader->sequenceNumber = requestHeader->sequenceNumber;
272 
273  //Point to the first data byte
274  requestOffset += sizeof(IcmpEchoMessage);
275  requestLength -= sizeof(IcmpEchoMessage);
276 
277  //Check the length of the payload
278  if(requestLength > 0)
279  {
280  //Copy payload data
281  error = netBufferConcat(reply, request, requestOffset, requestLength);
282  }
283  else
284  {
285  //The Echo Request message is empty
286  error = NO_ERROR;
287  }
288 
289  //Check status code
290  if(!error)
291  {
292  NetTxAncillary ancillary;
293 
294  //Get the length of the resulting message
295  replyLength = netBufferGetLength(reply) - replyOffset;
296  //Calculate ICMP header checksum
297  replyHeader->checksum = ipCalcChecksumEx(reply, replyOffset, replyLength);
298 
299  //Format IPv4 pseudo header
300  replyPseudoHeader.destAddr = requestPseudoHeader->srcAddr;
301  replyPseudoHeader.reserved = 0;
302  replyPseudoHeader.protocol = IPV4_PROTOCOL_ICMP;
303  replyPseudoHeader.length = htons(replyLength);
304 
305  //Update ICMP statistics
307 
308  //Debug message
309  TRACE_INFO("Sending ICMP Echo Reply message (%" PRIuSIZE " bytes)...\r\n", replyLength);
310  //Dump message contents for debugging purpose
311  icmpDumpEchoMessage(replyHeader);
312 
313  //Additional options can be passed to the stack along with the packet
314  ancillary = NET_DEFAULT_TX_ANCILLARY;
315 
316  //Send Echo Reply message
317  ipv4SendDatagram(interface, &replyPseudoHeader, reply, replyOffset,
318  &ancillary);
319  }
320 
321  //Free previously allocated memory block
322  netBufferFree(reply);
323 }
324 
325 
326 /**
327  * @brief Send an ICMP Error message
328  * @param[in] interface Underlying network interface
329  * @param[in] type Message type
330  * @param[in] code Specific message code
331  * @param[in] parameter Specific message parameter
332  * @param[in] ipPacket Multi-part buffer that holds the invoking IPv4 packet
333  * @param[in] ipPacketOffset Offset to the first byte of the IPv4 packet
334  * @return Error code
335  **/
336 
337 error_t icmpSendErrorMessage(NetInterface *interface, uint8_t type, uint8_t code,
338  uint8_t parameter, const NetBuffer *ipPacket, size_t ipPacketOffset)
339 {
340  error_t error;
341  size_t offset;
342  size_t length;
343  Ipv4Header *ipHeader;
344  NetBuffer *icmpMessage;
345  IcmpErrorMessage *icmpHeader;
346  Ipv4PseudoHeader pseudoHeader;
347 
348  //Retrieve the length of the invoking IPv4 packet
349  length = netBufferGetLength(ipPacket) - ipPacketOffset;
350 
351  //Check the length of the IPv4 packet
352  if(length < sizeof(Ipv4Header))
353  return ERROR_INVALID_LENGTH;
354 
355  //Point to the header of the invoking packet
356  ipHeader = netBufferAt(ipPacket, ipPacketOffset);
357  //Sanity check
358  if(ipHeader == NULL)
359  return ERROR_FAILURE;
360 
361  //Never respond to a packet destined to a broadcast or a multicast address
362  if(ipv4IsBroadcastAddr(interface, ipHeader->destAddr) ||
363  ipv4IsMulticastAddr(ipHeader->destAddr))
364  {
365  //Report an error
366  return ERROR_INVALID_ADDRESS;
367  }
368 
369  //Length of the data that will be returned along with the ICMP header
370  length = MIN(length, (size_t) ipHeader->headerLength * 4 + 8);
371 
372  //Allocate a memory buffer to hold the ICMP message
373  icmpMessage = ipAllocBuffer(sizeof(IcmpErrorMessage), &offset);
374  //Failed to allocate memory?
375  if(icmpMessage == NULL)
376  return ERROR_OUT_OF_MEMORY;
377 
378  //Point to the ICMP header
379  icmpHeader = netBufferAt(icmpMessage, offset);
380 
381  //Format ICMP message
382  icmpHeader->type = type;
383  icmpHeader->code = code;
384  icmpHeader->checksum = 0;
385  icmpHeader->parameter = parameter;
386  icmpHeader->unused[0] = 0;
387  icmpHeader->unused[1] = 0;
388  icmpHeader->unused[2] = 0;
389 
390  //Copy the IP header and the first 8 bytes of the original datagram data
391  error = netBufferConcat(icmpMessage, ipPacket, ipPacketOffset, length);
392 
393  //Check status code
394  if(!error)
395  {
396  NetTxAncillary ancillary;
397 
398  //Get the length of the resulting message
399  length = netBufferGetLength(icmpMessage) - offset;
400  //Message checksum calculation
401  icmpHeader->checksum = ipCalcChecksumEx(icmpMessage, offset, length);
402 
403  //Format IPv4 pseudo header
404  pseudoHeader.srcAddr = ipHeader->destAddr;
405  pseudoHeader.destAddr = ipHeader->srcAddr;
406  pseudoHeader.reserved = 0;
407  pseudoHeader.protocol = IPV4_PROTOCOL_ICMP;
408  pseudoHeader.length = htons(length);
409 
410  //Update ICMP statistics
412 
413  //Debug message
414  TRACE_INFO("Sending ICMP Error message (%" PRIuSIZE " bytes)...\r\n", length);
415  //Dump message contents for debugging purpose
416  icmpDumpErrorMessage(icmpHeader);
417 
418  //Additional options can be passed to the stack along with the packet
419  ancillary = NET_DEFAULT_TX_ANCILLARY;
420 
421  //Send ICMP Error message
422  error = ipv4SendDatagram(interface, &pseudoHeader, icmpMessage, offset,
423  &ancillary);
424  }
425 
426  //Free previously allocated memory
427  netBufferFree(icmpMessage);
428 
429  //Return status code
430  return error;
431 }
432 
433 
434 /**
435  * @brief Update ICMP input statistics
436  * @param[in] type ICMP message type
437  **/
438 
439 void icmpUpdateInStats(uint8_t type)
440 {
441  //Check ICMP message type
442  switch(type)
443  {
445  //Number of ICMP Destination Unreachable messages received
446  MIB2_ICMP_INC_COUNTER32(icmpInDestUnreachs, 1);
447  break;
448 
450  //Number of ICMP Time Exceeded messages received
451  MIB2_ICMP_INC_COUNTER32(icmpInTimeExcds, 1);
452  break;
453 
455  //Number of ICMP Parameter Problem messages received
456  MIB2_ICMP_INC_COUNTER32(icmpInParmProbs, 1);
457  break;
458 
460  //Number of ICMP Source Quench messages received
461  MIB2_ICMP_INC_COUNTER32(icmpInSrcQuenchs, 1);
462  break;
463 
464  case ICMP_TYPE_REDIRECT:
465  //Number of ICMP Redirect messages received
466  MIB2_ICMP_INC_COUNTER32(icmpInRedirects, 1);
467  break;
468 
470  //Number of ICMP Echo Request messages received
471  MIB2_ICMP_INC_COUNTER32(icmpInEchos, 1);
472  break;
473 
475  //Number of ICMP Echo Reply messages received
476  MIB2_ICMP_INC_COUNTER32(icmpInEchoReps, 1);
477  break;
478 
480  //Number of ICMP Timestamp Request messages received
481  MIB2_ICMP_INC_COUNTER32(icmpInTimestamps, 1);
482  break;
483 
485  //Number of ICMP Timestamp Reply messages received
486  MIB2_ICMP_INC_COUNTER32(icmpInTimestampReps, 1);
487  break;
488 
490  //Number of ICMP Address Mask Request messages received
491  MIB2_ICMP_INC_COUNTER32(icmpInAddrMasks, 1);
492  break;
493 
495  //Number of ICMP Address Mask Reply messages received
496  MIB2_ICMP_INC_COUNTER32(icmpInAddrMaskReps, 1);
497  break;
498 
499  default:
500  //Just for sanity
501  break;
502  }
503 
504  //Increment per-message type ICMP counter
505  IP_MIB_INC_COUNTER32(icmpMsgStatsTable.icmpMsgStatsInPkts[type], 1);
506 }
507 
508 
509 /**
510  * @brief Update ICMP output statistics
511  * @param[in] type ICMPv6 message type
512  **/
513 
515 {
516  //Total number of ICMP messages which this entity attempted to send
517  MIB2_ICMP_INC_COUNTER32(icmpOutMsgs, 1);
518  IP_MIB_INC_COUNTER32(icmpStats.icmpStatsOutMsgs, 1);
519 
520  //Check ICMP message type
521  switch(type)
522  {
524  //Number of ICMP Destination Unreachable messages sent
525  MIB2_ICMP_INC_COUNTER32(icmpOutDestUnreachs, 1);
526  break;
527 
529  //Number of ICMP Time Exceeded messages sent
530  MIB2_ICMP_INC_COUNTER32(icmpOutTimeExcds, 1);
531  break;
532 
534  //Number of ICMP Parameter Problem messages sent
535  MIB2_ICMP_INC_COUNTER32(icmpOutParmProbs, 1);
536  break;
537 
539  //Number of ICMP Source Quench messages sent
540  MIB2_ICMP_INC_COUNTER32(icmpOutSrcQuenchs, 1);
541  break;
542 
543  case ICMP_TYPE_REDIRECT:
544  //Number of ICMP Redirect messages sent
545  MIB2_ICMP_INC_COUNTER32(icmpOutRedirects, 1);
546  break;
547 
549  //Number of ICMP Echo Request messages sent
550  MIB2_ICMP_INC_COUNTER32(icmpOutEchos, 1);
551  break;
552 
554  //Number of ICMP Echo Reply messages sent
555  MIB2_ICMP_INC_COUNTER32(icmpOutEchoReps, 1);
556  break;
557 
559  //Number of ICMP Timestamp Request messages sent
560  MIB2_ICMP_INC_COUNTER32(icmpOutTimestamps, 1);
561  break;
562 
564  //Number of ICMP Timestamp Reply messages sent
565  MIB2_ICMP_INC_COUNTER32(icmpOutTimestampReps, 1);
566  break;
567 
569  //Number of ICMP Address Mask Request messages sent
570  MIB2_ICMP_INC_COUNTER32(icmpOutAddrMasks, 1);
571  break;
572 
574  //Number of ICMP Address Mask Reply messages sent
575  MIB2_ICMP_INC_COUNTER32(icmpOutAddrMaskReps, 1);
576  break;
577 
578  default:
579  //Just for sanity
580  break;
581  }
582 
583  //Increment per-message type ICMP counter
584  IP_MIB_INC_COUNTER32(icmpMsgStatsTable.icmpMsgStatsOutPkts[type], 1);
585 }
586 
587 
588 /**
589  * @brief Dump ICMP message for debugging purpose
590  * @param[in] message Pointer to the ICMP message
591  **/
592 
594 {
595  //Dump ICMP message
596  TRACE_DEBUG(" Type = %" PRIu8 "\r\n", message->type);
597  TRACE_DEBUG(" Code = %" PRIu8 "\r\n", message->code);
598  TRACE_DEBUG(" Checksum = 0x%04" PRIX16 "\r\n", ntohs(message->checksum));
599 }
600 
601 
602 /**
603  * @brief Dump ICMP Echo Request or Echo Reply message
604  * @param[in] message Pointer to the ICMP message
605  **/
606 
608 {
609  //Dump ICMP message
610  TRACE_DEBUG(" Type = %" PRIu8 "\r\n", message->type);
611  TRACE_DEBUG(" Code = %" PRIu8 "\r\n", message->code);
612  TRACE_DEBUG(" Checksum = 0x%04" PRIX16 "\r\n", ntohs(message->checksum));
613  TRACE_DEBUG(" Identifier = 0x%04" PRIX16 "\r\n", ntohs(message->identifier));
614  TRACE_DEBUG(" Sequence Number = 0x%04" PRIX16 "\r\n", ntohs(message->sequenceNumber));
615 }
616 
617 
618 /**
619  * @brief Dump generic ICMP Error message
620  * @param[in] message Pointer to the ICMP message
621  **/
622 
624 {
625  //Dump ICMP message
626  TRACE_DEBUG(" Type = %" PRIu8 "\r\n", message->type);
627  TRACE_DEBUG(" Code = %" PRIu8 "\r\n", message->code);
628  TRACE_DEBUG(" Checksum = 0x%04" PRIX16 "\r\n", ntohs(message->checksum));
629  TRACE_DEBUG(" Parameter = %" PRIu8 "\r\n", message->parameter);
630 }
631 
632 #endif
#define ipv4IsMulticastAddr(ipAddr)
Definition: ipv4.h:169
uint8_t length
Definition: coap_common.h:193
#define htons(value)
Definition: cpu_endian.h:413
MIB-II module.
NetBuffer * ipAllocBuffer(size_t length, size_t *offset)
Allocate a buffer to hold an IP packet.
Definition: ip.c:724
@ ICMP_TYPE_ADDR_MASK_REQUEST
Definition: icmp.h:64
uint8_t code
Definition: coap_common.h:177
int bool_t
Definition: compiler_port.h:53
#define Ipv4Header
Definition: ipv4.h:36
void icmpDumpEchoMessage(const IcmpEchoMessage *message)
Dump ICMP Echo Request or Echo Reply message.
Definition: icmp.c:607
@ IPV4_PROTOCOL_ICMP
Definition: ipv4.h:221
uint16_t ipCalcChecksumEx(const NetBuffer *buffer, size_t offset, size_t length)
Calculate IP checksum over a multi-part buffer.
Definition: ip.c:599
const NetTxAncillary NET_DEFAULT_TX_ANCILLARY
Definition: net_misc.c:71
#define netMutex
Definition: net_legacy.h:195
#define IP_MIB_INC_COUNTER32(name, value)
Definition: ip_mib_module.h:46
error_t icmpEnableBroadcastEchoRequest(NetInterface *interface, bool_t enable)
Enable support for broadcast Echo Request messages.
Definition: icmp.c:85
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:89
bool_t ipv4IsBroadcastAddr(NetInterface *interface, Ipv4Addr ipAddr)
Check whether an IPv4 address is a broadcast address.
Definition: ipv4_misc.c:469
__start_packed struct @5 IcmpEchoMessage
ICMP Echo Request and Echo Reply messages.
void icmpProcessEchoRequest(NetInterface *interface, Ipv4PseudoHeader *requestPseudoHeader, const NetBuffer *request, size_t requestOffset)
Echo Request message processing.
Definition: icmp.c:192
error_t icmpEnableEchoRequest(NetInterface *interface, bool_t enable)
Enable support for Echo Request messages.
Definition: icmp.c:58
error_t ipv4SelectSourceAddr(NetInterface **interface, Ipv4Addr destAddr, Ipv4Addr *srcAddr)
IPv4 source address selection.
Definition: ipv4_misc.c:203
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
@ ICMP_TYPE_TIME_EXCEEDED
Definition: icmp.h:58
uint8_t parameter
Definition: icmp.h:123
__start_packed struct @0 IcmpHeader
ICMP header.
@ ICMP_TYPE_PARAM_PROBLEM
Definition: icmp.h:59
uint32_t Ipv4Addr
IPv4 network address.
Definition: ipv4.h:268
uint8_t ipPacket[]
Definition: ndp.h:429
error_t netBufferConcat(NetBuffer *dest, const NetBuffer *src, size_t srcOffset, size_t length)
Concatenate two multi-part buffers.
Definition: net_mem.c:442
__start_packed struct @1 IcmpErrorMessage
ICMP Error message.
Helper functions for IPv4.
void icmpDumpErrorMessage(const IcmpErrorMessage *message)
Dump generic ICMP Error message.
Definition: icmp.c:623
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
ICMP (Internet Control Message Protocol)
char_t type
error_t
Error codes.
Definition: error.h:43
@ ICMP_TYPE_REDIRECT
Definition: icmp.h:56
void * netBufferAt(const NetBuffer *buffer, size_t offset)
Returns a pointer to the data at the specified position.
Definition: net_mem.c:413
@ ERROR_INVALID_ADDRESS
Definition: error.h:103
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
@ ICMP_TYPE_TIMESTAMP_REPLY
Definition: icmp.h:61
@ ICMP_TYPE_SOURCE_QUENCH
Definition: icmp.h:55
#define MIB2_ICMP_INC_COUNTER32(name, value)
Definition: mib2_module.h:171
#define NetInterface
Definition: net.h:36
void netBufferFree(NetBuffer *buffer)
Dispose a multi-part buffer.
Definition: net_mem.c:282
@ ERROR_INVALID_LENGTH
Definition: error.h:111
#define NetTxAncillary
Definition: net_misc.h:36
@ ICMP_TYPE_ECHO_REQUEST
Definition: icmp.h:57
#define Ipv4PseudoHeader
Definition: ipv4.h:39
#define TRACE_INFO(...)
Definition: debug.h:95
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:297
#define MIN(a, b)
Definition: os_port.h:65
void icmpUpdateInStats(uint8_t type)
Update ICMP input statistics.
Definition: icmp.c:439
@ ICMP_TYPE_INFO_REPLY
Definition: icmp.h:63
#define ntohs(value)
Definition: cpu_endian.h:421
#define TRACE_WARNING(...)
Definition: debug.h:85
#define TRACE_DEBUG(...)
Definition: debug.h:107
@ ICMP_TYPE_DEST_UNREACHABLE
Definition: icmp.h:54
IPv4 and IPv6 common routines.
@ ICMP_TYPE_ECHO_REPLY
Definition: icmp.h:53
IP MIB module.
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
void icmpDumpMessage(const IcmpHeader *message)
Dump ICMP message for debugging purpose.
Definition: icmp.c:593
@ ICMP_TYPE_ADDR_MASK_REPLY
Definition: icmp.h:65
uint8_t message[]
Definition: chap.h:152
error_t ipv4SendDatagram(NetInterface *interface, Ipv4PseudoHeader *pseudoHeader, NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send an IPv4 datagram.
Definition: ipv4.c:977
void icmpProcessMessage(NetInterface *interface, Ipv4PseudoHeader *requestPseudoHeader, const NetBuffer *buffer, size_t offset)
Incoming ICMP message processing.
Definition: icmp.c:111
void icmpUpdateOutStats(uint8_t type)
Update ICMP output statistics.
Definition: icmp.c:514
IPv4 (Internet Protocol Version 4)
#define PRIuSIZE
TCP/IP stack core.
uint8_t ipAddr[4]
Definition: mib_common.h:187
error_t icmpSendErrorMessage(NetInterface *interface, uint8_t type, uint8_t code, uint8_t parameter, const NetBuffer *ipPacket, size_t ipPacketOffset)
Send an ICMP Error message.
Definition: icmp.c:337
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
@ ICMP_TYPE_TIMESTAMP_REQUEST
Definition: icmp.h:60