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 #include <algorithm>
10 #include <iterator>
11 
13 
16 namespace pcpp
17 {
20 #pragma pack(push, 1)
21  struct iphdr
22  {
23 #if (BYTE_ORDER == LITTLE_ENDIAN)
25  uint8_t internetHeaderLength : 4,
27  ipVersion : 4;
28 #else
30  uint8_t ipVersion : 4,
33 #endif
35  uint8_t typeOfService;
37  uint16_t totalLength;
40  uint16_t ipId;
42  uint16_t fragmentOffset;
45  uint8_t timeToLive;
47  uint8_t protocol;
49  uint16_t headerChecksum;
51  uint32_t ipSrc;
53  uint32_t ipDst;
54  // The options start here.
55  };
56 #pragma pack(pop)
57  static_assert(sizeof(iphdr) == 20, "iphdr size is not 20 bytes");
58 
61  {
106  };
107 
110  {
153  };
154 
155 #define PCPP_IP_DONT_FRAGMENT 0x40
156 #define PCPP_IP_MORE_FRAGMENTS 0x20
157 
162  {
165  {
173  Unknown = 3
174  };
175 
178 
180  std::vector<uint32_t> timestamps;
181 
183  std::vector<IPv4Address> ipAddresses;
184 
187  {}
188 
191  void clear()
192  {
194  timestamps.clear();
195  ipAddresses.clear();
196  }
197  };
198 
202  class IPv4Option : public TLVRecord<uint8_t, uint8_t>
203  {
204  public:
207  explicit IPv4Option(uint8_t* optionRawData) : TLVRecord(optionRawData)
208  {}
209 
211  ~IPv4Option() override = default;
212 
219  std::vector<IPv4Address> getValueAsIpList() const
220  {
221  std::vector<IPv4Address> res;
222 
223  if (m_Data == nullptr)
224  return res;
225 
226  size_t dataSize = getDataSize();
227  if (dataSize < 2)
228  return res;
229 
230  uint8_t valueOffset = static_cast<uint8_t>(1);
231 
232  while (static_cast<size_t>(valueOffset) < dataSize)
233  {
234  uint32_t curValue;
235  memcpy(&curValue, m_Data->recordValue + valueOffset, sizeof(uint32_t));
236  if (curValue == 0)
237  break;
238 
239  res.push_back(IPv4Address(curValue));
240 
241  valueOffset += static_cast<uint8_t>(4);
242  }
243 
244  return res;
245  }
246 
255  {
257  res.clear();
258 
259  if (m_Data == nullptr)
260  return res;
261 
263  return res;
264 
265  size_t dataSize = getDataSize();
266  if (dataSize < 2)
267  return res;
268 
269  res.type = static_cast<IPv4TimestampOptionValue::TimestampType>(m_Data->recordValue[1]);
270 
271  uint8_t valueOffset = static_cast<uint8_t>(2);
272  bool readIPAddr = (res.type == IPv4TimestampOptionValue::TimestampAndIP);
273 
274  while (static_cast<size_t>(valueOffset) < dataSize)
275  {
276  uint32_t curValue;
277  memcpy(&curValue, m_Data->recordValue + valueOffset, sizeof(uint32_t));
278  if (curValue == 0)
279  break;
280 
281  if (readIPAddr)
282  res.ipAddresses.push_back(IPv4Address(curValue));
283  else
284  res.timestamps.push_back(curValue);
285 
287  readIPAddr = !readIPAddr;
288 
289  valueOffset += static_cast<uint8_t>(4);
290  }
291 
292  return res;
293  }
294 
297  {
298  return getIPv4OptionType(m_Data);
299  }
300 
305  static bool canAssign(const uint8_t* recordRawData, size_t tlvDataLen)
306  {
307  auto data = reinterpret_cast<TLVRawData const*>(recordRawData);
308  if (data == nullptr)
309  return false;
310 
311  if (tlvDataLen < sizeof(TLVRawData::recordType))
312  return false;
313 
314  if (getIPv4OptionType(data) == static_cast<uint8_t>(IPV4OPT_EndOfOptionsList) ||
315  data->recordType == static_cast<uint8_t>(IPV4OPT_NOP))
316  return true;
317 
318  return TLVRecord<uint8_t, uint8_t>::canAssign(recordRawData, tlvDataLen);
319  }
320 
321  // implement abstract methods
322 
323  size_t getTotalSize() const override
324  {
325  if (m_Data == nullptr)
326  return 0;
327 
328  if (getIPv4OptionType() == static_cast<uint8_t>(IPV4OPT_EndOfOptionsList) ||
329  m_Data->recordType == static_cast<uint8_t>(IPV4OPT_NOP))
330  return sizeof(uint8_t);
331 
332  return static_cast<size_t>(m_Data->recordLen);
333  }
334 
335  size_t getDataSize() const override
336  {
337  if (m_Data == nullptr)
338  return 0;
339 
340  if (getIPv4OptionType() == static_cast<uint8_t>(IPV4OPT_EndOfOptionsList) ||
341  m_Data->recordType == static_cast<uint8_t>(IPV4OPT_NOP))
342  return 0;
343 
344  return static_cast<size_t>(m_Data->recordLen) - (2 * sizeof(uint8_t));
345  }
346 
347  private:
349  static IPv4OptionTypes getIPv4OptionType(const TLVRawData* data)
350  {
351  if (data == nullptr)
352  return IPV4OPT_Unknown;
353 
354  return static_cast<IPv4OptionTypes>(data->recordType);
355  }
356  };
357 
362  {
363  private:
364  bool m_BuilderParamsValid;
365 
366  public:
374  IPv4OptionBuilder(IPv4OptionTypes optionType, const uint8_t* optionValue, uint8_t optionValueLen)
375  : TLVRecordBuilder((uint8_t)optionType, optionValue, optionValueLen)
376  {
377  m_BuilderParamsValid = true;
378  }
379 
384  IPv4OptionBuilder(IPv4OptionTypes optionType, uint16_t optionValue)
385  : TLVRecordBuilder((uint8_t)optionType, optionValue)
386  {
387  m_BuilderParamsValid = true;
388  }
389 
395  IPv4OptionBuilder(IPv4OptionTypes optionType, const std::vector<IPv4Address>& ipList);
396 
400  explicit IPv4OptionBuilder(const IPv4TimestampOptionValue& timestampValue);
401 
404  IPv4Option build() const;
405  };
406 
409  class IPv4Layer : public Layer, public IPLayer
410  {
411  public:
417  IPv4Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
418 
429  IPv4Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet, bool setTotalLenAsDataLen);
430 
433 
437  IPv4Layer(const IPv4Address& srcIP, const IPv4Address& dstIP);
438 
440  IPv4Layer(const IPv4Layer& other);
441 
444  IPv4Layer& operator=(const IPv4Layer& other);
445 
450  {
451  return reinterpret_cast<iphdr*>(m_Data);
452  }
453 
457  IPAddress getSrcIPAddress() const override
458  {
459  return getSrcIPv4Address();
460  }
461 
465  {
466  return getIPv4Header()->ipSrc;
467  }
468 
471  void setSrcIPv4Address(const IPv4Address& ipAddr)
472  {
473  getIPv4Header()->ipSrc = ipAddr.toInt();
474  }
475 
479  IPAddress getDstIPAddress() const override
480  {
481  return getDstIPv4Address();
482  }
483 
487  {
488  return getIPv4Header()->ipDst;
489  }
490 
493  void setDstIPv4Address(const IPv4Address& ipAddr)
494  {
495  getIPv4Header()->ipDst = ipAddr.toInt();
496  }
497 
499  bool isFragment() const;
500 
503  bool isFirstFragment() const;
504 
507  bool isLastFragment() const;
508 
510  uint8_t getFragmentFlags() const;
511 
513  uint16_t getFragmentOffset() const;
514 
520 
524 
532 
534  size_t getOptionCount() const;
535 
541  IPv4Option addOption(const IPv4OptionBuilder& optionBuilder);
542 
553  IPv4OptionTypes prevOptionType = IPV4OPT_Unknown);
554 
560 
565 
566  // implement abstract methods
567 
580  void parseNextLayer() override;
581 
583  size_t getHeaderLen() const override
584  {
585  return static_cast<size_t>(static_cast<uint16_t>(getIPv4Header()->internetHeaderLength) * 4) +
586  m_TempHeaderExtension;
587  }
588 
595  void computeCalculateFields() override;
596 
597  std::string toString() const override;
598 
600  {
601  return OsiModelNetworkLayer;
602  }
603 
608  static inline bool isDataValid(const uint8_t* data, size_t dataLen);
609 
614  {
616  static std::vector<FieldDescriptor> all()
617  {
618  auto result = Layer::SerializedFields::all();
619  std::initializer_list<FieldDescriptor> extra{ SrcIp, DstIp, IpId, IpProtocol,
621  std::copy(extra.begin(), extra.end(), std::back_inserter(result));
622  return result;
623  }
624 
626  static const FieldDescriptor SrcIp;
627 
629  static const FieldDescriptor DstIp;
630 
632  static const FieldDescriptor IpId;
633 
636 
639 
642 
645 
647  static const FieldDescriptor Options;
648 
650  static const FieldDescriptor Option;
651  };
652 
653  protected:
654  void serializeLayer(ObjectScope& serializer) const override;
655 
656  private:
657  int m_NumOfTrailingBytes;
658  int m_TempHeaderExtension;
659  TLVRecordReader<IPv4Option> m_OptionReader;
660 
661  void copyLayerData(const IPv4Layer& other);
662  uint8_t* getOptionsBasePtr() const
663  {
664  return m_Data + sizeof(iphdr);
665  }
666  IPv4Option addOptionAt(const IPv4OptionBuilder& optionBuilder, int offset);
667  void adjustOptionsTrailer(size_t totalOptSize);
668  void initLayer();
669  void initLayerInPacket(bool setTotalLenAsDataLen);
670  };
671 
672  // implementation of inline methods
673 
674  bool IPv4Layer::isDataValid(const uint8_t* data, size_t dataLen)
675  {
676  const iphdr* hdr = reinterpret_cast<const iphdr*>(data);
677  return canReinterpretAs<iphdr>(data, dataLen) && hdr->ipVersion == 4 && hdr->internetHeaderLength >= 5;
678  }
679 
680 } // namespace pcpp
Definition: IpAddress.h:318
Definition: IPLayer.h:18
Definition: IpAddress.h:30
uint32_t toInt() const
Definition: IpAddress.h:155
Definition: IPv4Layer.h:410
bool removeAllOptions()
IPv4Option getNextOption(IPv4Option &option) const
iphdr * getIPv4Header() const
Definition: IPv4Layer.h:449
size_t getHeaderLen() const override
Definition: IPv4Layer.h:583
IPv4Layer()
A constructor that allocates a new IPv4 header with empty fields.
uint8_t getFragmentFlags() const
IPv4Address getSrcIPv4Address() const
Definition: IPv4Layer.h:464
IPAddress getDstIPAddress() const override
Definition: IPv4Layer.h:479
IPAddress getSrcIPAddress() const override
Definition: IPv4Layer.h:457
void parseNextLayer() override
static bool isDataValid(const uint8_t *data, size_t dataLen)
Definition: IPv4Layer.h:674
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:493
void serializeLayer(ObjectScope &serializer) const override
void setSrcIPv4Address(const IPv4Address &ipAddr)
Definition: IPv4Layer.h:471
IPv4Layer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet, bool setTotalLenAsDataLen)
void computeCalculateFields() override
OsiModelLayer getOsiModelLayer() const override
Definition: IPv4Layer.h:599
bool isLastFragment() const
IPv4Layer & operator=(const IPv4Layer &other)
IPv4Address getDstIPv4Address() const
Definition: IPv4Layer.h:486
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:362
IPv4OptionBuilder(IPv4OptionTypes optionType, const uint8_t *optionValue, uint8_t optionValueLen)
Definition: IPv4Layer.h:374
IPv4OptionBuilder(IPv4OptionTypes optionType, uint16_t optionValue)
Definition: IPv4Layer.h:384
IPv4OptionBuilder(const IPv4TimestampOptionValue &timestampValue)
IPv4Option build() const
IPv4OptionBuilder(IPv4OptionTypes optionType, const std::vector< IPv4Address > &ipList)
Definition: IPv4Layer.h:203
IPv4Option(uint8_t *optionRawData)
Definition: IPv4Layer.h:207
std::vector< IPv4Address > getValueAsIpList() const
Definition: IPv4Layer.h:219
~IPv4Option() override=default
A d'tor for this class, currently does nothing.
IPv4OptionTypes getIPv4OptionType() const
Definition: IPv4Layer.h:296
size_t getDataSize() const override
Definition: IPv4Layer.h:335
size_t getTotalSize() const override
Definition: IPv4Layer.h:323
static bool canAssign(const uint8_t *recordRawData, size_t tlvDataLen)
Definition: IPv4Layer.h:305
IPv4TimestampOptionValue getTimestampOptionValue() const
Definition: IPv4Layer.h:254
Definition: Layer.h:117
Definition: Serializers.h:230
Definition: Packet.h:49
Definition: TLVData.h:374
Definition: TLVData.h:20
static bool canAssign(const uint8_t *recordRawData, size_t tlvDataLen)
Definition: TLVData.h:67
Definition: TLVData.h:219
The main namespace for the PcapPlusPlus lib.
Definition: AssertionUtils.h:19
IPv4OptionTypes
An enum for supported IPv4 option types.
Definition: IPv4Layer.h:110
@ IPV4OPT_MTUReply
MTU Reply.
Definition: IPv4Layer.h:120
@ IPV4OPT_QuickStart
Quick-Start.
Definition: IPv4Layer.h:122
@ IPV4OPT_LooseSourceRoute
Loose Source Route.
Definition: IPv4Layer.h:130
@ IPV4OPT_Traceroute
Traceroute.
Definition: IPv4Layer.h:126
@ IPV4OPT_NOP
No Operation.
Definition: IPv4Layer.h:114
@ IPV4OPT_UpstreamMulticastPkt
Upstream Multicast Pkt.
Definition: IPv4Layer.h:150
@ IPV4OPT_DynamicPacketState
Dynamic Packet State.
Definition: IPv4Layer.h:148
@ IPV4OPT_EndOfOptionsList
End of Options List.
Definition: IPv4Layer.h:112
@ IPV4OPT_ExtendedSecurity
Extended Security.
Definition: IPv4Layer.h:132
@ IPV4OPT_RouterAlert
Router Alert.
Definition: IPv4Layer.h:144
@ IPV4OPT_SelectiveDirectedBroadcast
Selective Directed Broadcast.
Definition: IPv4Layer.h:146
@ IPV4OPT_Security
Security.
Definition: IPv4Layer.h:128
@ IPV4OPT_Timestamp
Timestamp.
Definition: IPv4Layer.h:124
@ IPV4OPT_Unknown
Unknown IPv4 option.
Definition: IPv4Layer.h:152
@ IPV4OPT_AddressExtension
Address Extension.
Definition: IPv4Layer.h:142
@ IPV4OPT_CommercialSecurity
Commercial Security.
Definition: IPv4Layer.h:134
@ IPV4OPT_MTUProbe
MTU Probe.
Definition: IPv4Layer.h:118
@ IPV4OPT_StrictSourceRoute
Strict Source Route.
Definition: IPv4Layer.h:138
@ IPV4OPT_ExtendedInternetProtocol
Extended Internet Protocol.
Definition: IPv4Layer.h:140
@ IPV4OPT_StreamID
Stream ID.
Definition: IPv4Layer.h:136
@ IPV4OPT_RecordRoute
Record Route.
Definition: IPv4Layer.h:116
OsiModelLayer
An enum representing OSI model layers.
Definition: ProtocolType.h:420
@ OsiModelNetworkLayer
Network layer (layer 3)
Definition: ProtocolType.h:426
IPProtocolTypes
An enum for all possible IPv4 and IPv6 protocol types.
Definition: IPv4Layer.h:61
@ PACKETPP_IPPROTO_ROUTING
IPv6 Routing header.
Definition: IPv4Layer.h:85
@ PACKETPP_IPPROTO_AH
authentication header
Definition: IPv4Layer.h:93
@ PACKETPP_IPPROTO_ICMP
Internet Control Message Protocol.
Definition: IPv4Layer.h:67
@ PACKETPP_IPPROTO_IPIP
IPIP tunnels (older KA9Q tunnels use 94)
Definition: IPv4Layer.h:71
@ PACKETPP_IPPROTO_FRAGMENT
IPv6 fragmentation header.
Definition: IPv4Layer.h:87
@ PACKETPP_IPPROTO_UDP
User Datagram Protocol.
Definition: IPv4Layer.h:79
@ PACKETPP_IPPROTO_IP
Dummy protocol for TCP.
Definition: IPv4Layer.h:63
@ PACKETPP_IPPROTO_ESP
encapsulating security payload
Definition: IPv4Layer.h:91
@ PACKETPP_IPPROTO_IGMP
Internet Gateway Management Protocol.
Definition: IPv4Layer.h:69
@ PACKETPP_IPPROTO_GRE
GRE protocol.
Definition: IPv4Layer.h:89
@ PACKETPP_IPPROTO_TCP
Transmission Control Protocol.
Definition: IPv4Layer.h:73
@ PACKETPP_IPPROTO_ICMPV6
ICMPv6.
Definition: IPv4Layer.h:95
@ PACKETPP_IPPROTO_PUP
PUP protocol.
Definition: IPv4Layer.h:77
@ PACKETPP_IPPROTO_VRRP
VRRP protocol.
Definition: IPv4Layer.h:101
@ PACKETPP_IPPROTO_IDP
XNS IDP protocol.
Definition: IPv4Layer.h:81
@ PACKETPP_IPPROTO_EGP
Exterior Gateway Protocol.
Definition: IPv4Layer.h:75
@ PACKETPP_IPPROTO_HOPOPTS
IPv6 Hop-by-Hop options.
Definition: IPv4Layer.h:65
@ PACKETPP_IPPROTO_DSTOPTS
IPv6 Destination options.
Definition: IPv4Layer.h:99
@ PACKETPP_IPPROTO_RAW
Raw IP packets.
Definition: IPv4Layer.h:103
@ PACKETPP_IPPROTO_NONE
IPv6 no next header.
Definition: IPv4Layer.h:97
@ PACKETPP_IPPROTO_MAX
Maximum value.
Definition: IPv4Layer.h:105
@ PACKETPP_IPPROTO_IPV6
IPv6 header.
Definition: IPv4Layer.h:83
Definition: Serializers.h:18
Definition: IPv4Layer.h:614
static std::vector< FieldDescriptor > all()
Definition: IPv4Layer.h:616
static const FieldDescriptor IpProtocol
Next layer's protocol (e.g. 6 for TCP, 17 for UDP)
Definition: IPv4Layer.h:635
static const FieldDescriptor Option
One option's type name (e.g. "NOP"); an Options element, not included in all()
Definition: IPv4Layer.h:650
static const FieldDescriptor IsFragment
Whether this packet is a fragment.
Definition: IPv4Layer.h:641
static const FieldDescriptor IpId
IP identification field, in host byte order.
Definition: IPv4Layer.h:632
static const FieldDescriptor FragmentOffset
Fragment offset, in 8-byte units.
Definition: IPv4Layer.h:644
static const FieldDescriptor TotalLength
Total length, in host byte order.
Definition: IPv4Layer.h:638
static const FieldDescriptor DstIp
Destination IP address, as a string.
Definition: IPv4Layer.h:629
static const FieldDescriptor Options
Array of header options; elements described by Option.
Definition: IPv4Layer.h:647
static const FieldDescriptor SrcIp
Source IP address, as a string.
Definition: IPv4Layer.h:626
Definition: IPv4Layer.h:162
TimestampType type
The timestamp value type.
Definition: IPv4Layer.h:177
std::vector< IPv4Address > ipAddresses
A list of IPv4 addresses parsed from the IPv4 timestamp option value.
Definition: IPv4Layer.h:183
TimestampType
An enum for IPv4 timestamp option types.
Definition: IPv4Layer.h:165
@ Unknown
Invalid or unknown value type.
Definition: IPv4Layer.h:173
@ TimestampsForPrespecifiedIPs
The IPv4 addresses are prespecified.
Definition: IPv4Layer.h:171
@ TimestampAndIP
Value containing both timestamps and IPv4 addresses.
Definition: IPv4Layer.h:169
@ TimestampOnly
Value containing only timestamps.
Definition: IPv4Layer.h:167
std::vector< uint32_t > timestamps
A list of timestamps parsed from the IPv4 timestamp option value.
Definition: IPv4Layer.h:180
void clear()
Definition: IPv4Layer.h:191
IPv4TimestampOptionValue()
The default constructor.
Definition: IPv4Layer.h:186
Definition: Layer.h:212
static std::vector< FieldDescriptor > all()
Definition: Layer.h:214
Definition: IPv4Layer.h:22
uint8_t typeOfService
type of service, same as Differentiated Services Code Point (DSCP)
Definition: IPv4Layer.h:35
uint32_t ipDst
IPv4 address of the receiver of the packet.
Definition: IPv4Layer.h:53
uint16_t headerChecksum
Error-checking of the header.
Definition: IPv4Layer.h:49
uint8_t ipVersion
IP version number, has the value of 4 for IPv4.
Definition: IPv4Layer.h:27
uint32_t ipSrc
IPv4 address of the sender of the packet.
Definition: IPv4Layer.h:51
uint8_t protocol
Defines the protocol used in the data portion of the IP datagram. Must be one of IPProtocolTypes.
Definition: IPv4Layer.h:47
uint16_t fragmentOffset
Fragment offset field, measured in units of eight-byte blocks (64 bits)
Definition: IPv4Layer.h:42
uint16_t ipId
Definition: IPv4Layer.h:40
uint8_t timeToLive
Definition: IPv4Layer.h:45
uint16_t totalLength
Entire packet (fragment) size, including header and data, in bytes.
Definition: IPv4Layer.h:37
uint8_t internetHeaderLength
IP header length, has the value of 5 for IPv4.
Definition: IPv4Layer.h:25