PcapPlusPlus  20.08+
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 
11 #ifndef PCPP_DEPRECATED
12 #if defined(__GNUC__) || defined(__clang__)
13 #define PCPP_DEPRECATED __attribute__((deprecated))
14 #elif defined(_MSC_VER)
15 #define PCPP_DEPRECATED __declspec(deprecated)
16 #else
17 #pragma message("WARNING: DEPRECATED feature is not implemented for this compiler")
18 #define PCPP_DEPRECATED
19 #endif
20 #endif
21 
23 
28 namespace pcpp
29 {
30 
35 #pragma pack(push, 1)
36  struct iphdr {
37 #if (BYTE_ORDER == LITTLE_ENDIAN)
38 
41  ipVersion:4;
42 #else
43 
44  uint8_t ipVersion:4,
47 #endif
48 
49  uint8_t typeOfService;
51  uint16_t totalLength;
53  uint16_t ipId;
55  uint16_t fragmentOffset;
57  uint8_t timeToLive;
59  uint8_t protocol;
61  uint16_t headerChecksum;
63  uint32_t ipSrc;
65  uint32_t ipDst;
66  /*The options start here. */
67  };
68 #pragma pack(pop)
69 
74  {
117  };
118 
119 
124  {
167  };
168 
169 #define PCPP_IP_DONT_FRAGMENT 0x40
170 #define PCPP_IP_MORE_FRAGMENTS 0x20
171 
177  {
182  {
184  TimestampOnly = 0,
186  TimestampAndIP = 1,
188  TimestampsForPrespecifiedIPs = 2,
190  Unknown = 3
191  };
192 
195 
197  std::vector<uint32_t> timestamps;
198 
200  std::vector<IPv4Address> ipAddresses;
201 
204 
208  void clear()
209  {
211  timestamps.clear();
212  ipAddresses.clear();
213  }
214  };
215 
216 
222  class IPv4Option : public TLVRecord
223  {
224  public:
225 
230  IPv4Option(uint8_t* optionRawData) : TLVRecord(optionRawData) { }
231 
236 
243  std::vector<IPv4Address> getValueAsIpList() const
244  {
245  std::vector<IPv4Address> res;
246 
247  if (m_Data == NULL)
248  return res;
249 
250  size_t dataSize = getDataSize();
251  if (dataSize < 2)
252  return res;
253 
254  uint8_t valueOffset = (uint8_t)(1);
255 
256  while ((size_t)valueOffset < dataSize)
257  {
258  uint32_t curValue;
259  memcpy(&curValue, m_Data->recordValue + valueOffset, sizeof(uint32_t));
260  if (curValue == 0)
261  break;
262 
263  res.push_back(IPv4Address(curValue));
264 
265  valueOffset += (uint8_t)(4);
266  }
267 
268  return res;
269  }
270 
279  {
281  res.clear();
282 
283  if (m_Data == NULL)
284  return res;
285 
286  if (getIPv4OptionType() != IPV4OPT_Timestamp)
287  return res;
288 
289  size_t dataSize = getDataSize();
290  if (dataSize < 2)
291  return res;
292 
293  res.type = (IPv4TimestampOptionValue::TimestampType)m_Data->recordValue[1];
294 
295  uint8_t valueOffset = (uint8_t)(2);
296  bool readIPAddr = (res.type == IPv4TimestampOptionValue::TimestampAndIP);
297 
298  while ((size_t)valueOffset < dataSize)
299  {
300  uint32_t curValue;
301  memcpy(&curValue, m_Data->recordValue + valueOffset, sizeof(uint32_t));
302  if (curValue == 0)
303  break;
304 
305  if (readIPAddr)
306  res.ipAddresses.push_back(IPv4Address(curValue));
307  else
308  res.timestamps.push_back(curValue);
309 
311  readIPAddr = !readIPAddr;
312 
313  valueOffset += (uint8_t)(4);
314  }
315 
316  return res;
317  }
318 
323  {
324  if (m_Data == NULL)
325  return IPV4OPT_Unknown;
326 
327  return (IPv4OptionTypes)m_Data->recordType;
328  }
329 
330 
331  // implement abstract methods
332 
333  size_t getTotalSize() const
334  {
335  if (m_Data == NULL)
336  return 0;
337 
338  if (getIPv4OptionType() == (uint8_t)IPV4OPT_EndOfOptionsList || m_Data->recordType == (uint8_t)IPV4OPT_NOP)
339  return sizeof(uint8_t);
340 
341  return (size_t)m_Data->recordLen;
342  }
343 
344  size_t getDataSize() const
345  {
346  if (m_Data == NULL)
347  return 0;
348 
349  if (getIPv4OptionType() == (uint8_t)IPV4OPT_EndOfOptionsList || m_Data->recordType == (uint8_t)IPV4OPT_NOP)
350  return (size_t)0;
351 
352  return (size_t)m_Data->recordLen - (2*sizeof(uint8_t));
353  }
354  };
355 
356 
363  {
364  private:
365  bool m_BuilderParamsValid;
366 
367  public:
368 
378  IPv4OptionBuilder(IPv4OptionTypes optionType, const uint8_t* optionValue, uint8_t optionValueLen) :
379  TLVRecordBuilder((uint8_t)optionType, optionValue, optionValueLen) { m_BuilderParamsValid = true; }
380 
387  IPv4OptionBuilder(IPv4OptionTypes optionType, uint16_t optionValue) :
388  TLVRecordBuilder((uint8_t)optionType, optionValue) { m_BuilderParamsValid = true; }
389 
397  IPv4OptionBuilder(IPv4OptionTypes optionType, const std::vector<IPv4Address>& ipList);
398 
403  IPv4OptionBuilder(const IPv4TimestampOptionValue& timestampValue);
404 
409  IPv4Option build() const;
410  };
411 
412 
417  class IPv4Layer : public Layer, public IPLayer
418  {
419  public:
427  IPv4Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
428 
440  IPv4Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet, bool setTotalLenAsDataLen);
441 
442 
446  IPv4Layer();
447 
453  IPv4Layer(const IPv4Address& srcIP, const IPv4Address& dstIP);
454 
458  IPv4Layer(const IPv4Layer& other);
459 
463  IPv4Layer& operator=(const IPv4Layer& other);
464 
469  iphdr* getIPv4Header() const { return (iphdr*)m_Data; }
470 
476  IPAddress getSrcIPAddress() const { return getSrcIPv4Address(); }
477 
481  PCPP_DEPRECATED IPv4Address getSrcIpAddress() const { return getSrcIPv4Address(); }
482 
487  IPv4Address getSrcIPv4Address() const { return getIPv4Header()->ipSrc; }
488 
493  void setSrcIPv4Address(const IPv4Address& ipAddr) { getIPv4Header()->ipSrc = ipAddr.toInt(); }
494 
500  IPAddress getDstIPAddress() const { return getDstIPv4Address(); }
501 
505  PCPP_DEPRECATED IPv4Address getDstIpAddress() const { return getDstIPv4Address(); }
506 
511  IPv4Address getDstIPv4Address() const { return getIPv4Header()->ipDst; }
512 
517  void setDstIPv4Address(const IPv4Address& ipAddr) { getIPv4Header()->ipDst = ipAddr.toInt(); }
518 
522  bool isFragment() const;
523 
528  bool isFirstFragment() const;
529 
534  bool isLastFragment() const;
535 
539  uint8_t getFragmentFlags() const;
540 
544  uint16_t getFragmentOffset() const;
545 
552  IPv4Option getOption(IPv4OptionTypes option) const;
553 
558  IPv4Option getFirstOption() const;
559 
567  IPv4Option getNextOption(IPv4Option& option) const;
568 
572  size_t getOptionCount() const;
573 
581  IPv4Option addOption(const IPv4OptionBuilder& optionBuilder);
582 
592  IPv4Option addOptionAfter(const IPv4OptionBuilder& optionBuilder, IPv4OptionTypes prevOptionType = IPV4OPT_Unknown);
593 
600  bool removeOption(IPv4OptionTypes option);
601 
606  bool removeAllOptions();
607 
608 
609  // implement abstract methods
610 
625  void parseNextLayer();
626 
630  size_t getHeaderLen() const { return (size_t)((uint16_t)(getIPv4Header()->internetHeaderLength) * 4) + m_TempHeaderExtension; }
631 
639  void computeCalculateFields();
640 
641  std::string toString() const;
642 
644 
651  static inline bool isDataValid(const uint8_t* data, size_t dataLen);
652 
653  private:
654  int m_NumOfTrailingBytes;
655  int m_TempHeaderExtension;
656  TLVRecordReader<IPv4Option> m_OptionReader;
657 
658  void copyLayerData(const IPv4Layer& other);
659  uint8_t* getOptionsBasePtr() const { return m_Data + sizeof(iphdr); }
660  IPv4Option addOptionAt(const IPv4OptionBuilder& optionBuilder, int offset);
661  void adjustOptionsTrailer(size_t totalOptSize);
662  void initLayer();
663  void initLayerInPacket(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet, bool setTotalLenAsDataLen);
664  };
665 
666 
667  // implementation of inline methods
668 
669  bool IPv4Layer::isDataValid(const uint8_t* data, size_t dataLen)
670  {
671  const iphdr* hdr = reinterpret_cast<const iphdr*>(data);
672  return dataLen >= sizeof(iphdr) && hdr->ipVersion == 4 && hdr->internetHeaderLength >= 5;
673  }
674 
675 } // namespace pcpp
676 
677 #endif /* PACKETPP_IPV4_LAYER */
Definition: IPv4Layer.h:114
The main namespace for the PcapPlusPlus lib.
OsiModelLayer
Definition: ProtocolType.h:253
size_t getTotalSize() const
Definition: IPv4Layer.h:333
Definition: IPv4Layer.h:110
std::vector< uint32_t > timestamps
Definition: IPv4Layer.h:197
Definition: IPv4Layer.h:142
uint16_t ipId
Definition: IPv4Layer.h:53
Definition: IPv4Layer.h:138
Definition: IPv4Layer.h:144
IPv4Option(uint8_t *optionRawData)
Definition: IPv4Layer.h:230
uint8_t timeToLive
Definition: IPv4Layer.h:57
uint8_t internetHeaderLength
Definition: IPv4Layer.h:39
Definition: IPv4Layer.h:82
uint8_t typeOfService
Definition: IPv4Layer.h:49
Definition: IPv4Layer.h:128
Definition: IPv4Layer.h:108
Definition: IPv4Layer.h:150
Definition: TLVData.h:351
Definition: IPv4Layer.h:160
Definition: Layer.h:70
Definition: IPv4Layer.h:152
Definition: IPv4Layer.h:164
Definition: TLVData.h:23
Definition: IPLayer.h:22
IPAddress getDstIPAddress() const
Definition: IPv4Layer.h:500
Definition: Packet.h:26
Definition: IPv4Layer.h:136
IPv4OptionTypes getIPv4OptionType() const
Definition: IPv4Layer.h:322
TimestampType
Definition: IPv4Layer.h:181
void setSrcIPv4Address(const IPv4Address &ipAddr)
Definition: IPv4Layer.h:493
Definition: IPv4Layer.h:126
Definition: IPv4Layer.h:80
std::vector< IPv4Address > getValueAsIpList() const
Definition: IPv4Layer.h:243
Definition: TLVData.h:197
Definition: IPv4Layer.h:102
IPProtocolTypes
Definition: IPv4Layer.h:73
Definition: IPv4Layer.h:92
Definition: ProtocolType.h:260
Definition: IPv4Layer.h:100
Definition: IPv4Layer.h:158
Definition: IPv4Layer.h:362
uint16_t totalLength
Definition: IPv4Layer.h:51
IPv4Address getSrcIPv4Address() const
Definition: IPv4Layer.h:487
Definition: IPv4Layer.h:94
Definition: IPv4Layer.h:36
Definition: IPv4Layer.h:98
Definition: IPv4Layer.h:190
IPv4OptionBuilder(IPv4OptionTypes optionType, const uint8_t *optionValue, uint8_t optionValueLen)
Definition: IPv4Layer.h:378
Definition: IPv4Layer.h:162
Definition: IPv4Layer.h:130
Definition: IPv4Layer.h:84
Definition: IpAddress.h:26
IPv4TimestampOptionValue getTimestampOptionValue() const
Definition: IPv4Layer.h:278
uint16_t fragmentOffset
Definition: IPv4Layer.h:55
IPAddress getSrcIPAddress() const
Definition: IPv4Layer.h:476
std::vector< IPv4Address > ipAddresses
Definition: IPv4Layer.h:200
Definition: IPv4Layer.h:222
Definition: IPv4Layer.h:148
Definition: IPv4Layer.h:106
Definition: IPv4Layer.h:132
void setDstIPv4Address(const IPv4Address &ipAddr)
Definition: IPv4Layer.h:517
uint8_t ipVersion
Definition: IPv4Layer.h:39
OsiModelLayer getOsiModelLayer() const
Definition: IPv4Layer.h:643
uint8_t protocol
Definition: IPv4Layer.h:59
Definition: IPv4Layer.h:140
Definition: IPv4Layer.h:176
TimestampType type
Definition: IPv4Layer.h:194
Definition: IPv4Layer.h:90
IPv4TimestampOptionValue()
Definition: IPv4Layer.h:203
uint16_t headerChecksum
Definition: IPv4Layer.h:61
~IPv4Option()
Definition: IPv4Layer.h:235
void clear()
Definition: IPv4Layer.h:208
size_t getDataSize() const
Definition: IPv4Layer.h:344
Definition: IPv4Layer.h:104
IPv4OptionBuilder(IPv4OptionTypes optionType, uint16_t optionValue)
Definition: IPv4Layer.h:387
Definition: IPv4Layer.h:112
uint32_t ipDst
Definition: IPv4Layer.h:65
static bool isDataValid(const uint8_t *data, size_t dataLen)
Definition: IPv4Layer.h:669
Definition: IPv4Layer.h:96
Definition: IPv4Layer.h:417
IPv4Address getDstIPv4Address() const
Definition: IPv4Layer.h:511
Definition: IpAddress.h:265
Definition: IPv4Layer.h:156
Definition: IPv4Layer.h:116
Definition: IPv4Layer.h:146
Definition: IPv4Layer.h:134
Definition: IPv4Layer.h:76
uint32_t ipSrc
Definition: IPv4Layer.h:63
Definition: IPv4Layer.h:78
Definition: IPv4Layer.h:86
IPv4OptionTypes
Definition: IPv4Layer.h:123
uint32_t toInt() const
Definition: IpAddress.h:149
size_t getHeaderLen() const
Definition: IPv4Layer.h:630
Definition: IPv4Layer.h:88
Definition: IPv4Layer.h:166
Definition: IPv4Layer.h:154
iphdr * getIPv4Header() const
Definition: IPv4Layer.h:469