PcapPlusPlus  21.11
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  {
38 #if (BYTE_ORDER == LITTLE_ENDIAN)
39 
42  ipVersion:4;
43 #else
44 
45  uint8_t ipVersion:4,
48 #endif
49 
50  uint8_t typeOfService;
52  uint16_t totalLength;
54  uint16_t ipId;
56  uint16_t fragmentOffset;
58  uint8_t timeToLive;
60  uint8_t protocol;
62  uint16_t headerChecksum;
64  uint32_t ipSrc;
66  uint32_t ipDst;
67  /*The options start here. */
68  };
69 #pragma pack(pop)
70 
75  {
118  };
119 
120 
125  {
168  };
169 
170 #define PCPP_IP_DONT_FRAGMENT 0x40
171 #define PCPP_IP_MORE_FRAGMENTS 0x20
172 
178  {
183  {
185  TimestampOnly = 0,
187  TimestampAndIP = 1,
189  TimestampsForPrespecifiedIPs = 2,
191  Unknown = 3
192  };
193 
196 
198  std::vector<uint32_t> timestamps;
199 
201  std::vector<IPv4Address> ipAddresses;
202 
205 
209  void clear()
210  {
212  timestamps.clear();
213  ipAddresses.clear();
214  }
215  };
216 
217 
223  class IPv4Option : public TLVRecord<uint8_t, uint8_t>
224  {
225  public:
226 
231  IPv4Option(uint8_t* optionRawData) : TLVRecord(optionRawData) { }
232 
237 
244  std::vector<IPv4Address> getValueAsIpList() const
245  {
246  std::vector<IPv4Address> res;
247 
248  if (m_Data == NULL)
249  return res;
250 
251  size_t dataSize = getDataSize();
252  if (dataSize < 2)
253  return res;
254 
255  uint8_t valueOffset = (uint8_t)(1);
256 
257  while ((size_t)valueOffset < dataSize)
258  {
259  uint32_t curValue;
260  memcpy(&curValue, m_Data->recordValue + valueOffset, sizeof(uint32_t));
261  if (curValue == 0)
262  break;
263 
264  res.push_back(IPv4Address(curValue));
265 
266  valueOffset += (uint8_t)(4);
267  }
268 
269  return res;
270  }
271 
280  {
282  res.clear();
283 
284  if (m_Data == NULL)
285  return res;
286 
287  if (getIPv4OptionType() != IPV4OPT_Timestamp)
288  return res;
289 
290  size_t dataSize = getDataSize();
291  if (dataSize < 2)
292  return res;
293 
294  res.type = (IPv4TimestampOptionValue::TimestampType)m_Data->recordValue[1];
295 
296  uint8_t valueOffset = (uint8_t)(2);
297  bool readIPAddr = (res.type == IPv4TimestampOptionValue::TimestampAndIP);
298 
299  while ((size_t)valueOffset < dataSize)
300  {
301  uint32_t curValue;
302  memcpy(&curValue, m_Data->recordValue + valueOffset, sizeof(uint32_t));
303  if (curValue == 0)
304  break;
305 
306  if (readIPAddr)
307  res.ipAddresses.push_back(IPv4Address(curValue));
308  else
309  res.timestamps.push_back(curValue);
310 
312  readIPAddr = !readIPAddr;
313 
314  valueOffset += (uint8_t)(4);
315  }
316 
317  return res;
318  }
319 
324  {
325  if (m_Data == NULL)
326  return IPV4OPT_Unknown;
327 
328  return (IPv4OptionTypes)m_Data->recordType;
329  }
330 
331 
332  // implement abstract methods
333 
334  size_t getTotalSize() const
335  {
336  if (m_Data == NULL)
337  return 0;
338 
339  if (getIPv4OptionType() == (uint8_t)IPV4OPT_EndOfOptionsList || m_Data->recordType == (uint8_t)IPV4OPT_NOP)
340  return sizeof(uint8_t);
341 
342  return (size_t)m_Data->recordLen;
343  }
344 
345  size_t getDataSize() const
346  {
347  if (m_Data == NULL)
348  return 0;
349 
350  if (getIPv4OptionType() == (uint8_t)IPV4OPT_EndOfOptionsList || m_Data->recordType == (uint8_t)IPV4OPT_NOP)
351  return (size_t)0;
352 
353  return (size_t)m_Data->recordLen - (2*sizeof(uint8_t));
354  }
355  };
356 
357 
364  {
365  private:
366  bool m_BuilderParamsValid;
367 
368  public:
369 
379  IPv4OptionBuilder(IPv4OptionTypes optionType, const uint8_t* optionValue, uint8_t optionValueLen) :
380  TLVRecordBuilder((uint8_t)optionType, optionValue, optionValueLen) { m_BuilderParamsValid = true; }
381 
388  IPv4OptionBuilder(IPv4OptionTypes optionType, uint16_t optionValue) :
389  TLVRecordBuilder((uint8_t)optionType, optionValue) { m_BuilderParamsValid = true; }
390 
398  IPv4OptionBuilder(IPv4OptionTypes optionType, const std::vector<IPv4Address>& ipList);
399 
404  IPv4OptionBuilder(const IPv4TimestampOptionValue& timestampValue);
405 
410  IPv4Option build() const;
411  };
412 
413 
418  class IPv4Layer : public Layer, public IPLayer
419  {
420  public:
428  IPv4Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
429 
441  IPv4Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet, bool setTotalLenAsDataLen);
442 
443 
447  IPv4Layer();
448 
454  IPv4Layer(const IPv4Address& srcIP, const IPv4Address& dstIP);
455 
459  IPv4Layer(const IPv4Layer& other);
460 
464  IPv4Layer& operator=(const IPv4Layer& other);
465 
470  iphdr* getIPv4Header() const { return (iphdr*)m_Data; }
471 
477  IPAddress getSrcIPAddress() const { return getSrcIPv4Address(); }
478 
482  PCPP_DEPRECATED IPv4Address getSrcIpAddress() const { return getSrcIPv4Address(); }
483 
488  IPv4Address getSrcIPv4Address() const { return getIPv4Header()->ipSrc; }
489 
494  void setSrcIPv4Address(const IPv4Address& ipAddr) { getIPv4Header()->ipSrc = ipAddr.toInt(); }
495 
501  IPAddress getDstIPAddress() const { return getDstIPv4Address(); }
502 
506  PCPP_DEPRECATED IPv4Address getDstIpAddress() const { return getDstIPv4Address(); }
507 
512  IPv4Address getDstIPv4Address() const { return getIPv4Header()->ipDst; }
513 
518  void setDstIPv4Address(const IPv4Address& ipAddr) { getIPv4Header()->ipDst = ipAddr.toInt(); }
519 
523  bool isFragment() const;
524 
529  bool isFirstFragment() const;
530 
535  bool isLastFragment() const;
536 
540  uint8_t getFragmentFlags() const;
541 
545  uint16_t getFragmentOffset() const;
546 
553  IPv4Option getOption(IPv4OptionTypes option) const;
554 
559  IPv4Option getFirstOption() const;
560 
568  IPv4Option getNextOption(IPv4Option& option) const;
569 
573  size_t getOptionCount() const;
574 
582  IPv4Option addOption(const IPv4OptionBuilder& optionBuilder);
583 
593  IPv4Option addOptionAfter(const IPv4OptionBuilder& optionBuilder, IPv4OptionTypes prevOptionType = IPV4OPT_Unknown);
594 
601  bool removeOption(IPv4OptionTypes option);
602 
607  bool removeAllOptions();
608 
609 
610  // implement abstract methods
611 
626  void parseNextLayer();
627 
631  size_t getHeaderLen() const { return (size_t)((uint16_t)(getIPv4Header()->internetHeaderLength) * 4) + m_TempHeaderExtension; }
632 
640  void computeCalculateFields();
641 
642  std::string toString() const;
643 
645 
652  static inline bool isDataValid(const uint8_t* data, size_t dataLen);
653 
654  private:
655  int m_NumOfTrailingBytes;
656  int m_TempHeaderExtension;
657  TLVRecordReader<IPv4Option> m_OptionReader;
658 
659  void copyLayerData(const IPv4Layer& other);
660  uint8_t* getOptionsBasePtr() const { return m_Data + sizeof(iphdr); }
661  IPv4Option addOptionAt(const IPv4OptionBuilder& optionBuilder, int offset);
662  void adjustOptionsTrailer(size_t totalOptSize);
663  void initLayer();
664  void initLayerInPacket(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet, bool setTotalLenAsDataLen);
665  };
666 
667 
668  // implementation of inline methods
669 
670  bool IPv4Layer::isDataValid(const uint8_t* data, size_t dataLen)
671  {
672  const iphdr* hdr = reinterpret_cast<const iphdr*>(data);
673  return dataLen >= sizeof(iphdr) && hdr->ipVersion == 4 && hdr->internetHeaderLength >= 5;
674  }
675 
676 } // namespace pcpp
677 
678 #endif /* PACKETPP_IPV4_LAYER */
Definition: IPv4Layer.h:115
The main namespace for the PcapPlusPlus lib.
OsiModelLayer
Definition: ProtocolType.h:258
size_t getTotalSize() const
Definition: IPv4Layer.h:334
Definition: IPv4Layer.h:111
std::vector< uint32_t > timestamps
Definition: IPv4Layer.h:198
Definition: IPv4Layer.h:143
uint16_t ipId
Definition: IPv4Layer.h:54
Definition: IPv4Layer.h:139
Definition: IPv4Layer.h:145
IPv4Option(uint8_t *optionRawData)
Definition: IPv4Layer.h:231
uint8_t timeToLive
Definition: IPv4Layer.h:58
uint8_t internetHeaderLength
Definition: IPv4Layer.h:40
Definition: IPv4Layer.h:83
uint8_t typeOfService
Definition: IPv4Layer.h:50
Definition: IPv4Layer.h:129
Definition: IPv4Layer.h:109
Definition: IPv4Layer.h:151
Definition: TLVData.h:363
Definition: IPv4Layer.h:161
Definition: Layer.h:70
Definition: IPv4Layer.h:153
Definition: IPv4Layer.h:165
Definition: TLVData.h:24
Definition: IPLayer.h:22
IPAddress getDstIPAddress() const
Definition: IPv4Layer.h:501
Definition: Packet.h:26
Definition: IPv4Layer.h:137
IPv4OptionTypes getIPv4OptionType() const
Definition: IPv4Layer.h:323
TimestampType
Definition: IPv4Layer.h:182
void setSrcIPv4Address(const IPv4Address &ipAddr)
Definition: IPv4Layer.h:494
Definition: IPv4Layer.h:127
Definition: IPv4Layer.h:81
std::vector< IPv4Address > getValueAsIpList() const
Definition: IPv4Layer.h:244
Definition: TLVData.h:207
Definition: IPv4Layer.h:103
IPProtocolTypes
Definition: IPv4Layer.h:74
Definition: IPv4Layer.h:93
Definition: ProtocolType.h:265
Definition: IPv4Layer.h:101
Definition: IPv4Layer.h:159
Definition: IPv4Layer.h:363
uint16_t totalLength
Definition: IPv4Layer.h:52
IPv4Address getSrcIPv4Address() const
Definition: IPv4Layer.h:488
Definition: IPv4Layer.h:95
Definition: IPv4Layer.h:36
Definition: IPv4Layer.h:99
Definition: IPv4Layer.h:191
IPv4OptionBuilder(IPv4OptionTypes optionType, const uint8_t *optionValue, uint8_t optionValueLen)
Definition: IPv4Layer.h:379
Definition: IPv4Layer.h:163
Definition: IPv4Layer.h:131
Definition: IPv4Layer.h:85
Definition: IpAddress.h:27
IPv4TimestampOptionValue getTimestampOptionValue() const
Definition: IPv4Layer.h:279
uint16_t fragmentOffset
Definition: IPv4Layer.h:56
IPAddress getSrcIPAddress() const
Definition: IPv4Layer.h:477
std::vector< IPv4Address > ipAddresses
Definition: IPv4Layer.h:201
Definition: IPv4Layer.h:223
Definition: IPv4Layer.h:149
Definition: IPv4Layer.h:107
Definition: IPv4Layer.h:133
void setDstIPv4Address(const IPv4Address &ipAddr)
Definition: IPv4Layer.h:518
uint8_t ipVersion
Definition: IPv4Layer.h:40
OsiModelLayer getOsiModelLayer() const
Definition: IPv4Layer.h:644
uint8_t protocol
Definition: IPv4Layer.h:60
Definition: IPv4Layer.h:141
Definition: IPv4Layer.h:177
TimestampType type
Definition: IPv4Layer.h:195
Definition: IPv4Layer.h:91
IPv4TimestampOptionValue()
Definition: IPv4Layer.h:204
uint16_t headerChecksum
Definition: IPv4Layer.h:62
~IPv4Option()
Definition: IPv4Layer.h:236
void clear()
Definition: IPv4Layer.h:209
size_t getDataSize() const
Definition: IPv4Layer.h:345
Definition: IPv4Layer.h:105
IPv4OptionBuilder(IPv4OptionTypes optionType, uint16_t optionValue)
Definition: IPv4Layer.h:388
Definition: IPv4Layer.h:113
uint32_t ipDst
Definition: IPv4Layer.h:66
static bool isDataValid(const uint8_t *data, size_t dataLen)
Definition: IPv4Layer.h:670
Definition: IPv4Layer.h:97
Definition: IPv4Layer.h:418
IPv4Address getDstIPv4Address() const
Definition: IPv4Layer.h:512
Definition: IpAddress.h:278
Definition: IPv4Layer.h:157
Definition: IPv4Layer.h:117
Definition: IPv4Layer.h:147
Definition: IPv4Layer.h:135
Definition: IPv4Layer.h:77
uint32_t ipSrc
Definition: IPv4Layer.h:64
Definition: IPv4Layer.h:79
Definition: IPv4Layer.h:87
IPv4OptionTypes
Definition: IPv4Layer.h:124
uint32_t toInt() const
Definition: IpAddress.h:156
size_t getHeaderLen() const
Definition: IPv4Layer.h:631
Definition: IPv4Layer.h:89
Definition: IPv4Layer.h:167
Definition: IPv4Layer.h:155
iphdr * getIPv4Header() const
Definition: IPv4Layer.h:470