PcapPlusPlus  Next
IPv4Layer.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "Layer.h"
4 #include "TLVData.h"
5 #include "IpAddress.h"
6 #include "IPLayer.h"
7 #include <string.h>
8 #include <vector>
9 
11 
14 namespace pcpp
15 {
18 #pragma pack(push, 1)
19  struct iphdr
20  {
21 #if (BYTE_ORDER == LITTLE_ENDIAN)
23  uint8_t internetHeaderLength : 4,
25  ipVersion : 4;
26 #else
28  uint8_t ipVersion : 4,
31 #endif
33  uint8_t typeOfService;
35  uint16_t totalLength;
38  uint16_t ipId;
40  uint16_t fragmentOffset;
43  uint8_t timeToLive;
45  uint8_t protocol;
47  uint16_t headerChecksum;
49  uint32_t ipSrc;
51  uint32_t ipDst;
52  // The options start here.
53  };
54 #pragma pack(pop)
55  static_assert(sizeof(iphdr) == 20, "iphdr size is not 20 bytes");
56 
59  {
104  };
105 
108  {
151  };
152 
153 #define PCPP_IP_DONT_FRAGMENT 0x40
154 #define PCPP_IP_MORE_FRAGMENTS 0x20
155 
160  {
163  {
171  Unknown = 3
172  };
173 
176 
178  std::vector<uint32_t> timestamps;
179 
181  std::vector<IPv4Address> ipAddresses;
182 
185  {}
186 
189  void clear()
190  {
192  timestamps.clear();
193  ipAddresses.clear();
194  }
195  };
196 
200  class IPv4Option : public TLVRecord<uint8_t, uint8_t>
201  {
202  public:
205  explicit IPv4Option(uint8_t* optionRawData) : TLVRecord(optionRawData)
206  {}
207 
209  ~IPv4Option() override = default;
210 
217  std::vector<IPv4Address> getValueAsIpList() const
218  {
219  std::vector<IPv4Address> res;
220 
221  if (m_Data == nullptr)
222  return res;
223 
224  size_t dataSize = getDataSize();
225  if (dataSize < 2)
226  return res;
227 
228  uint8_t valueOffset = static_cast<uint8_t>(1);
229 
230  while (static_cast<size_t>(valueOffset) < dataSize)
231  {
232  uint32_t curValue;
233  memcpy(&curValue, m_Data->recordValue + valueOffset, sizeof(uint32_t));
234  if (curValue == 0)
235  break;
236 
237  res.push_back(IPv4Address(curValue));
238 
239  valueOffset += static_cast<uint8_t>(4);
240  }
241 
242  return res;
243  }
244 
253  {
255  res.clear();
256 
257  if (m_Data == nullptr)
258  return res;
259 
261  return res;
262 
263  size_t dataSize = getDataSize();
264  if (dataSize < 2)
265  return res;
266 
267  res.type = static_cast<IPv4TimestampOptionValue::TimestampType>(m_Data->recordValue[1]);
268 
269  uint8_t valueOffset = static_cast<uint8_t>(2);
270  bool readIPAddr = (res.type == IPv4TimestampOptionValue::TimestampAndIP);
271 
272  while (static_cast<size_t>(valueOffset) < dataSize)
273  {
274  uint32_t curValue;
275  memcpy(&curValue, m_Data->recordValue + valueOffset, sizeof(uint32_t));
276  if (curValue == 0)
277  break;
278 
279  if (readIPAddr)
280  res.ipAddresses.push_back(IPv4Address(curValue));
281  else
282  res.timestamps.push_back(curValue);
283 
285  readIPAddr = !readIPAddr;
286 
287  valueOffset += static_cast<uint8_t>(4);
288  }
289 
290  return res;
291  }
292 
295  {
296  return getIPv4OptionType(m_Data);
297  }
298 
303  static bool canAssign(const uint8_t* recordRawData, size_t tlvDataLen)
304  {
305  auto data = reinterpret_cast<TLVRawData const*>(recordRawData);
306  if (data == nullptr)
307  return false;
308 
309  if (tlvDataLen < sizeof(TLVRawData::recordType))
310  return false;
311 
312  if (getIPv4OptionType(data) == static_cast<uint8_t>(IPV4OPT_EndOfOptionsList) ||
313  data->recordType == static_cast<uint8_t>(IPV4OPT_NOP))
314  return true;
315 
316  return TLVRecord<uint8_t, uint8_t>::canAssign(recordRawData, tlvDataLen);
317  }
318 
319  // implement abstract methods
320 
321  size_t getTotalSize() const override
322  {
323  if (m_Data == nullptr)
324  return 0;
325 
326  if (getIPv4OptionType() == static_cast<uint8_t>(IPV4OPT_EndOfOptionsList) ||
327  m_Data->recordType == static_cast<uint8_t>(IPV4OPT_NOP))
328  return sizeof(uint8_t);
329 
330  return static_cast<size_t>(m_Data->recordLen);
331  }
332 
333  size_t getDataSize() const override
334  {
335  if (m_Data == nullptr)
336  return 0;
337 
338  if (getIPv4OptionType() == static_cast<uint8_t>(IPV4OPT_EndOfOptionsList) ||
339  m_Data->recordType == static_cast<uint8_t>(IPV4OPT_NOP))
340  return 0;
341 
342  return static_cast<size_t>(m_Data->recordLen) - (2 * sizeof(uint8_t));
343  }
344 
345  private:
347  static IPv4OptionTypes getIPv4OptionType(const TLVRawData* data)
348  {
349  if (data == nullptr)
350  return IPV4OPT_Unknown;
351 
352  return static_cast<IPv4OptionTypes>(data->recordType);
353  }
354  };
355 
360  {
361  private:
362  bool m_BuilderParamsValid;
363 
364  public:
372  IPv4OptionBuilder(IPv4OptionTypes optionType, const uint8_t* optionValue, uint8_t optionValueLen)
373  : TLVRecordBuilder((uint8_t)optionType, optionValue, optionValueLen)
374  {
375  m_BuilderParamsValid = true;
376  }
377 
382  IPv4OptionBuilder(IPv4OptionTypes optionType, uint16_t optionValue)
383  : TLVRecordBuilder((uint8_t)optionType, optionValue)
384  {
385  m_BuilderParamsValid = true;
386  }
387 
393  IPv4OptionBuilder(IPv4OptionTypes optionType, const std::vector<IPv4Address>& ipList);
394 
398  explicit IPv4OptionBuilder(const IPv4TimestampOptionValue& timestampValue);
399 
402  IPv4Option build() const;
403  };
404 
407  class IPv4Layer : public Layer, public IPLayer
408  {
409  public:
415  IPv4Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
416 
427  IPv4Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet, bool setTotalLenAsDataLen);
428 
431 
435  IPv4Layer(const IPv4Address& srcIP, const IPv4Address& dstIP);
436 
438  IPv4Layer(const IPv4Layer& other);
439 
442  IPv4Layer& operator=(const IPv4Layer& other);
443 
448  {
449  return reinterpret_cast<iphdr*>(m_Data);
450  }
451 
455  IPAddress getSrcIPAddress() const override
456  {
457  return getSrcIPv4Address();
458  }
459 
463  {
464  return getIPv4Header()->ipSrc;
465  }
466 
469  void setSrcIPv4Address(const IPv4Address& ipAddr)
470  {
471  getIPv4Header()->ipSrc = ipAddr.toInt();
472  }
473 
477  IPAddress getDstIPAddress() const override
478  {
479  return getDstIPv4Address();
480  }
481 
485  {
486  return getIPv4Header()->ipDst;
487  }
488 
491  void setDstIPv4Address(const IPv4Address& ipAddr)
492  {
493  getIPv4Header()->ipDst = ipAddr.toInt();
494  }
495 
497  bool isFragment() const;
498 
501  bool isFirstFragment() const;
502 
505  bool isLastFragment() const;
506 
508  uint8_t getFragmentFlags() const;
509 
511  uint16_t getFragmentOffset() const;
512 
518 
522 
530 
532  size_t getOptionCount() const;
533 
539  IPv4Option addOption(const IPv4OptionBuilder& optionBuilder);
540 
551  IPv4OptionTypes prevOptionType = IPV4OPT_Unknown);
552 
558 
563 
564  // implement abstract methods
565 
578  void parseNextLayer() override;
579 
581  size_t getHeaderLen() const override
582  {
583  return static_cast<size_t>(static_cast<uint16_t>(getIPv4Header()->internetHeaderLength) * 4) +
584  m_TempHeaderExtension;
585  }
586 
593  void computeCalculateFields() override;
594 
595  std::string toString() const override;
596 
598  {
599  return OsiModelNetworkLayer;
600  }
601 
606  static inline bool isDataValid(const uint8_t* data, size_t dataLen);
607 
608  private:
609  int m_NumOfTrailingBytes;
610  int m_TempHeaderExtension;
611  TLVRecordReader<IPv4Option> m_OptionReader;
612 
613  void copyLayerData(const IPv4Layer& other);
614  uint8_t* getOptionsBasePtr() const
615  {
616  return m_Data + sizeof(iphdr);
617  }
618  IPv4Option addOptionAt(const IPv4OptionBuilder& optionBuilder, int offset);
619  void adjustOptionsTrailer(size_t totalOptSize);
620  void initLayer();
621  void initLayerInPacket(bool setTotalLenAsDataLen);
622  };
623 
624  // implementation of inline methods
625 
626  bool IPv4Layer::isDataValid(const uint8_t* data, size_t dataLen)
627  {
628  const iphdr* hdr = reinterpret_cast<const iphdr*>(data);
629  return dataLen >= sizeof(iphdr) && hdr->ipVersion == 4 && hdr->internetHeaderLength >= 5;
630  }
631 
632 } // namespace pcpp
Definition: IpAddress.h:276
Definition: IPLayer.h:18
Definition: IpAddress.h:28
uint32_t toInt() const
Definition: IpAddress.h:146
Definition: IPv4Layer.h:408
bool removeAllOptions()
IPv4Option getNextOption(IPv4Option &option) const
iphdr * getIPv4Header() const
Definition: IPv4Layer.h:447
size_t getHeaderLen() const override
Definition: IPv4Layer.h:581
IPv4Layer()
A constructor that allocates a new IPv4 header with empty fields.
uint8_t getFragmentFlags() const
IPv4Address getSrcIPv4Address() const
Definition: IPv4Layer.h:462
IPAddress getDstIPAddress() const override
Definition: IPv4Layer.h:477
IPAddress getSrcIPAddress() const override
Definition: IPv4Layer.h:455
void parseNextLayer() override
static bool isDataValid(const uint8_t *data, size_t dataLen)
Definition: IPv4Layer.h:626
IPv4Option addOption(const IPv4OptionBuilder &optionBuilder)
IPv4Layer(const IPv4Address &srcIP, const IPv4Address &dstIP)
IPv4Layer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet)
IPv4Option getOption(IPv4OptionTypes option) const
bool isFragment() const
void setDstIPv4Address(const IPv4Address &ipAddr)
Definition: IPv4Layer.h:491
void setSrcIPv4Address(const IPv4Address &ipAddr)
Definition: IPv4Layer.h:469
IPv4Layer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet, bool setTotalLenAsDataLen)
void computeCalculateFields() override
OsiModelLayer getOsiModelLayer() const override
Definition: IPv4Layer.h:597
bool isLastFragment() const
IPv4Layer & operator=(const IPv4Layer &other)
IPv4Address getDstIPv4Address() const
Definition: IPv4Layer.h:484
IPv4Layer(const IPv4Layer &other)
A copy constructor that copy the entire header from the other IPv4Layer (including IPv4 options)
size_t getOptionCount() const
IPv4Option addOptionAfter(const IPv4OptionBuilder &optionBuilder, IPv4OptionTypes prevOptionType=IPV4OPT_Unknown)
IPv4Option getFirstOption() const
bool removeOption(IPv4OptionTypes option)
uint16_t getFragmentOffset() const
bool isFirstFragment() const
std::string toString() const override
Definition: IPv4Layer.h:360
IPv4OptionBuilder(IPv4OptionTypes optionType, const uint8_t *optionValue, uint8_t optionValueLen)
Definition: IPv4Layer.h:372
IPv4OptionBuilder(IPv4OptionTypes optionType, uint16_t optionValue)
Definition: IPv4Layer.h:382
IPv4OptionBuilder(const IPv4TimestampOptionValue &timestampValue)
IPv4Option build() const
IPv4OptionBuilder(IPv4OptionTypes optionType, const std::vector< IPv4Address > &ipList)
Definition: IPv4Layer.h:201
IPv4Option(uint8_t *optionRawData)
Definition: IPv4Layer.h:205
std::vector< IPv4Address > getValueAsIpList() const
Definition: IPv4Layer.h:217
~IPv4Option() override=default
A d'tor for this class, currently does nothing.
IPv4OptionTypes getIPv4OptionType() const
Definition: IPv4Layer.h:294
size_t getDataSize() const override
Definition: IPv4Layer.h:333
size_t getTotalSize() const override
Definition: IPv4Layer.h:321
static bool canAssign(const uint8_t *recordRawData, size_t tlvDataLen)
Definition: IPv4Layer.h:303
IPv4TimestampOptionValue getTimestampOptionValue() const
Definition: IPv4Layer.h:252
Definition: Layer.h:60
Definition: Packet.h:22
Definition: TLVData.h:357
Definition: TLVData.h:19
static bool canAssign(const uint8_t *recordRawData, size_t tlvDataLen)
Definition: TLVData.h:66
Definition: TLVData.h:204
The main namespace for the PcapPlusPlus lib.
IPv4OptionTypes
An enum for supported IPv4 option types.
Definition: IPv4Layer.h:108
@ IPV4OPT_MTUReply
MTU Reply.
Definition: IPv4Layer.h:118
@ IPV4OPT_QuickStart
Quick-Start.
Definition: IPv4Layer.h:120
@ IPV4OPT_LooseSourceRoute
Loose Source Route.
Definition: IPv4Layer.h:128
@ IPV4OPT_Traceroute
Traceroute.
Definition: IPv4Layer.h:124
@ IPV4OPT_NOP
No Operation.
Definition: IPv4Layer.h:112
@ IPV4OPT_UpstreamMulticastPkt
Upstream Multicast Pkt.
Definition: IPv4Layer.h:148
@ IPV4OPT_DynamicPacketState
Dynamic Packet State.
Definition: IPv4Layer.h:146
@ IPV4OPT_EndOfOptionsList
End of Options List.
Definition: IPv4Layer.h:110
@ IPV4OPT_ExtendedSecurity
Extended Security.
Definition: IPv4Layer.h:130
@ IPV4OPT_RouterAlert
Router Alert.
Definition: IPv4Layer.h:142
@ IPV4OPT_SelectiveDirectedBroadcast
Selective Directed Broadcast.
Definition: IPv4Layer.h:144
@ IPV4OPT_Security
Security.
Definition: IPv4Layer.h:126
@ IPV4OPT_Timestamp
Timestamp.
Definition: IPv4Layer.h:122
@ IPV4OPT_Unknown
Unknown IPv4 option.
Definition: IPv4Layer.h:150
@ IPV4OPT_AddressExtension
Address Extension.
Definition: IPv4Layer.h:140
@ IPV4OPT_CommercialSecurity
Commercial Security.
Definition: IPv4Layer.h:132
@ IPV4OPT_MTUProbe
MTU Probe.
Definition: IPv4Layer.h:116
@ IPV4OPT_StrictSourceRoute
Strict Source Route.
Definition: IPv4Layer.h:136
@ IPV4OPT_ExtendedInternetProtocol
Extended Internet Protocol.
Definition: IPv4Layer.h:138
@ IPV4OPT_StreamID
Stream ID.
Definition: IPv4Layer.h:134
@ IPV4OPT_RecordRoute
Record Route.
Definition: IPv4Layer.h:114
OsiModelLayer
An enum representing OSI model layers.
Definition: ProtocolType.h:225
@ OsiModelNetworkLayer
Network layer (layer 3)
Definition: ProtocolType.h:231
IPProtocolTypes
An enum for all possible IPv4 and IPv6 protocol types.
Definition: IPv4Layer.h:59
@ PACKETPP_IPPROTO_ROUTING
IPv6 Routing header.
Definition: IPv4Layer.h:83
@ PACKETPP_IPPROTO_AH
authentication header
Definition: IPv4Layer.h:91
@ PACKETPP_IPPROTO_ICMP
Internet Control Message Protocol.
Definition: IPv4Layer.h:65
@ PACKETPP_IPPROTO_IPIP
IPIP tunnels (older KA9Q tunnels use 94)
Definition: IPv4Layer.h:69
@ PACKETPP_IPPROTO_FRAGMENT
IPv6 fragmentation header.
Definition: IPv4Layer.h:85
@ PACKETPP_IPPROTO_UDP
User Datagram Protocol.
Definition: IPv4Layer.h:77
@ PACKETPP_IPPROTO_IP
Dummy protocol for TCP.
Definition: IPv4Layer.h:61
@ PACKETPP_IPPROTO_ESP
encapsulating security payload
Definition: IPv4Layer.h:89
@ PACKETPP_IPPROTO_IGMP
Internet Gateway Management Protocol.
Definition: IPv4Layer.h:67
@ PACKETPP_IPPROTO_GRE
GRE protocol.
Definition: IPv4Layer.h:87
@ PACKETPP_IPPROTO_TCP
Transmission Control Protocol.
Definition: IPv4Layer.h:71
@ PACKETPP_IPPROTO_ICMPV6
ICMPv6.
Definition: IPv4Layer.h:93
@ PACKETPP_IPPROTO_PUP
PUP protocol.
Definition: IPv4Layer.h:75
@ PACKETPP_IPPROTO_VRRP
VRRP protocol.
Definition: IPv4Layer.h:99
@ PACKETPP_IPPROTO_IDP
XNS IDP protocol.
Definition: IPv4Layer.h:79
@ PACKETPP_IPPROTO_EGP
Exterior Gateway Protocol.
Definition: IPv4Layer.h:73
@ PACKETPP_IPPROTO_HOPOPTS
IPv6 Hop-by-Hop options.
Definition: IPv4Layer.h:63
@ PACKETPP_IPPROTO_DSTOPTS
IPv6 Destination options.
Definition: IPv4Layer.h:97
@ PACKETPP_IPPROTO_RAW
Raw IP packets.
Definition: IPv4Layer.h:101
@ PACKETPP_IPPROTO_NONE
IPv6 no next header.
Definition: IPv4Layer.h:95
@ PACKETPP_IPPROTO_MAX
Maximum value.
Definition: IPv4Layer.h:103
@ PACKETPP_IPPROTO_IPV6
IPv6 header.
Definition: IPv4Layer.h:81
Definition: IPv4Layer.h:160
TimestampType type
The timestamp value type.
Definition: IPv4Layer.h:175
std::vector< IPv4Address > ipAddresses
A list of IPv4 addresses parsed from the IPv4 timestamp option value.
Definition: IPv4Layer.h:181
TimestampType
An enum for IPv4 timestamp option types.
Definition: IPv4Layer.h:163
@ Unknown
Invalid or unknown value type.
Definition: IPv4Layer.h:171
@ TimestampsForPrespecifiedIPs
The IPv4 addresses are prespecified.
Definition: IPv4Layer.h:169
@ TimestampAndIP
Value containing both timestamps and IPv4 addresses.
Definition: IPv4Layer.h:167
@ TimestampOnly
Value containing only timestamps.
Definition: IPv4Layer.h:165
std::vector< uint32_t > timestamps
A list of timestamps parsed from the IPv4 timestamp option value.
Definition: IPv4Layer.h:178
void clear()
Definition: IPv4Layer.h:189
IPv4TimestampOptionValue()
The default constructor.
Definition: IPv4Layer.h:184
Definition: IPv4Layer.h:20
uint8_t typeOfService
type of service, same as Differentiated Services Code Point (DSCP)
Definition: IPv4Layer.h:33
uint32_t ipDst
IPv4 address of the receiver of the packet.
Definition: IPv4Layer.h:51
uint16_t headerChecksum
Error-checking of the header.
Definition: IPv4Layer.h:47
uint8_t ipVersion
IP version number, has the value of 4 for IPv4.
Definition: IPv4Layer.h:25
uint32_t ipSrc
IPv4 address of the sender of the packet.
Definition: IPv4Layer.h:49
uint8_t protocol
Defines the protocol used in the data portion of the IP datagram. Must be one of IPProtocolTypes.
Definition: IPv4Layer.h:45
uint16_t fragmentOffset
Fragment offset field, measured in units of eight-byte blocks (64 bits)
Definition: IPv4Layer.h:40
uint16_t ipId
Definition: IPv4Layer.h:38
uint8_t timeToLive
Definition: IPv4Layer.h:43
uint16_t totalLength
Entire packet (fragment) size, including header and data, in bytes.
Definition: IPv4Layer.h:35
uint8_t internetHeaderLength
IP header length, has the value of 5 for IPv4.
Definition: IPv4Layer.h:23