PcapPlusPlus  23.09
IPv4Layer.h
Go to the documentation of this file.
1 #ifndef PACKETPP_IPV4_LAYER
2 #define PACKETPP_IPV4_LAYER
3 
4 #include "Layer.h"
5 #include "TLVData.h"
6 #include "IpAddress.h"
7 #include "IPLayer.h"
8 #include <string.h>
9 #include <vector>
10 
12 
17 namespace pcpp
18 {
19 
24 #pragma pack(push, 1)
25  struct iphdr
26  {
27 #if (BYTE_ORDER == LITTLE_ENDIAN)
28 
31  ipVersion:4;
32 #else
33 
34  uint8_t ipVersion:4,
37 #endif
38 
39  uint8_t typeOfService;
41  uint16_t totalLength;
43  uint16_t ipId;
45  uint16_t fragmentOffset;
47  uint8_t timeToLive;
49  uint8_t protocol;
51  uint16_t headerChecksum;
53  uint32_t ipSrc;
55  uint32_t ipDst;
56  /*The options start here. */
57  };
58 #pragma pack(pop)
59 
64  {
109  };
110 
111 
116  {
159  };
160 
161 #define PCPP_IP_DONT_FRAGMENT 0x40
162 #define PCPP_IP_MORE_FRAGMENTS 0x20
163 
169  {
174  {
176  TimestampOnly = 0,
178  TimestampAndIP = 1,
180  TimestampsForPrespecifiedIPs = 2,
182  Unknown = 3
183  };
184 
187 
189  std::vector<uint32_t> timestamps;
190 
192  std::vector<IPv4Address> ipAddresses;
193 
196 
200  void clear()
201  {
203  timestamps.clear();
204  ipAddresses.clear();
205  }
206  };
207 
208 
214  class IPv4Option : public TLVRecord<uint8_t, uint8_t>
215  {
216  public:
217 
222  explicit IPv4Option(uint8_t* optionRawData) : TLVRecord(optionRawData) { }
223 
228 
235  std::vector<IPv4Address> getValueAsIpList() const
236  {
237  std::vector<IPv4Address> res;
238 
239  if (m_Data == nullptr)
240  return res;
241 
242  size_t dataSize = getDataSize();
243  if (dataSize < 2)
244  return res;
245 
246  uint8_t valueOffset = (uint8_t)(1);
247 
248  while ((size_t)valueOffset < dataSize)
249  {
250  uint32_t curValue;
251  memcpy(&curValue, m_Data->recordValue + valueOffset, sizeof(uint32_t));
252  if (curValue == 0)
253  break;
254 
255  res.push_back(IPv4Address(curValue));
256 
257  valueOffset += (uint8_t)(4);
258  }
259 
260  return res;
261  }
262 
271  {
273  res.clear();
274 
275  if (m_Data == nullptr)
276  return res;
277 
278  if (getIPv4OptionType() != IPV4OPT_Timestamp)
279  return res;
280 
281  size_t dataSize = getDataSize();
282  if (dataSize < 2)
283  return res;
284 
285  res.type = (IPv4TimestampOptionValue::TimestampType)m_Data->recordValue[1];
286 
287  uint8_t valueOffset = (uint8_t)(2);
288  bool readIPAddr = (res.type == IPv4TimestampOptionValue::TimestampAndIP);
289 
290  while ((size_t)valueOffset < dataSize)
291  {
292  uint32_t curValue;
293  memcpy(&curValue, m_Data->recordValue + valueOffset, sizeof(uint32_t));
294  if (curValue == 0)
295  break;
296 
297  if (readIPAddr)
298  res.ipAddresses.push_back(IPv4Address(curValue));
299  else
300  res.timestamps.push_back(curValue);
301 
303  readIPAddr = !readIPAddr;
304 
305  valueOffset += (uint8_t)(4);
306  }
307 
308  return res;
309  }
310 
315  {
316  if (m_Data == nullptr)
317  return IPV4OPT_Unknown;
318 
319  return (IPv4OptionTypes)m_Data->recordType;
320  }
321 
322 
323  // implement abstract methods
324 
325  size_t getTotalSize() const
326  {
327  if (m_Data == nullptr)
328  return 0;
329 
330  if (getIPv4OptionType() == (uint8_t)IPV4OPT_EndOfOptionsList || m_Data->recordType == (uint8_t)IPV4OPT_NOP)
331  return sizeof(uint8_t);
332 
333  return (size_t)m_Data->recordLen;
334  }
335 
336  size_t getDataSize() const
337  {
338  if (m_Data == nullptr)
339  return 0;
340 
341  if (getIPv4OptionType() == (uint8_t)IPV4OPT_EndOfOptionsList || m_Data->recordType == (uint8_t)IPV4OPT_NOP)
342  return (size_t)0;
343 
344  return (size_t)m_Data->recordLen - (2*sizeof(uint8_t));
345  }
346  };
347 
348 
355  {
356  private:
357  bool m_BuilderParamsValid;
358 
359  public:
360 
370  IPv4OptionBuilder(IPv4OptionTypes optionType, const uint8_t* optionValue, uint8_t optionValueLen) :
371  TLVRecordBuilder((uint8_t)optionType, optionValue, optionValueLen) { m_BuilderParamsValid = true; }
372 
379  IPv4OptionBuilder(IPv4OptionTypes optionType, uint16_t optionValue) :
380  TLVRecordBuilder((uint8_t)optionType, optionValue) { m_BuilderParamsValid = true; }
381 
389  IPv4OptionBuilder(IPv4OptionTypes optionType, const std::vector<IPv4Address>& ipList);
390 
395  explicit IPv4OptionBuilder(const IPv4TimestampOptionValue& timestampValue);
396 
401  IPv4Option build() const;
402  };
403 
404 
409  class IPv4Layer : public Layer, public IPLayer
410  {
411  public:
419  IPv4Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
420 
432  IPv4Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet, bool setTotalLenAsDataLen);
433 
434 
438  IPv4Layer();
439 
445  IPv4Layer(const IPv4Address& srcIP, const IPv4Address& dstIP);
446 
450  IPv4Layer(const IPv4Layer& other);
451 
455  IPv4Layer& operator=(const IPv4Layer& other);
456 
461  iphdr* getIPv4Header() const { return (iphdr*)m_Data; }
462 
468  IPAddress getSrcIPAddress() const { return getSrcIPv4Address(); }
469 
474  IPv4Address getSrcIPv4Address() const { return getIPv4Header()->ipSrc; }
475 
480  void setSrcIPv4Address(const IPv4Address& ipAddr) { getIPv4Header()->ipSrc = ipAddr.toInt(); }
481 
487  IPAddress getDstIPAddress() const { return getDstIPv4Address(); }
488 
493  IPv4Address getDstIPv4Address() const { return getIPv4Header()->ipDst; }
494 
499  void setDstIPv4Address(const IPv4Address& ipAddr) { getIPv4Header()->ipDst = ipAddr.toInt(); }
500 
504  bool isFragment() const;
505 
510  bool isFirstFragment() const;
511 
516  bool isLastFragment() const;
517 
521  uint8_t getFragmentFlags() const;
522 
526  uint16_t getFragmentOffset() const;
527 
534  IPv4Option getOption(IPv4OptionTypes option) const;
535 
540  IPv4Option getFirstOption() const;
541 
549  IPv4Option getNextOption(IPv4Option& option) const;
550 
554  size_t getOptionCount() const;
555 
563  IPv4Option addOption(const IPv4OptionBuilder& optionBuilder);
564 
574  IPv4Option addOptionAfter(const IPv4OptionBuilder& optionBuilder, IPv4OptionTypes prevOptionType = IPV4OPT_Unknown);
575 
582  bool removeOption(IPv4OptionTypes option);
583 
588  bool removeAllOptions();
589 
590 
591  // implement abstract methods
592 
607  void parseNextLayer();
608 
612  size_t getHeaderLen() const { return (size_t)((uint16_t)(getIPv4Header()->internetHeaderLength) * 4) + m_TempHeaderExtension; }
613 
621  void computeCalculateFields();
622 
623  std::string toString() const;
624 
626 
633  static inline bool isDataValid(const uint8_t* data, size_t dataLen);
634 
635  private:
636  int m_NumOfTrailingBytes;
637  int m_TempHeaderExtension;
638  TLVRecordReader<IPv4Option> m_OptionReader;
639 
640  void copyLayerData(const IPv4Layer& other);
641  uint8_t* getOptionsBasePtr() const { return m_Data + sizeof(iphdr); }
642  IPv4Option addOptionAt(const IPv4OptionBuilder& optionBuilder, int offset);
643  void adjustOptionsTrailer(size_t totalOptSize);
644  void initLayer();
645  void initLayerInPacket(bool setTotalLenAsDataLen);
646  };
647 
648 
649  // implementation of inline methods
650 
651  bool IPv4Layer::isDataValid(const uint8_t* data, size_t dataLen)
652  {
653  const iphdr* hdr = reinterpret_cast<const iphdr*>(data);
654  return dataLen >= sizeof(iphdr) && hdr->ipVersion == 4 && hdr->internetHeaderLength >= 5;
655  }
656 
657 } // namespace pcpp
658 
659 #endif /* PACKETPP_IPV4_LAYER */
Definition: IPv4Layer.h:106
The main namespace for the PcapPlusPlus lib.
OsiModelLayer
Definition: ProtocolType.h:333
size_t getTotalSize() const
Definition: IPv4Layer.h:325
Definition: IPv4Layer.h:100
std::vector< uint32_t > timestamps
Definition: IPv4Layer.h:189
Definition: IPv4Layer.h:134
uint16_t ipId
Definition: IPv4Layer.h:43
Definition: IPv4Layer.h:130
Definition: IPv4Layer.h:136
IPv4Option(uint8_t *optionRawData)
Definition: IPv4Layer.h:222
uint8_t timeToLive
Definition: IPv4Layer.h:47
uint8_t internetHeaderLength
Definition: IPv4Layer.h:29
Definition: IPv4Layer.h:72
uint8_t typeOfService
Definition: IPv4Layer.h:39
Definition: IPv4Layer.h:120
Definition: IPv4Layer.h:104
Definition: IPv4Layer.h:98
Definition: IPv4Layer.h:142
Definition: TLVData.h:376
Definition: IPv4Layer.h:152
Definition: Layer.h:70
Definition: IPv4Layer.h:144
Definition: IPv4Layer.h:156
Definition: TLVData.h:24
Definition: IPLayer.h:22
IPAddress getDstIPAddress() const
Definition: IPv4Layer.h:487
Definition: Packet.h:26
Definition: IPv4Layer.h:128
IPv4OptionTypes getIPv4OptionType() const
Definition: IPv4Layer.h:314
TimestampType
Definition: IPv4Layer.h:173
void setSrcIPv4Address(const IPv4Address &ipAddr)
Definition: IPv4Layer.h:480
Definition: IPv4Layer.h:118
Definition: IPv4Layer.h:70
std::vector< IPv4Address > getValueAsIpList() const
Definition: IPv4Layer.h:235
Definition: TLVData.h:217
Definition: IPv4Layer.h:92
IPProtocolTypes
Definition: IPv4Layer.h:63
Definition: IPv4Layer.h:82
Definition: ProtocolType.h:340
Definition: IPv4Layer.h:90
Definition: IPv4Layer.h:150
Definition: IPv4Layer.h:354
uint16_t totalLength
Definition: IPv4Layer.h:41
IPv4Address getSrcIPv4Address() const
Definition: IPv4Layer.h:474
Definition: IPv4Layer.h:84
Definition: IPv4Layer.h:25
Definition: IPv4Layer.h:88
Definition: IPv4Layer.h:182
IPv4OptionBuilder(IPv4OptionTypes optionType, const uint8_t *optionValue, uint8_t optionValueLen)
Definition: IPv4Layer.h:370
Definition: IPv4Layer.h:154
Definition: IPv4Layer.h:122
Definition: IPv4Layer.h:74
Definition: IpAddress.h:42
IPv4TimestampOptionValue getTimestampOptionValue() const
Definition: IPv4Layer.h:270
uint16_t fragmentOffset
Definition: IPv4Layer.h:45
IPAddress getSrcIPAddress() const
Definition: IPv4Layer.h:468
std::vector< IPv4Address > ipAddresses
Definition: IPv4Layer.h:192
Definition: IPv4Layer.h:214
Definition: IPv4Layer.h:140
Definition: IPv4Layer.h:96
Definition: IPv4Layer.h:124
void setDstIPv4Address(const IPv4Address &ipAddr)
Definition: IPv4Layer.h:499
uint8_t ipVersion
Definition: IPv4Layer.h:29
OsiModelLayer getOsiModelLayer() const
Definition: IPv4Layer.h:625
uint8_t protocol
Definition: IPv4Layer.h:49
Definition: IPv4Layer.h:132
Definition: IPv4Layer.h:168
TimestampType type
Definition: IPv4Layer.h:186
Definition: IPv4Layer.h:80
IPv4TimestampOptionValue()
Definition: IPv4Layer.h:195
uint16_t headerChecksum
Definition: IPv4Layer.h:51
~IPv4Option()
Definition: IPv4Layer.h:227
void clear()
Definition: IPv4Layer.h:200
size_t getDataSize() const
Definition: IPv4Layer.h:336
Definition: IPv4Layer.h:94
IPv4OptionBuilder(IPv4OptionTypes optionType, uint16_t optionValue)
Definition: IPv4Layer.h:379
Definition: IPv4Layer.h:102
uint32_t ipDst
Definition: IPv4Layer.h:55
static bool isDataValid(const uint8_t *data, size_t dataLen)
Definition: IPv4Layer.h:651
Definition: IPv4Layer.h:86
Definition: IPv4Layer.h:409
IPv4Address getDstIPv4Address() const
Definition: IPv4Layer.h:493
Definition: IpAddress.h:321
Definition: IPv4Layer.h:148
Definition: IPv4Layer.h:108
Definition: IPv4Layer.h:138
Definition: IPv4Layer.h:126
Definition: IPv4Layer.h:66
uint32_t ipSrc
Definition: IPv4Layer.h:53
Definition: IPv4Layer.h:68
Definition: IPv4Layer.h:76
IPv4OptionTypes
Definition: IPv4Layer.h:115
uint32_t toInt() const
Definition: IpAddress.h:181
size_t getHeaderLen() const
Definition: IPv4Layer.h:612
Definition: IPv4Layer.h:78
Definition: IPv4Layer.h:158
Definition: IPv4Layer.h:146
iphdr * getIPv4Header() const
Definition: IPv4Layer.h:461