PcapPlusPlus  Next
IcmpLayer.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "Layer.h"
4 #include "IPv4Layer.h"
5 #ifdef _MSC_VER
6 # include <winsock2.h>
7 #else
8 # include <sys/time.h>
9 #endif
10 #include <vector>
11 
13 
16 namespace pcpp
17 {
18 
21 #pragma pack(push, 1)
22  typedef struct icmphdr
23  {
25  uint8_t type;
27  uint8_t code;
29  uint16_t checksum;
30  } icmphdr;
31 #pragma pack(pop)
32  static_assert(sizeof(icmphdr) == 4, "icmphdr size is not 4 bytes");
33 
36  {
68  ICMP_UNSUPPORTED = 255
69  };
70 
74  {
110  };
111 
114 #pragma pack(push, 1)
115  typedef struct icmp_echo_hdr : icmphdr
116  {
118  uint16_t id;
120  uint16_t sequence;
122  uint64_t timestamp;
123  } icmp_echo_hdr;
124 #pragma pack(pop)
125  static_assert(sizeof(icmp_echo_hdr) == 16, "icmp_echo_hdr size is not 16 bytes");
126 
129  typedef struct icmp_echo_request
130  {
134  size_t dataLength;
136  uint8_t* data;
138 
142 
145 #pragma pack(push, 1)
147  {
149  uint16_t id;
151  uint16_t sequence;
159 #pragma pack(pop)
160  static_assert(sizeof(icmp_timestamp_request) == 20, "icmp_timestamp_request size is not 20 bytes");
161 
165  static_assert(sizeof(icmp_timestamp_reply) == 20, "icmp_timestamp_reply size is not 20 bytes");
166 
169 #pragma pack(push, 1)
171  {
173  uint16_t unused;
175  uint16_t nextHopMTU;
177 #pragma pack(pop)
178  static_assert(sizeof(icmp_destination_unreachable) == 8, "icmp_destination_unreachable size is not 8 bytes");
179 
182 #pragma pack(push, 1)
183  typedef struct icmp_time_exceeded : icmphdr
184  {
186  uint32_t unused;
188 #pragma pack(pop)
189  static_assert(sizeof(icmp_time_exceeded) == 8, "icmp_time_exceeded size is not 8 bytes");
190 
194  static_assert(sizeof(icmp_source_quench) == 8, "icmp_source_quench size is not 8 bytes");
195 
198 #pragma pack(push, 1)
199  typedef struct icmp_param_problem : icmphdr
200  {
203  uint8_t pointer;
205  uint8_t unused1;
207  uint16_t unused2;
209 #pragma pack(pop)
210  static_assert(sizeof(icmp_param_problem) == 8, "icmp_param_problem size is not 8 bytes");
211 
215  static_assert(sizeof(icmp_router_solicitation) == 4, "icmp_router_solicitation size is not 4 bytes");
216 
219 #pragma pack(push, 1)
220  typedef struct icmp_redirect : icmphdr
221  {
223  uint32_t gatewayAddress;
224  } icmp_redirect;
225 #pragma pack(pop)
226  static_assert(sizeof(icmp_redirect) == 8, "icmp_redirect size is not 8 bytes");
227 
230 #pragma pack(push, 1)
232  {
234  uint32_t routerAddress;
238  uint32_t preferenceLevel;
239 
243  void setRouterAddress(IPv4Address addr, uint32_t preference);
244 
247  {
248  return routerAddress;
249  }
250  };
251 #pragma pack(pop)
252  static_assert(sizeof(icmp_router_address_structure) == 8, "icmp_router_address_structure size is not 8 bytes");
253 
256 #pragma pack(push, 1)
258  {
266  uint16_t lifetime;
268 #pragma pack(pop)
269  static_assert(sizeof(icmp_router_advertisement_hdr) == 8, "icmp_router_advertisement_hdr size is not 8 bytes");
270 
274  {
277 
284  };
285 
288 #pragma pack(push, 1)
290  {
292  uint16_t id;
294  uint16_t sequence;
296  uint32_t addressMask;
298 #pragma pack(pop)
299  static_assert(sizeof(icmp_address_mask_request) == 12, "icmp_address_mask_request size is not 12 bytes");
300 
304 
307 #pragma pack(push, 1)
308  typedef struct icmp_info_request : icmphdr
309  {
311  uint16_t id;
313  uint16_t sequence;
315 #pragma pack(pop)
316  static_assert(sizeof(icmp_info_request) == 8, "icmp_info_request size is not 8 bytes");
317 
321  static_assert(sizeof(icmp_info_reply) == 8, "icmp_info_reply size is not 8 bytes");
322 
325  class IcmpLayer : public Layer
326  {
327  private:
328  icmp_echo_request m_EchoData;
329  mutable icmp_router_advertisement m_RouterAdvData;
330 
331  bool cleanIcmpLayer();
332 
333  bool setEchoData(IcmpMessageType echoType, uint16_t id, uint16_t sequence, uint64_t timestamp,
334  const uint8_t* data, size_t dataLen);
335 
336  bool setIpAndL4Layers(IPv4Layer* ipLayer, Layer* l4Layer);
337 
338  public:
344  // cppcheck-suppress uninitMemberVar
345  IcmpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
346  : Layer(data, dataLen, prevLayer, packet, ICMP)
347  {}
348 
352 
353  ~IcmpLayer() override = default;
354 
359  {
360  return reinterpret_cast<icmphdr*>(m_Data);
361  }
362 
365 
369  {
370  return getMessageType() == type;
371  }
372 
375 
384  icmp_echo_request* setEchoRequestData(uint16_t id, uint16_t sequence, uint64_t timestamp, const uint8_t* data,
385  size_t dataLen);
386 
389 
398  icmp_echo_reply* setEchoReplyData(uint16_t id, uint16_t sequence, uint64_t timestamp, const uint8_t* data,
399  size_t dataLen);
400 
403 
410  icmp_timestamp_request* setTimestampRequestData(uint16_t id, uint16_t sequence, timeval originateTimestamp);
411 
414 
423  icmp_timestamp_reply* setTimestampReplyData(uint16_t id, uint16_t sequence, timeval originateTimestamp,
424  timeval receiveTimestamp, timeval transmitTimestamp);
425 
430 
443  IPv4Layer* ipHeader, Layer* l4Header);
444 
449 
460 
465 
478  icmp_redirect* setRedirectData(uint8_t code, IPv4Address gatewayAddress, IPv4Layer* ipHeader, Layer* l4Header);
479 
483 
493  uint8_t code, uint16_t lifetimeInSeconds,
494  const std::vector<icmp_router_address_structure>& routerAddresses);
495 
499 
505 
510 
522  icmp_time_exceeded* setTimeExceededData(uint8_t code, IPv4Layer* ipHeader, Layer* l4Header);
523 
526 
540  icmp_param_problem* setParamProblemData(uint8_t code, uint8_t errorOctetPointer, IPv4Layer* ipHeader,
541  Layer* l4Header);
542 
546 
553  icmp_address_mask_request* setAddressMaskRequestData(uint16_t id, uint16_t sequence, IPv4Address mask);
554 
557 
564  icmp_address_mask_reply* setAddressMaskReplyData(uint16_t id, uint16_t sequence, IPv4Address mask);
565 
569 
575  icmp_info_request* setInfoRequestData(uint16_t id, uint16_t sequence);
576 
580 
586  icmp_info_reply* setInfoReplyData(uint16_t id, uint16_t sequence);
587 
592  static inline bool isDataValid(const uint8_t* data, size_t dataLen);
593 
594  // implement abstract methods
595 
599  void parseNextLayer() override;
600 
604  size_t getHeaderLen() const override;
605 
607  void computeCalculateFields() override;
608 
609  std::string toString() const override;
610 
612  {
613  return OsiModelNetworkLayer;
614  }
615  };
616 
617  // implementation of inline methods
618 
619  bool IcmpLayer::isDataValid(const uint8_t* data, size_t dataLen)
620  {
621  if (dataLen < sizeof(icmphdr))
622  return false;
623 
624  uint8_t type = data[0];
625 
626  // ICMP_ECHO_REQUEST, ICMP_ECHO_REPLY, ICMP_ROUTER_SOL, ICMP_INFO_REQUEST, ICMP_INFO_REPLY
627  if (type == 8 || type == 0 || type == 10 || type == 15 || type == 16)
628  return true;
629 
630  // ICMP_TIMESTAMP_REQUEST, ICMP_TIMESTAMP_REPLY
631  if (type == 13 || type == 14)
632  return dataLen >= sizeof(icmp_timestamp_request);
633 
634  // ICMP_ADDRESS_MASK_REPLY, ICMP_ADDRESS_MASK_REQUEST
635  if (type == 17 || type == 18)
636  return dataLen >= sizeof(icmp_address_mask_request);
637 
638  // ICMP_DEST_UNREACHABLE
639  if (type == 3)
640  return dataLen >= sizeof(icmp_destination_unreachable);
641 
642  // ICMP_REDIRECT
643  if (type == 5)
644  return dataLen >= sizeof(icmp_redirect);
645 
646  // ICMP_TIME_EXCEEDED, ICMP_SOURCE_QUENCH
647  if (type == 4 || type == 11)
648  return dataLen >= sizeof(icmp_time_exceeded);
649 
650  // ICMP_PARAM_PROBLEM
651  if (type == 12)
652  return dataLen >= sizeof(icmp_param_problem);
653 
654  // ICMP_ROUTER_ADV
655  if (type == 9)
656  return dataLen >= sizeof(icmp_router_advertisement_hdr);
657 
658  return false;
659  }
660 
661 } // namespace pcpp
Definition: IpAddress.h:28
Definition: IPv4Layer.h:408
Definition: IcmpLayer.h:326
icmp_router_solicitation * getRouterSolicitationData()
icmp_address_mask_request * setAddressMaskRequestData(uint16_t id, uint16_t sequence, IPv4Address mask)
icmp_echo_request * getEchoRequestData()
icmp_info_reply * getInfoReplyData()
icmp_info_request * setInfoRequestData(uint16_t id, uint16_t sequence)
icmp_echo_reply * getEchoReplyData()
size_t getHeaderLen() const override
icmp_source_quench * getSourceQuenchdata()
icmp_echo_reply * setEchoReplyData(uint16_t id, uint16_t sequence, uint64_t timestamp, const uint8_t *data, size_t dataLen)
icmp_echo_request * setEchoRequestData(uint16_t id, uint16_t sequence, uint64_t timestamp, const uint8_t *data, size_t dataLen)
IcmpLayer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet)
Definition: IcmpLayer.h:345
icmp_router_solicitation * setRouterSolicitationData()
icmp_address_mask_reply * setAddressMaskReplyData(uint16_t id, uint16_t sequence, IPv4Address mask)
icmp_router_advertisement * setRouterAdvertisementData(uint8_t code, uint16_t lifetimeInSeconds, const std::vector< icmp_router_address_structure > &routerAddresses)
icmp_redirect * getRedirectData()
icmp_address_mask_request * getAddressMaskRequestData()
icmp_address_mask_reply * getAddressMaskReplyData()
icmp_timestamp_request * getTimestampRequestData()
bool isMessageOfType(IcmpMessageType type) const
Definition: IcmpLayer.h:368
icmp_redirect * setRedirectData(uint8_t code, IPv4Address gatewayAddress, IPv4Layer *ipHeader, Layer *l4Header)
icmp_timestamp_reply * getTimestampReplyData()
icmp_destination_unreachable * setDestUnreachableData(IcmpDestUnreachableCodes code, uint16_t nextHopMTU, IPv4Layer *ipHeader, Layer *l4Header)
icmphdr * getIcmpHeader() const
Definition: IcmpLayer.h:358
icmp_timestamp_request * setTimestampRequestData(uint16_t id, uint16_t sequence, timeval originateTimestamp)
icmp_router_advertisement * getRouterAdvertisementData() const
icmp_info_request * getInfoRequestData()
icmp_destination_unreachable * getDestUnreachableData()
icmp_time_exceeded * setTimeExceededData(uint8_t code, IPv4Layer *ipHeader, Layer *l4Header)
static bool isDataValid(const uint8_t *data, size_t dataLen)
Definition: IcmpLayer.h:619
icmp_param_problem * setParamProblemData(uint8_t code, uint8_t errorOctetPointer, IPv4Layer *ipHeader, Layer *l4Header)
void parseNextLayer() override
icmp_time_exceeded * getTimeExceededData()
icmp_param_problem * getParamProblemData()
void computeCalculateFields() override
Calculate ICMP checksum field.
icmp_timestamp_reply * setTimestampReplyData(uint16_t id, uint16_t sequence, timeval originateTimestamp, timeval receiveTimestamp, timeval transmitTimestamp)
icmp_info_reply * setInfoReplyData(uint16_t id, uint16_t sequence)
std::string toString() const override
IcmpMessageType getMessageType() const
icmp_source_quench * setSourceQuenchdata(IPv4Layer *ipHeader, Layer *l4Header)
OsiModelLayer getOsiModelLayer() const override
Definition: IcmpLayer.h:611
Definition: Layer.h:60
Definition: Packet.h:22
The main namespace for the PcapPlusPlus lib.
icmp_address_mask_request icmp_address_mask_reply
Definition: IcmpLayer.h:303
icmphdr icmp_router_solicitation
Definition: IcmpLayer.h:214
icmp_info_request icmp_info_reply
Definition: IcmpLayer.h:320
IcmpMessageType
An enum of all supported ICMP message types.
Definition: IcmpLayer.h:36
@ ICMP_DEST_UNREACHABLE
ICMP destination unreachable message.
Definition: IcmpLayer.h:40
@ ICMP_TIMESTAMP_REPLY
ICMP timestamp reply message.
Definition: IcmpLayer.h:58
@ ICMP_TIME_EXCEEDED
ICMP time-to-live excceded message.
Definition: IcmpLayer.h:52
@ ICMP_ECHO_REQUEST
ICMP echo (ping) request message.
Definition: IcmpLayer.h:46
@ ICMP_TIMESTAMP_REQUEST
ICMP timestamp request message.
Definition: IcmpLayer.h:56
@ ICMP_UNSUPPORTED
ICMP message type unsupported by PcapPlusPlus.
Definition: IcmpLayer.h:68
@ ICMP_PARAM_PROBLEM
ICMP parameter problem message.
Definition: IcmpLayer.h:54
@ ICMP_ADDRESS_MASK_REPLY
ICMP address mask reply message.
Definition: IcmpLayer.h:66
@ ICMP_ROUTER_SOL
ICMP router soliciatation message.
Definition: IcmpLayer.h:50
@ ICMP_ECHO_REPLY
ICMP echo (ping) reply message.
Definition: IcmpLayer.h:38
@ ICMP_INFO_REQUEST
ICMP information request message.
Definition: IcmpLayer.h:60
@ ICMP_ADDRESS_MASK_REQUEST
ICMP address mask request message.
Definition: IcmpLayer.h:64
@ ICMP_SOURCE_QUENCH
ICMP source quench message.
Definition: IcmpLayer.h:42
@ ICMP_REDIRECT
ICMP redirect message.
Definition: IcmpLayer.h:44
@ ICMP_ROUTER_ADV
ICMP router advertisement message.
Definition: IcmpLayer.h:48
@ ICMP_INFO_REPLY
ICMP information reply message.
Definition: IcmpLayer.h:62
OsiModelLayer
An enum representing OSI model layers.
Definition: ProtocolType.h:225
@ OsiModelNetworkLayer
Network layer (layer 3)
Definition: ProtocolType.h:231
icmp_timestamp_request icmp_timestamp_reply
Definition: IcmpLayer.h:164
icmp_time_exceeded icmp_source_quench
Definition: IcmpLayer.h:193
IcmpDestUnreachableCodes
Definition: IcmpLayer.h:74
@ IcmpDestinationNetworkProhibited
The destination network is administratively prohibited.
Definition: IcmpLayer.h:94
@ IcmpSourceHostIsolated
Source host isolated error.
Definition: IcmpLayer.h:92
@ IcmpPrecedenceCutoff
Definition: IcmpLayer.h:109
@ IcmpHostPrecedenceViolation
Definition: IcmpLayer.h:106
@ IcmpPortUnreachable
Port unreachable error (the designated protocol is unable to inform the host of the incoming message)
Definition: IcmpLayer.h:82
@ IcmpSourceRouteFailed
Source route failed error.
Definition: IcmpLayer.h:86
@ IcmpHostUnreachableForTypeOfService
The host is unreachable for Type Of Service.
Definition: IcmpLayer.h:100
@ IcmpDestinationHostProhibited
The destination host is administratively prohibited.
Definition: IcmpLayer.h:96
@ IcmpDestinationHostUnknown
Destination host unknown error.
Definition: IcmpLayer.h:90
@ IcmpProtocolUnreachable
Protocol unreachable error (the designated transport protocol is not supported)
Definition: IcmpLayer.h:80
@ IcmpCommunicationProhibited
Definition: IcmpLayer.h:103
@ IcmpDestinationNetworkUnknown
Destination network unknown error.
Definition: IcmpLayer.h:88
@ IcmpNetworkUnreachable
Network unreachable error.
Definition: IcmpLayer.h:76
@ IcmpNetworkUnreachableForTypeOfService
The network is unreachable for Type Of Service.
Definition: IcmpLayer.h:98
@ IcmpHostUnreachable
Host unreachable error.
Definition: IcmpLayer.h:78
@ IcmpDatagramTooBig
The datagram is too big. Packet fragmentation is required but the 'don't fragment' (DF) flag is on.
Definition: IcmpLayer.h:84
const ProtocolType ICMP
ICMP protocol.
Definition: ProtocolType.h:56
icmp_echo_request icmp_echo_reply
Definition: IcmpLayer.h:141
Definition: IcmpLayer.h:290
uint16_t id
the address mask request identifier
Definition: IcmpLayer.h:292
uint16_t sequence
the address mask request sequence
Definition: IcmpLayer.h:294
uint32_t addressMask
the subnet mask of the requesting host
Definition: IcmpLayer.h:296
Definition: IcmpLayer.h:171
uint16_t unused
unused 2 bytes
Definition: IcmpLayer.h:173
uint16_t nextHopMTU
contains the MTU of the next-hop network if a code 4 error occurs
Definition: IcmpLayer.h:175
Definition: IcmpLayer.h:116
uint64_t timestamp
a timestamp of when the message was sent
Definition: IcmpLayer.h:122
uint16_t id
the echo (ping) request identifier
Definition: IcmpLayer.h:118
uint16_t sequence
the echo (ping) request sequence number
Definition: IcmpLayer.h:120
Definition: IcmpLayer.h:130
icmp_echo_hdr * header
a pointer to the header data
Definition: IcmpLayer.h:132
size_t dataLength
most echo requests/replies contain some payload data. This is the data length
Definition: IcmpLayer.h:134
uint8_t * data
most echo requests/replies contain some payload data. This is a pointer to this data
Definition: IcmpLayer.h:136
Definition: IcmpLayer.h:309
uint16_t sequence
the information request sequence
Definition: IcmpLayer.h:313
uint16_t id
the information request identifier
Definition: IcmpLayer.h:311
Definition: IcmpLayer.h:200
uint8_t unused1
unused 1 byte
Definition: IcmpLayer.h:205
uint8_t pointer
Definition: IcmpLayer.h:203
uint16_t unused2
unused 2 bytes
Definition: IcmpLayer.h:207
Definition: IcmpLayer.h:221
uint32_t gatewayAddress
an IPv4 address of the gateway to which the redirection should be sent
Definition: IcmpLayer.h:223
Definition: IcmpLayer.h:232
void setRouterAddress(IPv4Address addr, uint32_t preference)
uint32_t routerAddress
the IPv4 address of the advertised router
Definition: IcmpLayer.h:234
IPv4Address getAddress() const
Definition: IcmpLayer.h:246
uint32_t preferenceLevel
Definition: IcmpLayer.h:238
Definition: IcmpLayer.h:258
uint8_t addressEntrySize
Definition: IcmpLayer.h:264
uint16_t lifetime
the maximum number of seconds that the router addresses in this list may be considered valid
Definition: IcmpLayer.h:266
uint8_t advertisementCount
Definition: IcmpLayer.h:261
Definition: IcmpLayer.h:274
icmp_router_advertisement_hdr * header
a pointer to the header data on the packet
Definition: IcmpLayer.h:276
icmp_router_address_structure * getRouterAddress(int index) const
Definition: IcmpLayer.h:184
uint32_t unused
unused 4 bytes
Definition: IcmpLayer.h:186
Definition: IcmpLayer.h:147
uint16_t id
the timestamp request identifier
Definition: IcmpLayer.h:149
uint32_t transmitTimestamp
relevant for timestamp reply only - the time the echoer last touched the message on sending it
Definition: IcmpLayer.h:157
uint16_t sequence
the timestamp request sequence number
Definition: IcmpLayer.h:151
uint32_t receiveTimestamp
relevant for timestamp reply only - the time the echoer first touched it on receipt
Definition: IcmpLayer.h:155
uint32_t originateTimestamp
the time (in milliseconds since midnight) the sender last touched the packet
Definition: IcmpLayer.h:153
Definition: IcmpLayer.h:23
uint8_t code
message code
Definition: IcmpLayer.h:27
uint8_t type
message type
Definition: IcmpLayer.h:25
uint16_t checksum
message checksum
Definition: IcmpLayer.h:29