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-2019 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 1.9.6
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 Incoming ICMP message processing
51  * @param[in] interface Underlying network interface
52  * @param[in] requestPseudoHeader IPv4 pseudo header
53  * @param[in] buffer Multi-part buffer containing the incoming ICMP message
54  * @param[in] offset Offset to the first byte of the ICMP message
55  **/
56 
58  Ipv4PseudoHeader *requestPseudoHeader, const NetBuffer *buffer,
59  size_t offset)
60 {
61  size_t length;
62  IcmpHeader *header;
63 
64  //Total number of ICMP messages which the entity received
65  MIB2_INC_COUNTER32(icmpGroup.icmpInMsgs, 1);
66  IP_MIB_INC_COUNTER32(icmpStats.icmpStatsInMsgs, 1);
67 
68  //Retrieve the length of the ICMP message
69  length = netBufferGetLength(buffer) - offset;
70 
71  //Ensure the message length is correct
72  if(length < sizeof(IcmpHeader))
73  {
74  //Number of ICMP messages which the entity received but determined
75  //as having ICMP-specific errors
76  MIB2_INC_COUNTER32(icmpGroup.icmpInErrors, 1);
77  IP_MIB_INC_COUNTER32(icmpStats.icmpStatsInErrors, 1);
78 
79  //Silently discard incoming message
80  return;
81  }
82 
83  //Point to the ICMP message header
84  header = netBufferAt(buffer, offset);
85  //Sanity check
86  if(header == NULL)
87  return;
88 
89  //Debug message
90  TRACE_INFO("ICMP message received (%" PRIuSIZE " bytes)...\r\n", length);
91  //Dump message contents for debugging purpose
92  icmpDumpMessage(header);
93 
94  //Verify checksum value
95  if(ipCalcChecksumEx(buffer, offset, length) != 0x0000)
96  {
97  //Debug message
98  TRACE_WARNING("Wrong ICMP header checksum!\r\n");
99 
100  //Number of ICMP messages which the entity received but determined
101  //as having ICMP-specific errors
102  MIB2_INC_COUNTER32(icmpGroup.icmpInErrors, 1);
103  IP_MIB_INC_COUNTER32(icmpStats.icmpStatsInErrors, 1);
104 
105  //Drop incoming message
106  return;
107  }
108 
109  //Update ICMP statistics
110  icmpUpdateInStats(header->type);
111 
112  //Check the type of ICMP message
113  switch(header->type)
114  {
115  //Echo Request?
117  //Process Echo Request message
118  icmpProcessEchoRequest(interface, requestPseudoHeader, buffer, offset);
119  break;
120  //Unknown type?
121  default:
122  //Debug message
123  TRACE_WARNING("Unknown ICMP message type!\r\n");
124  //Discard incoming ICMP message
125  break;
126  }
127 }
128 
129 
130 /**
131  * @brief Echo Request message processing
132  * @param[in] interface Underlying network interface
133  * @param[in] requestPseudoHeader IPv4 pseudo header
134  * @param[in] request Multi-part buffer containing the incoming Echo Request message
135  * @param[in] requestOffset Offset to the first byte of the Echo Request message
136  **/
137 
139  Ipv4PseudoHeader *requestPseudoHeader, const NetBuffer *request,
140  size_t requestOffset)
141 {
142  error_t error;
143  size_t requestLength;
144  size_t replyOffset;
145  size_t replyLength;
146  NetBuffer *reply;
147  IcmpEchoMessage *requestHeader;
148  IcmpEchoMessage *replyHeader;
149  Ipv4PseudoHeader replyPseudoHeader;
150 
151  //Retrieve the length of the Echo Request message
152  requestLength = netBufferGetLength(request) - requestOffset;
153 
154  //Ensure the packet length is correct
155  if(requestLength < sizeof(IcmpEchoMessage))
156  return;
157 
158  //Point to the Echo Request header
159  requestHeader = netBufferAt(request, requestOffset);
160  //Sanity check
161  if(requestHeader == NULL)
162  return;
163 
164  //Debug message
165  TRACE_INFO("ICMP Echo Request message received (%" PRIuSIZE " bytes)...\r\n", requestLength);
166  //Dump message contents for debugging purpose
167  icmpDumpEchoMessage(requestHeader);
168 
169  //Check whether the destination address of the Echo Request message is
170  //a broadcast or a multicast address
171  if(ipv4IsBroadcastAddr(interface, requestPseudoHeader->destAddr) ||
172  ipv4IsMulticastAddr(requestPseudoHeader->destAddr))
173  {
175 
176  //If support for broadcast Echo Request messages has been explicitly
177  //disabled, then the host shall not respond to the incoming request
178  if(!interface->ipv4Context.enableBroadcastEchoReq)
179  return;
180 
181  //The source address of the reply must be a unicast address belonging to
182  //the interface on which the broadcast Echo Request message was received
183  error = ipv4SelectSourceAddr(&interface, requestPseudoHeader->srcAddr,
184  &ipAddr);
185  //Any error to report?
186  if(error)
187  return;
188 
189  //Copy the resulting source IP address
190  replyPseudoHeader.srcAddr = ipAddr;
191  }
192  else
193  {
194  //The destination address of the Echo Request message is a unicast address
195  replyPseudoHeader.srcAddr = requestPseudoHeader->destAddr;
196  }
197 
198  //Allocate memory to hold the Echo Reply message
199  reply = ipAllocBuffer(sizeof(IcmpEchoMessage), &replyOffset);
200  //Failed to allocate memory?
201  if(reply == NULL)
202  return;
203 
204  //Point to the Echo Reply header
205  replyHeader = netBufferAt(reply, replyOffset);
206 
207  //Format Echo Reply header
208  replyHeader->type = ICMP_TYPE_ECHO_REPLY;
209  replyHeader->code = 0;
210  replyHeader->checksum = 0;
211  replyHeader->identifier = requestHeader->identifier;
212  replyHeader->sequenceNumber = requestHeader->sequenceNumber;
213 
214  //Point to the first data byte
215  requestOffset += sizeof(IcmpEchoMessage);
216  requestLength -= sizeof(IcmpEchoMessage);
217 
218  //Copy data
219  error = netBufferConcat(reply, request, requestOffset, requestLength);
220 
221  //Check status code
222  if(!error)
223  {
224  //Get the length of the resulting message
225  replyLength = netBufferGetLength(reply) - replyOffset;
226  //Calculate ICMP header checksum
227  replyHeader->checksum = ipCalcChecksumEx(reply, replyOffset, replyLength);
228 
229  //Format IPv4 pseudo header
230  replyPseudoHeader.destAddr = requestPseudoHeader->srcAddr;
231  replyPseudoHeader.reserved = 0;
232  replyPseudoHeader.protocol = IPV4_PROTOCOL_ICMP;
233  replyPseudoHeader.length = htons(replyLength);
234 
235  //Update ICMP statistics
237 
238  //Debug message
239  TRACE_INFO("Sending ICMP Echo Reply message (%" PRIuSIZE " bytes)...\r\n", replyLength);
240  //Dump message contents for debugging purpose
241  icmpDumpEchoMessage(replyHeader);
242 
243  //Send Echo Reply message
244  ipv4SendDatagram(interface, &replyPseudoHeader, reply, replyOffset,
246  }
247 
248  //Free previously allocated memory block
249  netBufferFree(reply);
250 }
251 
252 
253 /**
254  * @brief Send an ICMP Error message
255  * @param[in] interface Underlying network interface
256  * @param[in] type Message type
257  * @param[in] code Specific message code
258  * @param[in] parameter Specific message parameter
259  * @param[in] ipPacket Multi-part buffer that holds the invoking IPv4 packet
260  * @param[in] ipPacketOffset Offset to the first byte of the IPv4 packet
261  * @return Error code
262  **/
263 
264 error_t icmpSendErrorMessage(NetInterface *interface, uint8_t type, uint8_t code,
265  uint8_t parameter, const NetBuffer *ipPacket, size_t ipPacketOffset)
266 {
267  error_t error;
268  size_t offset;
269  size_t length;
270  Ipv4Header *ipHeader;
271  NetBuffer *icmpMessage;
272  IcmpErrorMessage *icmpHeader;
273  Ipv4PseudoHeader pseudoHeader;
274 
275  //Retrieve the length of the invoking IPv4 packet
276  length = netBufferGetLength(ipPacket) - ipPacketOffset;
277 
278  //Check the length of the IPv4 packet
279  if(length < sizeof(Ipv4Header))
280  return ERROR_INVALID_LENGTH;
281 
282  //Point to the header of the invoking packet
283  ipHeader = netBufferAt(ipPacket, ipPacketOffset);
284  //Sanity check
285  if(ipHeader == NULL)
286  return ERROR_FAILURE;
287 
288  //Never respond to a packet destined to a broadcast or a multicast address
289  if(ipv4IsBroadcastAddr(interface, ipHeader->destAddr) ||
290  ipv4IsMulticastAddr(ipHeader->destAddr))
291  {
292  //Report an error
293  return ERROR_INVALID_ADDRESS;
294  }
295 
296  //Length of the data that will be returned along with the ICMP header
297  length = MIN(length, (size_t) ipHeader->headerLength * 4 + 8);
298 
299  //Allocate a memory buffer to hold the ICMP message
300  icmpMessage = ipAllocBuffer(sizeof(IcmpErrorMessage), &offset);
301  //Failed to allocate memory?
302  if(icmpMessage == NULL)
303  return ERROR_OUT_OF_MEMORY;
304 
305  //Point to the ICMP header
306  icmpHeader = netBufferAt(icmpMessage, offset);
307 
308  //Format ICMP message
309  icmpHeader->type = type;
310  icmpHeader->code = code;
311  icmpHeader->checksum = 0;
312  icmpHeader->parameter = parameter;
313  icmpHeader->unused = 0;
314 
315  //Copy the IP header and the first 8 bytes of the original datagram data
316  error = netBufferConcat(icmpMessage, ipPacket, ipPacketOffset, length);
317 
318  //Check status code
319  if(!error)
320  {
321  //Get the length of the resulting message
322  length = netBufferGetLength(icmpMessage) - offset;
323  //Message checksum calculation
324  icmpHeader->checksum = ipCalcChecksumEx(icmpMessage, offset, length);
325 
326  //Format IPv4 pseudo header
327  pseudoHeader.srcAddr = ipHeader->destAddr;
328  pseudoHeader.destAddr = ipHeader->srcAddr;
329  pseudoHeader.reserved = 0;
330  pseudoHeader.protocol = IPV4_PROTOCOL_ICMP;
331  pseudoHeader.length = htons(length);
332 
333  //Update ICMP statistics
335 
336  //Debug message
337  TRACE_INFO("Sending ICMP Error message (%" PRIuSIZE " bytes)...\r\n", length);
338  //Dump message contents for debugging purpose
339  icmpDumpErrorMessage(icmpHeader);
340 
341  //Send ICMP Error message
342  error = ipv4SendDatagram(interface, &pseudoHeader, icmpMessage, offset,
344  }
345 
346  //Free previously allocated memory
347  netBufferFree(icmpMessage);
348 
349  //Return status code
350  return error;
351 }
352 
353 
354 /**
355  * @brief Update ICMP input statistics
356  * @param[in] type ICMP message type
357  **/
358 
359 void icmpUpdateInStats(uint8_t type)
360 {
361  //Check ICMP message type
362  switch(type)
363  {
365  //Number of ICMP Destination Unreachable messages received
366  MIB2_INC_COUNTER32(icmpGroup.icmpInDestUnreachs, 1);
367  break;
369  //Number of ICMP Time Exceeded messages received
370  MIB2_INC_COUNTER32(icmpGroup.icmpInTimeExcds, 1);
371  break;
373  //Number of ICMP Parameter Problem messages received
374  MIB2_INC_COUNTER32(icmpGroup.icmpInParmProbs, 1);
375  break;
377  //Number of ICMP Source Quench messages received
378  MIB2_INC_COUNTER32(icmpGroup.icmpInSrcQuenchs, 1);
379  break;
380  case ICMP_TYPE_REDIRECT:
381  //Number of ICMP Redirect messages received
382  MIB2_INC_COUNTER32(icmpGroup.icmpInRedirects, 1);
383  break;
385  //Number of ICMP Echo Request messages received
386  MIB2_INC_COUNTER32(icmpGroup.icmpInEchos, 1);
387  break;
389  //Number of ICMP Echo Reply messages received
390  MIB2_INC_COUNTER32(icmpGroup.icmpInEchoReps, 1);
391  break;
393  //Number of ICMP Timestamp Request messages received
394  MIB2_INC_COUNTER32(icmpGroup.icmpInTimestamps, 1);
395  break;
397  //Number of ICMP Timestamp Reply messages received
398  MIB2_INC_COUNTER32(icmpGroup.icmpInTimestampReps, 1);
399  break;
401  //Number of ICMP Address Mask Request messages received
402  MIB2_INC_COUNTER32(icmpGroup.icmpInAddrMasks, 1);
403  break;
405  //Number of ICMP Address Mask Reply messages received
406  MIB2_INC_COUNTER32(icmpGroup.icmpInAddrMaskReps, 1);
407  break;
408  default:
409  //Just for sanity
410  break;
411  }
412 
413  //Increment per-message type ICMP counter
414  IP_MIB_INC_COUNTER32(icmpMsgStatsTable.icmpMsgStatsInPkts[type], 1);
415 }
416 
417 
418 /**
419  * @brief Update ICMP output statistics
420  * @param[in] type ICMPv6 message type
421  **/
422 
424 {
425  //Total number of ICMP messages which this entity attempted to send
426  MIB2_INC_COUNTER32(icmpGroup.icmpOutMsgs, 1);
427  IP_MIB_INC_COUNTER32(icmpStats.icmpStatsOutMsgs, 1);
428 
429  //Check ICMP message type
430  switch(type)
431  {
433  //Number of ICMP Destination Unreachable messages sent
434  MIB2_INC_COUNTER32(icmpGroup.icmpOutDestUnreachs, 1);
435  break;
437  //Number of ICMP Time Exceeded messages sent
438  MIB2_INC_COUNTER32(icmpGroup.icmpOutTimeExcds, 1);
439  break;
441  //Number of ICMP Parameter Problem messages sent
442  MIB2_INC_COUNTER32(icmpGroup.icmpOutParmProbs, 1);
443  break;
445  //Number of ICMP Source Quench messages sent
446  MIB2_INC_COUNTER32(icmpGroup.icmpOutSrcQuenchs, 1);
447  break;
448  case ICMP_TYPE_REDIRECT:
449  //Number of ICMP Redirect messages sent
450  MIB2_INC_COUNTER32(icmpGroup.icmpOutRedirects, 1);
451  break;
453  //Number of ICMP Echo Request messages sent
454  MIB2_INC_COUNTER32(icmpGroup.icmpOutEchos, 1);
455  break;
457  //Number of ICMP Echo Reply messages sent
458  MIB2_INC_COUNTER32(icmpGroup.icmpOutEchoReps, 1);
459  break;
461  //Number of ICMP Timestamp Request messages sent
462  MIB2_INC_COUNTER32(icmpGroup.icmpOutTimestamps, 1);
463  break;
465  //Number of ICMP Timestamp Reply messages sent
466  MIB2_INC_COUNTER32(icmpGroup.icmpOutTimestampReps, 1);
467  break;
469  //Number of ICMP Address Mask Request messages sent
470  MIB2_INC_COUNTER32(icmpGroup.icmpOutAddrMasks, 1);
471  break;
473  //Number of ICMP Address Mask Reply messages sent
474  MIB2_INC_COUNTER32(icmpGroup.icmpOutAddrMaskReps, 1);
475  break;
476  default:
477  //Just for sanity
478  break;
479  }
480 
481  //Increment per-message type ICMP counter
482  IP_MIB_INC_COUNTER32(icmpMsgStatsTable.icmpMsgStatsOutPkts[type], 1);
483 }
484 
485 
486 /**
487  * @brief Dump ICMP message for debugging purpose
488  * @param[in] message Pointer to the ICMP message
489  **/
490 
492 {
493  //Dump ICMP message
494  TRACE_DEBUG(" Type = %" PRIu8 "\r\n", message->type);
495  TRACE_DEBUG(" Code = %" PRIu8 "\r\n", message->code);
496  TRACE_DEBUG(" Checksum = 0x%04" PRIX16 "\r\n", ntohs(message->checksum));
497 }
498 
499 
500 /**
501  * @brief Dump ICMP Echo Request or Echo Reply message
502  * @param[in] message Pointer to the ICMP message
503  **/
504 
506 {
507  //Dump ICMP message
508  TRACE_DEBUG(" Type = %" PRIu8 "\r\n", message->type);
509  TRACE_DEBUG(" Code = %" PRIu8 "\r\n", message->code);
510  TRACE_DEBUG(" Checksum = 0x%04" PRIX16 "\r\n", ntohs(message->checksum));
511  TRACE_DEBUG(" Identifier = 0x%04" PRIX16 "\r\n", ntohs(message->identifier));
512  TRACE_DEBUG(" Sequence Number = 0x%04" PRIX16 "\r\n", ntohs(message->sequenceNumber));
513 }
514 
515 
516 /**
517  * @brief Dump generic ICMP Error message
518  * @param[in] message Pointer to the ICMP message
519  **/
520 
522 {
523  //Dump ICMP message
524  TRACE_DEBUG(" Type = %" PRIu8 "\r\n", message->type);
525  TRACE_DEBUG(" Code = %" PRIu8 "\r\n", message->code);
526  TRACE_DEBUG(" Checksum = 0x%04" PRIX16 "\r\n", ntohs(message->checksum));
527  TRACE_DEBUG(" Parameter = %" PRIu8 "\r\n", message->parameter);
528 }
529 
530 #endif
#define ipv4IsMulticastAddr(ipAddr)
Definition: ipv4.h:162
#define htons(value)
Definition: cpu_endian.h:392
MIB-II module.
uint8_t length
Definition: dtls_misc.h:149
NetBuffer * ipAllocBuffer(size_t length, size_t *offset)
Allocate a buffer to hold an IP packet.
Definition: ip.c:637
@ ICMP_TYPE_ADDR_MASK_REQUEST
Definition: icmp.h:64
uint8_t code
Definition: coap_common.h:181
#define Ipv4Header
Definition: ipv4.h:36
void icmpDumpEchoMessage(const IcmpEchoMessage *message)
Dump ICMP Echo Request or Echo Reply message.
Definition: icmp.c:505
@ IPV4_PROTOCOL_ICMP
Definition: ipv4.h:214
uint16_t ipCalcChecksumEx(const NetBuffer *buffer, size_t offset, size_t length)
Calculate IP checksum over a multi-part buffer.
Definition: ip.c:512
#define IP_MIB_INC_COUNTER32(name, value)
Definition: ip_mib_module.h:46
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:88
bool_t ipv4IsBroadcastAddr(NetInterface *interface, Ipv4Addr ipAddr)
Check whether an IPv4 address is a broadcast address.
Definition: ipv4_misc.c:386
void icmpProcessEchoRequest(NetInterface *interface, Ipv4PseudoHeader *requestPseudoHeader, const NetBuffer *request, size_t requestOffset)
Echo Request message processing.
Definition: icmp.c:138
error_t ipv4SendDatagram(NetInterface *interface, Ipv4PseudoHeader *pseudoHeader, NetBuffer *buffer, size_t offset, uint_t flags)
Send an IPv4 datagram.
Definition: ipv4.c:878
__start_packed struct @164 IcmpErrorMessage
ICMP Error message.
error_t ipv4SelectSourceAddr(NetInterface **interface, Ipv4Addr destAddr, Ipv4Addr *srcAddr)
IPv4 source address selection.
Definition: ipv4_misc.c:163
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
@ ICMP_TYPE_TIME_EXCEEDED
Definition: icmp.h:58
@ ICMP_TYPE_PARAM_PROBLEM
Definition: icmp.h:59
uint32_t Ipv4Addr
IPv4 network address.
Definition: ipv4.h:239
uint8_t ipPacket[]
Definition: ndp.h:430
uint32_t parameter
Definition: icmp.h:123
error_t netBufferConcat(NetBuffer *dest, const NetBuffer *src, size_t srcOffset, size_t length)
Concatenate two multi-part buffers.
Definition: net_mem.c:442
Helper functions for IPv4.
void icmpDumpErrorMessage(const IcmpErrorMessage *message)
Dump generic ICMP Error message.
Definition: icmp.c:521
ICMP (Internet Control Message Protocol)
char_t type
error_t
Error codes.
Definition: error.h:42
@ 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:102
@ 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 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:109
@ ICMP_TYPE_ECHO_REQUEST
Definition: icmp.h:57
#define Ipv4PseudoHeader
Definition: ipv4.h:39
#define TRACE_INFO(...)
Definition: debug.h:94
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:62
#define IPV4_DEFAULT_TTL
Definition: ipv4.h:56
void icmpUpdateInStats(uint8_t type)
Update ICMP input statistics.
Definition: icmp.c:359
@ ICMP_TYPE_INFO_REPLY
Definition: icmp.h:63
#define ntohs(value)
Definition: cpu_endian.h:398
#define TRACE_WARNING(...)
Definition: debug.h:84
#define TRACE_DEBUG(...)
Definition: debug.h:106
@ ICMP_TYPE_DEST_UNREACHABLE
Definition: icmp.h:54
__start_packed struct @168 IcmpEchoMessage
ICMP Echo Request and Echo Reply messages.
IPv4 and IPv6 common routines.
@ ICMP_TYPE_ECHO_REPLY
Definition: icmp.h:53
IP MIB module.
#define MIB2_INC_COUNTER32(name, value)
Definition: mib2_module.h:156
void icmpDumpMessage(const IcmpHeader *message)
Dump ICMP message for debugging purpose.
Definition: icmp.c:491
@ ICMP_TYPE_ADDR_MASK_REPLY
Definition: icmp.h:65
uint8_t message[]
Definition: chap.h:152
void icmpProcessMessage(NetInterface *interface, Ipv4PseudoHeader *requestPseudoHeader, const NetBuffer *buffer, size_t offset)
Incoming ICMP message processing.
Definition: icmp.c:57
void icmpUpdateOutStats(uint8_t type)
Update ICMP output statistics.
Definition: icmp.c:423
IPv4 (Internet Protocol Version 4)
#define PRIuSIZE
Definition: compiler_port.h:78
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:264
__start_packed struct @163 IcmpHeader
ICMP header.
Debugging facilities.
@ ICMP_TYPE_TIMESTAMP_REQUEST
Definition: icmp.h:60