PcapPlusPlus  Next
IPv6Layer.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "Layer.h"
4 #include "IPLayer.h"
5 #include "IPv6Extensions.h"
6 #include "IpAddress.h"
7 #include <algorithm>
8 #include <iterator>
9 
11 
14 namespace pcpp
15 {
16 
19 #pragma pack(push, 1)
20  struct ip6_hdr
21  {
22 #if (BYTE_ORDER == LITTLE_ENDIAN)
24  uint8_t trafficClass : 4,
26  ipVersion : 4;
27 #else
29  uint8_t ipVersion : 4,
31  trafficClass : 4;
32 #endif
34  uint8_t flowLabel[3];
36  uint16_t payloadLength;
38  uint8_t nextHeader;
40  uint8_t hopLimit;
42  uint8_t ipSrc[16];
44  uint8_t ipDst[16];
45  };
46 #pragma pack(pop)
47  static_assert(sizeof(ip6_hdr) == 40, "ip6_hdr size is not 40 bytes");
48 
51  class IPv6Layer : public Layer, public IPLayer
52  {
53  public:
59  IPv6Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet);
60 
63 
67  IPv6Layer(const IPv6Address& srcIP, const IPv6Address& dstIP);
68 
70  IPv6Layer(const IPv6Layer& other);
71 
73  ~IPv6Layer() override;
74 
77  IPv6Layer& operator=(const IPv6Layer& other);
78 
83  {
84  return reinterpret_cast<ip6_hdr*>(m_Data);
85  }
86 
90  IPAddress getSrcIPAddress() const override
91  {
92  return getSrcIPv6Address();
93  }
94 
98  {
99  return getIPv6Header()->ipSrc;
100  }
101 
104  void setSrcIPv6Address(const IPv6Address& ipAddr)
105  {
106  ipAddr.copyTo(getIPv6Header()->ipSrc);
107  }
108 
111  void setDstIPv6Address(const IPv6Address& ipAddr)
112  {
113  ipAddr.copyTo(getIPv6Header()->ipDst);
114  }
115 
119  IPAddress getDstIPAddress() const override
120  {
121  return getDstIPv6Address();
122  }
123 
127  {
128  return getIPv6Header()->ipDst;
129  }
130 
132  size_t getExtensionCount() const;
133 
138  template <class TIPv6Extension> TIPv6Extension* getExtensionOfType() const;
139 
147  template <class TIPv6Extension> TIPv6Extension* addExtension(const TIPv6Extension& extensionHeader);
148 
151 
153  bool isFragment() const;
154 
159  static inline bool isDataValid(const uint8_t* data, size_t dataLen);
160 
161  // implement abstract methods
162 
173  void parseNextLayer() override;
174 
176  size_t getHeaderLen() const override
177  {
178  return sizeof(ip6_hdr) + m_ExtensionsLen;
179  }
180 
186  void computeCalculateFields() override;
187 
188  std::string toString() const override;
189 
191  {
192  return OsiModelNetworkLayer;
193  }
194 
199  {
201  static std::vector<FieldDescriptor> all()
202  {
203  auto result = Layer::SerializedFields::all();
204  std::initializer_list<FieldDescriptor> extra{ SrcIp, DstIp, PayloadLength,
206  std::copy(extra.begin(), extra.end(), std::back_inserter(result));
207  return result;
208  }
209 
212  struct IPv6ExtensionObject : ObjectFieldDescriptor<IPv6ExtensionObject>
213  {
215 
217  static std::vector<FieldDescriptor> all()
218  {
219  return { Name, Type };
220  }
221 
223  static const FieldDescriptor Name;
224 
226  static const FieldDescriptor Type;
227  };
228 
230  static const FieldDescriptor SrcIp;
231 
233  static const FieldDescriptor DstIp;
234 
237 
240 
243 
246  };
247 
248  protected:
249  void serializeLayer(ObjectScope& serializer) const override;
250 
251  private:
252  void initLayer();
253  void parseExtensions();
254  void deleteExtensions();
255 
256  IPv6Extension* m_FirstExtension;
257  IPv6Extension* m_LastExtension;
258  size_t m_ExtensionsLen;
259  };
260 
261  template <class TIPv6Extension> TIPv6Extension* IPv6Layer::getExtensionOfType() const
262  {
263  IPv6Extension* curExt = m_FirstExtension;
264  while (curExt != nullptr && dynamic_cast<TIPv6Extension*>(curExt) == nullptr)
265  curExt = curExt->getNextHeader();
266 
267  return static_cast<TIPv6Extension*>(curExt);
268  }
269 
270  template <class TIPv6Extension> TIPv6Extension* IPv6Layer::addExtension(const TIPv6Extension& extensionHeader)
271  {
272  int offsetToAddHeader = static_cast<int>(getHeaderLen());
273  if (!extendLayer(offsetToAddHeader, extensionHeader.getExtensionLen()))
274  {
275  return nullptr;
276  }
277 
278  TIPv6Extension* newHeader = new TIPv6Extension(this, static_cast<size_t>(offsetToAddHeader));
279  (*newHeader) = extensionHeader;
280 
281  if (m_FirstExtension != nullptr)
282  {
283  newHeader->getBaseHeader()->nextHeader = m_LastExtension->getBaseHeader()->nextHeader;
284  m_LastExtension->getBaseHeader()->nextHeader = newHeader->getExtensionType();
285  m_LastExtension->setNextHeader(newHeader);
286  m_LastExtension = newHeader;
287  }
288  else
289  {
290  m_FirstExtension = newHeader;
291  m_LastExtension = newHeader;
292  newHeader->getBaseHeader()->nextHeader = getIPv6Header()->nextHeader;
293  getIPv6Header()->nextHeader = newHeader->getExtensionType();
294  }
295 
296  m_ExtensionsLen += newHeader->getExtensionLen();
297 
298  return newHeader;
299  }
300 
301  // implementation of inline methods
302 
303  bool IPv6Layer::isDataValid(const uint8_t* data, size_t dataLen)
304  {
305  auto ip6Header = reinterpret_cast<const ip6_hdr*>(data);
306  return canReinterpretAs<ip6_hdr>(data, dataLen) && ip6Header->ipVersion == 6;
307  }
308 
309 } // namespace pcpp
Definition: IpAddress.h:318
Definition: IPLayer.h:18
Definition: IpAddress.h:165
void copyTo(uint8_t **arr, size_t &length) const
Definition: IPv6Extensions.h:18
IPv6Extension * getNextHeader() const
Definition: IPv6Extensions.h:57
Definition: IPv6Layer.h:52
IPv6Address getSrcIPv6Address() const
Definition: IPv6Layer.h:97
void serializeLayer(ObjectScope &serializer) const override
IPv6Layer(const IPv6Address &srcIP, const IPv6Address &dstIP)
IPv6Layer(const IPv6Layer &other)
A copy constructor that copies the entire header from the other IPv6Layer (including IPv6 extensions)
void parseNextLayer() override
IPv6Address getDstIPv6Address() const
Definition: IPv6Layer.h:126
void removeAllExtensions()
Remove all IPv6 extensions in this layer.
TIPv6Extension * getExtensionOfType() const
Definition: IPv6Layer.h:261
void computeCalculateFields() override
OsiModelLayer getOsiModelLayer() const override
Definition: IPv6Layer.h:190
std::string toString() const override
bool isFragment() const
ip6_hdr * getIPv6Header() const
Definition: IPv6Layer.h:82
void setDstIPv6Address(const IPv6Address &ipAddr)
Definition: IPv6Layer.h:111
size_t getHeaderLen() const override
Definition: IPv6Layer.h:176
IPv6Layer & operator=(const IPv6Layer &other)
static bool isDataValid(const uint8_t *data, size_t dataLen)
Definition: IPv6Layer.h:303
IPv6Layer()
A constructor that allocates a new IPv6 header with empty fields.
void setSrcIPv6Address(const IPv6Address &ipAddr)
Definition: IPv6Layer.h:104
IPAddress getSrcIPAddress() const override
Definition: IPv6Layer.h:90
IPv6Layer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet)
size_t getExtensionCount() const
TIPv6Extension * addExtension(const TIPv6Extension &extensionHeader)
Definition: IPv6Layer.h:270
~IPv6Layer() override
A destructor for this layer.
IPAddress getDstIPAddress() const override
Definition: IPv6Layer.h:119
Definition: Layer.h:117
Definition: Serializers.h:230
Definition: Packet.h:49
The main namespace for the PcapPlusPlus lib.
Definition: AssertionUtils.h:19
OsiModelLayer
An enum representing OSI model layers.
Definition: ProtocolType.h:420
@ OsiModelNetworkLayer
Network layer (layer 3)
Definition: ProtocolType.h:426
Definition: Serializers.h:18
static const FieldDescriptor Name
Extension type name (e.g. "Fragment", "Hop-By-Hop")
Definition: IPv6Layer.h:223
static std::vector< FieldDescriptor > all()
Definition: IPv6Layer.h:217
static const FieldDescriptor Type
Raw numeric extension type.
Definition: IPv6Layer.h:226
Definition: IPv6Layer.h:199
static std::vector< FieldDescriptor > all()
Definition: IPv6Layer.h:201
static const FieldDescriptor IsFragment
Whether this packet is a fragment.
Definition: IPv6Layer.h:239
static const FieldDescriptor NextHeader
Next Header field (first extension header, or upper-layer protocol if none)
Definition: IPv6Layer.h:242
static const FieldDescriptor PayloadLength
Payload length, in host byte order.
Definition: IPv6Layer.h:236
static const FieldDescriptor SrcIp
Source IP address, as a string.
Definition: IPv6Layer.h:230
static const FieldDescriptor Extensions
Array of extension headers; elements described by IPv6ExtensionObject.
Definition: IPv6Layer.h:245
static const FieldDescriptor DstIp
Destination IP address, as a string.
Definition: IPv6Layer.h:233
Definition: Layer.h:212
static std::vector< FieldDescriptor > all()
Definition: Layer.h:214
Definition: Serializers.h:49
ObjectFieldDescriptor(uint16_t fieldId, std::string fieldName)
Definition: Serializers.h:53
Definition: IPv6Layer.h:21
uint8_t trafficClass
Traffic class.
Definition: IPv6Layer.h:24
uint8_t flowLabel[3]
Flow label.
Definition: IPv6Layer.h:34
uint8_t hopLimit
Replaces the time to live field of IPv4.
Definition: IPv6Layer.h:40
uint8_t ipSrc[16]
Source address.
Definition: IPv6Layer.h:42
uint16_t payloadLength
The size of the payload in octets, including any extension headers.
Definition: IPv6Layer.h:36
uint8_t ipVersion
IP version number, has the value of 6 for IPv6.
Definition: IPv6Layer.h:26
uint8_t nextHeader
Specifies the type of the next header (protocol). Must be one of IPProtocolTypes.
Definition: IPv6Layer.h:38
uint8_t ipDst[16]
Destination address.
Definition: IPv6Layer.h:44