PcapPlusPlus  24.09
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 
230  {}
231 
240  std::vector<IPv4Address> getValueAsIpList() const
241  {
242  std::vector<IPv4Address> res;
243 
244  if (m_Data == nullptr)
245  return res;
246 
247  size_t dataSize = getDataSize();
248  if (dataSize < 2)
249  return res;
250 
251  uint8_t valueOffset = static_cast<uint8_t>(1);
252 
253  while (static_cast<size_t>(valueOffset) < dataSize)
254  {
255  uint32_t curValue;
256  memcpy(&curValue, m_Data->recordValue + valueOffset, sizeof(uint32_t));
257  if (curValue == 0)
258  break;
259 
260  res.push_back(IPv4Address(curValue));
261 
262  valueOffset += static_cast<uint8_t>(4);
263  }
264 
265  return res;
266  }
267 
278  {
280  res.clear();
281 
282  if (m_Data == nullptr)
283  return res;
284 
286  return res;
287 
288  size_t dataSize = getDataSize();
289  if (dataSize < 2)
290  return res;
291 
292  res.type = static_cast<IPv4TimestampOptionValue::TimestampType>(m_Data->recordValue[1]);
293 
294  uint8_t valueOffset = static_cast<uint8_t>(2);
295  bool readIPAddr = (res.type == IPv4TimestampOptionValue::TimestampAndIP);
296 
297  while (static_cast<size_t>(valueOffset) < dataSize)
298  {
299  uint32_t curValue;
300  memcpy(&curValue, m_Data->recordValue + valueOffset, sizeof(uint32_t));
301  if (curValue == 0)
302  break;
303 
304  if (readIPAddr)
305  res.ipAddresses.push_back(IPv4Address(curValue));
306  else
307  res.timestamps.push_back(curValue);
308 
310  readIPAddr = !readIPAddr;
311 
312  valueOffset += static_cast<uint8_t>(4);
313  }
314 
315  return res;
316  }
317 
322  {
323  return getIPv4OptionType(m_Data);
324  }
325 
332  static bool canAssign(const uint8_t* recordRawData, size_t tlvDataLen)
333  {
334  auto data = reinterpret_cast<TLVRawData const*>(recordRawData);
335  if (data == nullptr)
336  return false;
337 
338  if (tlvDataLen < sizeof(TLVRawData::recordType))
339  return false;
340 
341  if (getIPv4OptionType(data) == static_cast<uint8_t>(IPV4OPT_EndOfOptionsList) ||
342  data->recordType == static_cast<uint8_t>(IPV4OPT_NOP))
343  return true;
344 
345  return TLVRecord<uint8_t, uint8_t>::canAssign(recordRawData, tlvDataLen);
346  }
347 
348  // implement abstract methods
349 
350  size_t getTotalSize() const
351  {
352  if (m_Data == nullptr)
353  return 0;
354 
355  if (getIPv4OptionType() == static_cast<uint8_t>(IPV4OPT_EndOfOptionsList) ||
356  m_Data->recordType == static_cast<uint8_t>(IPV4OPT_NOP))
357  return sizeof(uint8_t);
358 
359  return static_cast<size_t>(m_Data->recordLen);
360  }
361 
362  size_t getDataSize() const
363  {
364  if (m_Data == nullptr)
365  return 0;
366 
367  if (getIPv4OptionType() == static_cast<uint8_t>(IPV4OPT_EndOfOptionsList) ||
368  m_Data->recordType == static_cast<uint8_t>(IPV4OPT_NOP))
369  return 0;
370 
371  return static_cast<size_t>(m_Data->recordLen) - (2 * sizeof(uint8_t));
372  }
373 
374  private:
378  static IPv4OptionTypes getIPv4OptionType(const TLVRawData* data)
379  {
380  if (data == nullptr)
381  return IPV4OPT_Unknown;
382 
383  return static_cast<IPv4OptionTypes>(data->recordType);
384  }
385  };
386 
393  {
394  private:
395  bool m_BuilderParamsValid;
396 
397  public:
407  IPv4OptionBuilder(IPv4OptionTypes optionType, const uint8_t* optionValue, uint8_t optionValueLen)
408  : TLVRecordBuilder((uint8_t)optionType, optionValue, optionValueLen)
409  {
410  m_BuilderParamsValid = true;
411  }
412 
419  IPv4OptionBuilder(IPv4OptionTypes optionType, uint16_t optionValue)
420  : TLVRecordBuilder((uint8_t)optionType, optionValue)
421  {
422  m_BuilderParamsValid = true;
423  }
424 
432  IPv4OptionBuilder(IPv4OptionTypes optionType, const std::vector<IPv4Address>& ipList);
433 
439  explicit IPv4OptionBuilder(const IPv4TimestampOptionValue& timestampValue);
440 
445  IPv4Option build() const;
446  };
447 
452  class IPv4Layer : public Layer, public IPLayer
453  {
454  public:
462  IPv4Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
463 
476  IPv4Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet, bool setTotalLenAsDataLen);
477 
482 
488  IPv4Layer(const IPv4Address& srcIP, const IPv4Address& dstIP);
489 
493  IPv4Layer(const IPv4Layer& other);
494 
499  IPv4Layer& operator=(const IPv4Layer& other);
500 
507  {
508  return (iphdr*)m_Data;
509  }
510 
517  {
518  return getSrcIPv4Address();
519  }
520 
526  {
527  return getIPv4Header()->ipSrc;
528  }
529 
534  void setSrcIPv4Address(const IPv4Address& ipAddr)
535  {
536  getIPv4Header()->ipSrc = ipAddr.toInt();
537  }
538 
545  {
546  return getDstIPv4Address();
547  }
548 
554  {
555  return getIPv4Header()->ipDst;
556  }
557 
562  void setDstIPv4Address(const IPv4Address& ipAddr)
563  {
564  getIPv4Header()->ipDst = ipAddr.toInt();
565  }
566 
570  bool isFragment() const;
571 
576  bool isFirstFragment() const;
577 
582  bool isLastFragment() const;
583 
587  uint8_t getFragmentFlags() const;
588 
592  uint16_t getFragmentOffset() const;
593 
601 
607 
617 
621  size_t getOptionCount() const;
622 
630  IPv4Option addOption(const IPv4OptionBuilder& optionBuilder);
631 
643  IPv4OptionTypes prevOptionType = IPV4OPT_Unknown);
644 
652 
659 
660  // implement abstract methods
661 
677 
681  size_t getHeaderLen() const
682  {
683  return static_cast<size_t>(static_cast<uint16_t>(getIPv4Header()->internetHeaderLength) * 4) +
684  m_TempHeaderExtension;
685  }
686 
696 
697  std::string toString() const;
698 
700  {
701  return OsiModelNetworkLayer;
702  }
703 
710  static inline bool isDataValid(const uint8_t* data, size_t dataLen);
711 
712  private:
713  int m_NumOfTrailingBytes;
714  int m_TempHeaderExtension;
715  TLVRecordReader<IPv4Option> m_OptionReader;
716 
717  void copyLayerData(const IPv4Layer& other);
718  uint8_t* getOptionsBasePtr() const
719  {
720  return m_Data + sizeof(iphdr);
721  }
722  IPv4Option addOptionAt(const IPv4OptionBuilder& optionBuilder, int offset);
723  void adjustOptionsTrailer(size_t totalOptSize);
724  void initLayer();
725  void initLayerInPacket(bool setTotalLenAsDataLen);
726  };
727 
728  // implementation of inline methods
729 
730  bool IPv4Layer::isDataValid(const uint8_t* data, size_t dataLen)
731  {
732  const iphdr* hdr = reinterpret_cast<const iphdr*>(data);
733  return dataLen >= sizeof(iphdr) && hdr->ipVersion == 4 && hdr->internetHeaderLength >= 5;
734  }
735 
736 } // 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:453
bool removeAllOptions()
IPv4Option getNextOption(IPv4Option &option) const
iphdr * getIPv4Header() const
Definition: IPv4Layer.h:506
void parseNextLayer()
uint8_t getFragmentFlags() const
IPv4Address getSrcIPv4Address() const
Definition: IPv4Layer.h:525
static bool isDataValid(const uint8_t *data, size_t dataLen)
Definition: IPv4Layer.h:730
IPv4Option addOption(const IPv4OptionBuilder &optionBuilder)
IPAddress getDstIPAddress() const
Definition: IPv4Layer.h:544
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:562
IPAddress getSrcIPAddress() const
Definition: IPv4Layer.h:516
void setSrcIPv4Address(const IPv4Address &ipAddr)
Definition: IPv4Layer.h:534
IPv4Layer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet, bool setTotalLenAsDataLen)
size_t getHeaderLen() const
Definition: IPv4Layer.h:681
bool isLastFragment() const
OsiModelLayer getOsiModelLayer() const
Definition: IPv4Layer.h:699
IPv4Layer & operator=(const IPv4Layer &other)
IPv4Address getDstIPv4Address() const
Definition: IPv4Layer.h:553
std::string toString() const
void computeCalculateFields()
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
Definition: IPv4Layer.h:393
IPv4OptionBuilder(IPv4OptionTypes optionType, const uint8_t *optionValue, uint8_t optionValueLen)
Definition: IPv4Layer.h:407
IPv4OptionBuilder(IPv4OptionTypes optionType, uint16_t optionValue)
Definition: IPv4Layer.h:419
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
~IPv4Option()
Definition: IPv4Layer.h:229
std::vector< IPv4Address > getValueAsIpList() const
Definition: IPv4Layer.h:240
IPv4OptionTypes getIPv4OptionType() const
Definition: IPv4Layer.h:321
size_t getTotalSize() const
Definition: IPv4Layer.h:350
static bool canAssign(const uint8_t *recordRawData, size_t tlvDataLen)
Definition: IPv4Layer.h:332
size_t getDataSize() const
Definition: IPv4Layer.h:362
IPv4TimestampOptionValue getTimestampOptionValue() const
Definition: IPv4Layer.h:277
Definition: Layer.h:70
Definition: Packet.h:27
Definition: TLVData.h:413
Definition: TLVData.h:23
static bool canAssign(const uint8_t *recordRawData, size_t tlvDataLen)
Definition: TLVData.h:79
Definition: TLVData.h:239
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:354
@ OsiModelNetworkLayer
Definition: ProtocolType.h:360
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