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 
16 namespace pcpp
17 {
18 
23 #pragma pack(push, 1)
24  struct iphdr
25  {
26 #if (BYTE_ORDER == LITTLE_ENDIAN)
28  uint8_t internetHeaderLength : 4,
30  ipVersion : 4;
31 #else
33  uint8_t ipVersion : 4,
36 #endif
38  uint8_t typeOfService;
40  uint16_t totalLength;
43  uint16_t ipId;
45  uint16_t fragmentOffset;
48  uint8_t timeToLive;
50  uint8_t protocol;
52  uint16_t headerChecksum;
54  uint32_t ipSrc;
56  uint32_t ipDst;
57  /*The options start here. */
58  };
59 #pragma pack(pop)
60 
65  {
110  };
111 
116  {
159  };
160 
161 #define PCPP_IP_DONT_FRAGMENT 0x40
162 #define PCPP_IP_MORE_FRAGMENTS 0x20
163 
170  {
175  {
183  Unknown = 3
184  };
185 
188 
190  std::vector<uint32_t> timestamps;
191 
193  std::vector<IPv4Address> ipAddresses;
194 
197  {}
198 
203  void clear()
204  {
206  timestamps.clear();
207  ipAddresses.clear();
208  }
209  };
210 
216  class IPv4Option : public TLVRecord<uint8_t, uint8_t>
217  {
218  public:
223  explicit IPv4Option(uint8_t* optionRawData) : TLVRecord(optionRawData)
224  {}
225 
229  ~IPv4Option() override = default;
230 
239  std::vector<IPv4Address> getValueAsIpList() const
240  {
241  std::vector<IPv4Address> res;
242 
243  if (m_Data == nullptr)
244  return res;
245 
246  size_t dataSize = getDataSize();
247  if (dataSize < 2)
248  return res;
249 
250  uint8_t valueOffset = static_cast<uint8_t>(1);
251 
252  while (static_cast<size_t>(valueOffset) < dataSize)
253  {
254  uint32_t curValue;
255  memcpy(&curValue, m_Data->recordValue + valueOffset, sizeof(uint32_t));
256  if (curValue == 0)
257  break;
258 
259  res.push_back(IPv4Address(curValue));
260 
261  valueOffset += static_cast<uint8_t>(4);
262  }
263 
264  return res;
265  }
266 
277  {
279  res.clear();
280 
281  if (m_Data == nullptr)
282  return res;
283 
285  return res;
286 
287  size_t dataSize = getDataSize();
288  if (dataSize < 2)
289  return res;
290 
291  res.type = static_cast<IPv4TimestampOptionValue::TimestampType>(m_Data->recordValue[1]);
292 
293  uint8_t valueOffset = static_cast<uint8_t>(2);
294  bool readIPAddr = (res.type == IPv4TimestampOptionValue::TimestampAndIP);
295 
296  while (static_cast<size_t>(valueOffset) < dataSize)
297  {
298  uint32_t curValue;
299  memcpy(&curValue, m_Data->recordValue + valueOffset, sizeof(uint32_t));
300  if (curValue == 0)
301  break;
302 
303  if (readIPAddr)
304  res.ipAddresses.push_back(IPv4Address(curValue));
305  else
306  res.timestamps.push_back(curValue);
307 
309  readIPAddr = !readIPAddr;
310 
311  valueOffset += static_cast<uint8_t>(4);
312  }
313 
314  return res;
315  }
316 
321  {
322  return getIPv4OptionType(m_Data);
323  }
324 
331  static bool canAssign(const uint8_t* recordRawData, size_t tlvDataLen)
332  {
333  auto data = reinterpret_cast<TLVRawData const*>(recordRawData);
334  if (data == nullptr)
335  return false;
336 
337  if (tlvDataLen < sizeof(TLVRawData::recordType))
338  return false;
339 
340  if (getIPv4OptionType(data) == static_cast<uint8_t>(IPV4OPT_EndOfOptionsList) ||
341  data->recordType == static_cast<uint8_t>(IPV4OPT_NOP))
342  return true;
343 
344  return TLVRecord<uint8_t, uint8_t>::canAssign(recordRawData, tlvDataLen);
345  }
346 
347  // implement abstract methods
348 
349  size_t getTotalSize() const override
350  {
351  if (m_Data == nullptr)
352  return 0;
353 
354  if (getIPv4OptionType() == static_cast<uint8_t>(IPV4OPT_EndOfOptionsList) ||
355  m_Data->recordType == static_cast<uint8_t>(IPV4OPT_NOP))
356  return sizeof(uint8_t);
357 
358  return static_cast<size_t>(m_Data->recordLen);
359  }
360 
361  size_t getDataSize() const override
362  {
363  if (m_Data == nullptr)
364  return 0;
365 
366  if (getIPv4OptionType() == static_cast<uint8_t>(IPV4OPT_EndOfOptionsList) ||
367  m_Data->recordType == static_cast<uint8_t>(IPV4OPT_NOP))
368  return 0;
369 
370  return static_cast<size_t>(m_Data->recordLen) - (2 * sizeof(uint8_t));
371  }
372 
373  private:
377  static IPv4OptionTypes getIPv4OptionType(const TLVRawData* data)
378  {
379  if (data == nullptr)
380  return IPV4OPT_Unknown;
381 
382  return static_cast<IPv4OptionTypes>(data->recordType);
383  }
384  };
385 
392  {
393  private:
394  bool m_BuilderParamsValid;
395 
396  public:
406  IPv4OptionBuilder(IPv4OptionTypes optionType, const uint8_t* optionValue, uint8_t optionValueLen)
407  : TLVRecordBuilder((uint8_t)optionType, optionValue, optionValueLen)
408  {
409  m_BuilderParamsValid = true;
410  }
411 
418  IPv4OptionBuilder(IPv4OptionTypes optionType, uint16_t optionValue)
419  : TLVRecordBuilder((uint8_t)optionType, optionValue)
420  {
421  m_BuilderParamsValid = true;
422  }
423 
431  IPv4OptionBuilder(IPv4OptionTypes optionType, const std::vector<IPv4Address>& ipList);
432 
438  explicit IPv4OptionBuilder(const IPv4TimestampOptionValue& timestampValue);
439 
444  IPv4Option build() const;
445  };
446 
451  class IPv4Layer : public Layer, public IPLayer
452  {
453  public:
461  IPv4Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
462 
475  IPv4Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet, bool setTotalLenAsDataLen);
476 
481 
487  IPv4Layer(const IPv4Address& srcIP, const IPv4Address& dstIP);
488 
492  IPv4Layer(const IPv4Layer& other);
493 
498  IPv4Layer& operator=(const IPv4Layer& other);
499 
506  {
507  return reinterpret_cast<iphdr*>(m_Data);
508  }
509 
515  IPAddress getSrcIPAddress() const override
516  {
517  return getSrcIPv4Address();
518  }
519 
525  {
526  return getIPv4Header()->ipSrc;
527  }
528 
533  void setSrcIPv4Address(const IPv4Address& ipAddr)
534  {
535  getIPv4Header()->ipSrc = ipAddr.toInt();
536  }
537 
543  IPAddress getDstIPAddress() const override
544  {
545  return getDstIPv4Address();
546  }
547 
553  {
554  return getIPv4Header()->ipDst;
555  }
556 
561  void setDstIPv4Address(const IPv4Address& ipAddr)
562  {
563  getIPv4Header()->ipDst = ipAddr.toInt();
564  }
565 
569  bool isFragment() const;
570 
575  bool isFirstFragment() const;
576 
581  bool isLastFragment() const;
582 
586  uint8_t getFragmentFlags() const;
587 
591  uint16_t getFragmentOffset() const;
592 
600 
606 
616 
620  size_t getOptionCount() const;
621 
629  IPv4Option addOption(const IPv4OptionBuilder& optionBuilder);
630 
642  IPv4OptionTypes prevOptionType = IPV4OPT_Unknown);
643 
651 
658 
659  // implement abstract methods
660 
675  void parseNextLayer() override;
676 
680  size_t getHeaderLen() const override
681  {
682  return static_cast<size_t>(static_cast<uint16_t>(getIPv4Header()->internetHeaderLength) * 4) +
683  m_TempHeaderExtension;
684  }
685 
694  void computeCalculateFields() override;
695 
696  std::string toString() const override;
697 
699  {
700  return OsiModelNetworkLayer;
701  }
702 
709  static inline bool isDataValid(const uint8_t* data, size_t dataLen);
710 
711  private:
712  int m_NumOfTrailingBytes;
713  int m_TempHeaderExtension;
714  TLVRecordReader<IPv4Option> m_OptionReader;
715 
716  void copyLayerData(const IPv4Layer& other);
717  uint8_t* getOptionsBasePtr() const
718  {
719  return m_Data + sizeof(iphdr);
720  }
721  IPv4Option addOptionAt(const IPv4OptionBuilder& optionBuilder, int offset);
722  void adjustOptionsTrailer(size_t totalOptSize);
723  void initLayer();
724  void initLayerInPacket(bool setTotalLenAsDataLen);
725  };
726 
727  // implementation of inline methods
728 
729  bool IPv4Layer::isDataValid(const uint8_t* data, size_t dataLen)
730  {
731  const iphdr* hdr = reinterpret_cast<const iphdr*>(data);
732  return dataLen >= sizeof(iphdr) && hdr->ipVersion == 4 && hdr->internetHeaderLength >= 5;
733  }
734 
735 } // namespace pcpp
Definition: IpAddress.h:358
Definition: IPLayer.h:22
Definition: IpAddress.h:32
uint32_t toInt() const
Definition: IpAddress.h:187
Definition: IPv4Layer.h:452
bool removeAllOptions()
IPv4Option getNextOption(IPv4Option &option) const
iphdr * getIPv4Header() const
Definition: IPv4Layer.h:505
size_t getHeaderLen() const override
Definition: IPv4Layer.h:680
uint8_t getFragmentFlags() const
IPv4Address getSrcIPv4Address() const
Definition: IPv4Layer.h:524
IPAddress getDstIPAddress() const override
Definition: IPv4Layer.h:543
IPAddress getSrcIPAddress() const override
Definition: IPv4Layer.h:515
void parseNextLayer() override
static bool isDataValid(const uint8_t *data, size_t dataLen)
Definition: IPv4Layer.h:729
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:561
void setSrcIPv4Address(const IPv4Address &ipAddr)
Definition: IPv4Layer.h:533
IPv4Layer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet, bool setTotalLenAsDataLen)
void computeCalculateFields() override
OsiModelLayer getOsiModelLayer() const override
Definition: IPv4Layer.h:698
bool isLastFragment() const
IPv4Layer & operator=(const IPv4Layer &other)
IPv4Address getDstIPv4Address() const
Definition: IPv4Layer.h:552
IPv4Layer(const IPv4Layer &other)
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:392
IPv4OptionBuilder(IPv4OptionTypes optionType, const uint8_t *optionValue, uint8_t optionValueLen)
Definition: IPv4Layer.h:406
IPv4OptionBuilder(IPv4OptionTypes optionType, uint16_t optionValue)
Definition: IPv4Layer.h:418
IPv4OptionBuilder(const IPv4TimestampOptionValue &timestampValue)
IPv4Option build() const
IPv4OptionBuilder(IPv4OptionTypes optionType, const std::vector< IPv4Address > &ipList)
Definition: IPv4Layer.h:217
IPv4Option(uint8_t *optionRawData)
Definition: IPv4Layer.h:223
std::vector< IPv4Address > getValueAsIpList() const
Definition: IPv4Layer.h:239
~IPv4Option() override=default
IPv4OptionTypes getIPv4OptionType() const
Definition: IPv4Layer.h:320
size_t getDataSize() const override
Definition: IPv4Layer.h:361
size_t getTotalSize() const override
Definition: IPv4Layer.h:349
static bool canAssign(const uint8_t *recordRawData, size_t tlvDataLen)
Definition: IPv4Layer.h:331
IPv4TimestampOptionValue getTimestampOptionValue() const
Definition: IPv4Layer.h:276
Definition: Layer.h:69
Definition: Packet.h:27
Definition: TLVData.h:419
Definition: TLVData.h:23
static bool canAssign(const uint8_t *recordRawData, size_t tlvDataLen)
Definition: TLVData.h:80
Definition: TLVData.h:246
The main namespace for the PcapPlusPlus lib.
IPv4OptionTypes
Definition: IPv4Layer.h:116
@ IPV4OPT_MTUReply
Definition: IPv4Layer.h:126
@ IPV4OPT_QuickStart
Definition: IPv4Layer.h:128
@ IPV4OPT_LooseSourceRoute
Definition: IPv4Layer.h:136
@ IPV4OPT_Traceroute
Definition: IPv4Layer.h:132
@ IPV4OPT_NOP
Definition: IPv4Layer.h:120
@ IPV4OPT_UpstreamMulticastPkt
Definition: IPv4Layer.h:156
@ IPV4OPT_DynamicPacketState
Definition: IPv4Layer.h:154
@ IPV4OPT_EndOfOptionsList
Definition: IPv4Layer.h:118
@ IPV4OPT_ExtendedSecurity
Definition: IPv4Layer.h:138
@ IPV4OPT_RouterAlert
Definition: IPv4Layer.h:150
@ IPV4OPT_SelectiveDirectedBroadcast
Definition: IPv4Layer.h:152
@ IPV4OPT_Security
Definition: IPv4Layer.h:134
@ IPV4OPT_Timestamp
Definition: IPv4Layer.h:130
@ IPV4OPT_Unknown
Definition: IPv4Layer.h:158
@ IPV4OPT_AddressExtension
Definition: IPv4Layer.h:148
@ IPV4OPT_CommercialSecurity
Definition: IPv4Layer.h:140
@ IPV4OPT_MTUProbe
Definition: IPv4Layer.h:124
@ IPV4OPT_StrictSourceRoute
Definition: IPv4Layer.h:144
@ IPV4OPT_ExtendedInternetProtocol
Definition: IPv4Layer.h:146
@ IPV4OPT_StreamID
Definition: IPv4Layer.h:142
@ IPV4OPT_RecordRoute
Definition: IPv4Layer.h:122
OsiModelLayer
Definition: ProtocolType.h:364
@ OsiModelNetworkLayer
Definition: ProtocolType.h:370
IPProtocolTypes
Definition: IPv4Layer.h:65
@ PACKETPP_IPPROTO_ROUTING
Definition: IPv4Layer.h:89
@ PACKETPP_IPPROTO_AH
Definition: IPv4Layer.h:97
@ PACKETPP_IPPROTO_ICMP
Definition: IPv4Layer.h:71
@ PACKETPP_IPPROTO_IPIP
Definition: IPv4Layer.h:75
@ PACKETPP_IPPROTO_FRAGMENT
Definition: IPv4Layer.h:91
@ PACKETPP_IPPROTO_UDP
Definition: IPv4Layer.h:83
@ PACKETPP_IPPROTO_IP
Definition: IPv4Layer.h:67
@ PACKETPP_IPPROTO_ESP
Definition: IPv4Layer.h:95
@ PACKETPP_IPPROTO_IGMP
Definition: IPv4Layer.h:73
@ PACKETPP_IPPROTO_GRE
Definition: IPv4Layer.h:93
@ PACKETPP_IPPROTO_TCP
Definition: IPv4Layer.h:77
@ PACKETPP_IPPROTO_ICMPV6
Definition: IPv4Layer.h:99
@ PACKETPP_IPPROTO_PUP
Definition: IPv4Layer.h:81
@ PACKETPP_IPPROTO_VRRP
Definition: IPv4Layer.h:105
@ PACKETPP_IPPROTO_IDP
Definition: IPv4Layer.h:85
@ PACKETPP_IPPROTO_EGP
Definition: IPv4Layer.h:79
@ PACKETPP_IPPROTO_HOPOPTS
Definition: IPv4Layer.h:69
@ PACKETPP_IPPROTO_DSTOPTS
Definition: IPv4Layer.h:103
@ PACKETPP_IPPROTO_RAW
Definition: IPv4Layer.h:107
@ PACKETPP_IPPROTO_NONE
Definition: IPv4Layer.h:101
@ PACKETPP_IPPROTO_MAX
Definition: IPv4Layer.h:109
@ PACKETPP_IPPROTO_IPV6
Definition: IPv4Layer.h:87
Definition: IPv4Layer.h:170
TimestampType type
Definition: IPv4Layer.h:187
std::vector< IPv4Address > ipAddresses
Definition: IPv4Layer.h:193
TimestampType
Definition: IPv4Layer.h:175
@ Unknown
Definition: IPv4Layer.h:183
@ TimestampsForPrespecifiedIPs
Definition: IPv4Layer.h:181
@ TimestampAndIP
Definition: IPv4Layer.h:179
@ TimestampOnly
Definition: IPv4Layer.h:177
std::vector< uint32_t > timestamps
Definition: IPv4Layer.h:190
void clear()
Definition: IPv4Layer.h:203
IPv4TimestampOptionValue()
Definition: IPv4Layer.h:196
Definition: IPv4Layer.h:25
uint8_t typeOfService
Definition: IPv4Layer.h:38
uint32_t ipDst
Definition: IPv4Layer.h:56
uint16_t headerChecksum
Definition: IPv4Layer.h:52
uint8_t ipVersion
Definition: IPv4Layer.h:30
uint32_t ipSrc
Definition: IPv4Layer.h:54
uint8_t protocol
Definition: IPv4Layer.h:50
uint16_t fragmentOffset
Definition: IPv4Layer.h:45
uint16_t ipId
Definition: IPv4Layer.h:43
uint8_t timeToLive
Definition: IPv4Layer.h:48
uint16_t totalLength
Definition: IPv4Layer.h:40
uint8_t internetHeaderLength
Definition: IPv4Layer.h:28