PcapPlusPlus  Next
NdpLayer.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "IcmpV6Layer.h"
4 #include "IpAddress.h"
5 #include "Layer.h"
6 #include "MacAddress.h"
7 #include "TLVData.h"
8 
9 #include <vector>
10 
12 
15 namespace pcpp
16 {
17 
19  enum class NDPNeighborOptionTypes : int
20  {
21  NDP_OPTION_SOURCE_LINK_LAYER = 1,
22  NDP_OPTION_TARGET_LINK_LAYER = 2,
23  NDP_OPTION_PREFIX_INFORMATION = 3,
24  NDP_OPTION_REDIRECTED_HEADER = 4,
25  NDP_OPTION_MTU = 5,
26  NDP_OPTION_UNKNOWN = 255
27  };
28 
32  class NdpOption : public TLVRecord<uint8_t, uint8_t>
33  {
34  public:
37  explicit NdpOption(uint8_t* optionRawData) : TLVRecord(optionRawData)
38  {}
39 
41  ~NdpOption() override = default;
42 
46  {
47  if (m_Data == nullptr)
48  return NDPNeighborOptionTypes::NDP_OPTION_UNKNOWN;
49 
50  return static_cast<NDPNeighborOptionTypes>(m_Data->recordType);
51  }
52 
53  // implement abstract methods
54 
55  size_t getTotalSize() const override
56  {
57  if (m_Data == nullptr)
58  return 0;
59 
60  return static_cast<size_t>(m_Data->recordLen) * 8;
61  }
62 
63  size_t getDataSize() const override
64  {
65  if (m_Data == nullptr)
66  {
67  return 0;
68  }
69 
70  // length value is stored in units of 8 octets
71  return static_cast<size_t>(m_Data->recordLen) * 8 - (2 * sizeof(uint8_t));
72  }
73  };
74 
79  {
80  public:
87  NdpOptionBuilder(NDPNeighborOptionTypes optionType, const uint8_t* optionValue, uint8_t optionValueLen)
88  : TLVRecordBuilder((uint8_t)optionType, optionValue, optionValueLen)
89  {}
90 
94  NdpOption build() const;
95  };
96 
99  class NDPLayerBase : public IcmpV6Layer
100  {
101  public:
102  ~NDPLayerBase() override = default;
103 
105  size_t getNdpOptionCount() const;
106 
112 
116 
123 
129  NdpOption addNdpOption(const NdpOptionBuilder& optionBuilder);
130 
135 
140  {
142  static constexpr uint16_t MaxID = IcmpV6Layer::SerializedFields::MaxID + 1;
143 
145  static std::vector<FieldDescriptor> all()
146  {
147  auto result = IcmpV6Layer::SerializedFields::all();
148  std::initializer_list<FieldDescriptor> extra{ Options };
149  std::copy(extra.begin(), extra.end(), std::back_inserter(result));
150  return result;
151  }
152 
154  static const FieldDescriptor Options;
155 
157  static const FieldDescriptor Option;
158  };
159 
160  protected:
161  NDPLayerBase() = default;
162 
163  NDPLayerBase(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
164  : IcmpV6Layer(data, dataLen, prevLayer, packet)
165  {}
166 
167  void serializeOptions(ObjectScope& serializer) const;
168 
169  private:
170  TLVRecordReader<NdpOption> m_OptionReader;
171 
172  virtual size_t getNdpHeaderLen() const = 0;
173  virtual uint8_t* getNdpOptionsBasePtr() const
174  {
175  return m_Data + getNdpHeaderLen();
176  };
177  NdpOption addNdpOptionAt(const NdpOptionBuilder& optionBuilder, int offset);
178  };
179 
183  {
184  public:
187 #pragma pack(push, 1)
189  {
191  uint32_t reserved;
193  uint8_t targetIP[16];
194  };
195 #pragma pack(pop)
196 
202  NDPNeighborSolicitationLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
203  : NDPLayerBase(data, dataLen, prevLayer, packet)
204  {}
205 
210  static bool isDataValid(const uint8_t* data, size_t dataLen)
211  {
212  return data != nullptr && dataLen >= sizeof(ndpneighborsolicitationhdr);
213  }
214 
218  NDPNeighborSolicitationLayer(uint8_t code, const IPv6Address& targetIP);
219 
224  NDPNeighborSolicitationLayer(uint8_t code, const IPv6Address& targetIP, const MacAddress& srcMac);
225 
226  ~NDPNeighborSolicitationLayer() override = default;
227 
230  {
231  return IPv6Address(getNdpHeader()->targetIP);
232  };
233 
236  bool hasLinkLayerAddress() const;
237 
241 
242  std::string toString() const override;
243 
248  {
250  static std::vector<FieldDescriptor> all()
251  {
252  auto result = NDPLayerBase::SerializedFields::all();
253  std::initializer_list<FieldDescriptor> extra{ TargetIP, LinkLayerAddress };
254  std::copy(extra.begin(), extra.end(), std::back_inserter(result));
255  return result;
256  }
257 
259  static const FieldDescriptor TargetIP;
260 
263  };
264 
265  protected:
266  void serializeLayer(ObjectScope& serializer) const override;
267 
268  private:
269  void initLayer(uint8_t code, const IPv6Address& targetIP);
270  ndpneighborsolicitationhdr* getNdpHeader() const
271  {
272  return reinterpret_cast<ndpneighborsolicitationhdr*>(m_Data);
273  }
274  size_t getNdpHeaderLen() const override
275  {
276  return sizeof(ndpneighborsolicitationhdr);
277  };
278  };
279 
283  {
284  public:
287 #pragma pack(push, 1)
289  {
290 #if (BYTE_ORDER == LITTLE_ENDIAN)
291  uint32_t
293  reserved : 5,
295  override : 1,
300  router : 1,
302  reserved2 : 24;
303 #else
304  uint32_t
306  router : 1,
309  solicited : 1,
311  override : 1,
313  reserved : 29;
314 #endif
316  uint8_t targetIP[16];
317  };
318 #pragma pack(pop)
319 
325  NDPNeighborAdvertisementLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
326  : NDPLayerBase(data, dataLen, prevLayer, packet)
327  {}
328 
333  static bool isDataValid(const uint8_t* data, size_t dataLen)
334  {
335  return data != nullptr && dataLen >= sizeof(ndpneighboradvertisementhdr);
336  }
337 
346  NDPNeighborAdvertisementLayer(uint8_t code, const IPv6Address& targetIP, const MacAddress& targetMac,
347  bool routerFlag, bool unicastFlag, bool overrideFlag);
348 
356  NDPNeighborAdvertisementLayer(uint8_t code, const IPv6Address& targetIP, bool routerFlag, bool unicastFlag,
357  bool overrideFlag);
358 
359  ~NDPNeighborAdvertisementLayer() override = default;
360 
363 
366  {
367  return IPv6Address(getNdpHeader()->targetIP);
368  }
369 
371  bool hasTargetMacInfo() const;
372 
374  bool getRouterFlag() const
375  {
376  return getNdpHeader()->router;
377  }
378 
380  bool getUnicastFlag() const
381  {
382  return getNdpHeader()->solicited;
383  }
384 
386  bool getOverrideFlag() const
387  {
388  return getNdpHeader()->override;
389  }
390 
391  std::string toString() const override;
392 
397  {
399  static std::vector<FieldDescriptor> all()
400  {
401  auto result = NDPLayerBase::SerializedFields::all();
402  std::initializer_list<FieldDescriptor> extra{ TargetIP, RouterFlag, UnicastFlag, OverrideFlag,
403  TargetMac };
404  std::copy(extra.begin(), extra.end(), std::back_inserter(result));
405  return result;
406  }
407 
409  static const FieldDescriptor TargetIP;
410 
413 
416 
419 
422  };
423 
424  protected:
425  void serializeLayer(ObjectScope& serializer) const override;
426 
427  private:
428  void initLayer(uint8_t code, const IPv6Address& targetIP, bool routerFlag, bool unicastFlag, bool overrideFlag);
429  ndpneighboradvertisementhdr* getNdpHeader() const
430  {
431  return reinterpret_cast<ndpneighboradvertisementhdr*>(m_Data);
432  }
433  size_t getNdpHeaderLen() const override
434  {
435  return sizeof(ndpneighboradvertisementhdr);
436  };
437  };
438 
439 } // namespace pcpp
Definition: IpAddress.h:165
Definition: IcmpV6Layer.h:124
Definition: Layer.h:117
Definition: MacAddress.h:24
Definition: NdpLayer.h:100
NdpOption getFirstNdpOption() const
size_t getNdpOptionCount() const
bool removeAllNdpOptions()
NdpOption getNdpOption(NDPNeighborOptionTypes option) const
NdpOption addNdpOption(const NdpOptionBuilder &optionBuilder)
NdpOption getNextNdpOption(NdpOption &option) const
Definition: NdpLayer.h:283
IPv6Address getTargetIP() const
Definition: NdpLayer.h:365
NDPNeighborAdvertisementLayer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet)
Definition: NdpLayer.h:325
std::string toString() const override
bool getRouterFlag() const
Definition: NdpLayer.h:374
static bool isDataValid(const uint8_t *data, size_t dataLen)
Definition: NdpLayer.h:333
NDPNeighborAdvertisementLayer(uint8_t code, const IPv6Address &targetIP, const MacAddress &targetMac, bool routerFlag, bool unicastFlag, bool overrideFlag)
NDPNeighborAdvertisementLayer(uint8_t code, const IPv6Address &targetIP, bool routerFlag, bool unicastFlag, bool overrideFlag)
void serializeLayer(ObjectScope &serializer) const override
bool getUnicastFlag() const
Definition: NdpLayer.h:380
bool getOverrideFlag() const
Definition: NdpLayer.h:386
Definition: NdpLayer.h:183
NDPNeighborSolicitationLayer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet)
Definition: NdpLayer.h:202
void serializeLayer(ObjectScope &serializer) const override
IPv6Address getTargetIP() const
Definition: NdpLayer.h:229
NDPNeighborSolicitationLayer(uint8_t code, const IPv6Address &targetIP)
MacAddress getLinkLayerAddress() const
static bool isDataValid(const uint8_t *data, size_t dataLen)
Definition: NdpLayer.h:210
std::string toString() const override
NDPNeighborSolicitationLayer(uint8_t code, const IPv6Address &targetIP, const MacAddress &srcMac)
Definition: NdpLayer.h:79
NdpOption build() const
NdpOptionBuilder(NDPNeighborOptionTypes optionType, const uint8_t *optionValue, uint8_t optionValueLen)
Definition: NdpLayer.h:87
Definition: NdpLayer.h:33
NDPNeighborOptionTypes getNdpOptionType() const
Definition: NdpLayer.h:45
~NdpOption() override=default
A d'tor for this class, currently does nothing.
NdpOption(uint8_t *optionRawData)
Definition: NdpLayer.h:37
size_t getDataSize() const override
Definition: NdpLayer.h:63
size_t getTotalSize() const override
Definition: NdpLayer.h:55
Definition: Serializers.h:230
Definition: Packet.h:49
Definition: TLVData.h:374
Definition: TLVData.h:20
Definition: TLVData.h:219
The main namespace for the PcapPlusPlus lib.
Definition: AssertionUtils.h:19
NDPNeighborOptionTypes
An enum representing the available option types for Neighbor Discovery in IPv6 (see RFC 4861)
Definition: NdpLayer.h:20
Definition: Serializers.h:18
Definition: IcmpV6Layer.h:192
static constexpr uint16_t MaxID
The highest field ID used by IcmpV6Layer.
Definition: IcmpV6Layer.h:194
static std::vector< FieldDescriptor > all()
Definition: IcmpV6Layer.h:197
Definition: NdpLayer.h:140
static const FieldDescriptor Options
Array of NDP options; elements described by Option.
Definition: NdpLayer.h:154
static constexpr uint16_t MaxID
The highest field ID used by NDPLayerBase.
Definition: NdpLayer.h:142
static std::vector< FieldDescriptor > all()
Definition: NdpLayer.h:145
static const FieldDescriptor Option
One option's type name; an Options element, not included in all()
Definition: NdpLayer.h:157
static std::vector< FieldDescriptor > all()
Definition: NdpLayer.h:399
static const FieldDescriptor TargetMac
Target MAC address option, as a string (if present)
Definition: NdpLayer.h:421
static const FieldDescriptor OverrideFlag
Override flag.
Definition: NdpLayer.h:418
static const FieldDescriptor UnicastFlag
Solicited (unicast) flag.
Definition: NdpLayer.h:415
static const FieldDescriptor RouterFlag
Router flag.
Definition: NdpLayer.h:412
static const FieldDescriptor TargetIP
Target IPv6 address, as a string.
Definition: NdpLayer.h:409
uint32_t override
Flag indicating that this entry should override the old one.
Definition: NdpLayer.h:295
uint8_t targetIP[16]
Target address - Either source address of advertisement or address for requested MAC.
Definition: NdpLayer.h:316
uint32_t router
Flag indicating that the advertisement is sent by a router.
Definition: NdpLayer.h:300
uint32_t reserved
Unused field.
Definition: NdpLayer.h:293
uint32_t reserved2
Unused field.
Definition: NdpLayer.h:302
static std::vector< FieldDescriptor > all()
Definition: NdpLayer.h:250
static const FieldDescriptor LinkLayerAddress
Link-layer MAC address option, as a string (if present)
Definition: NdpLayer.h:262
static const FieldDescriptor TargetIP
Target IPv6 address, as a string.
Definition: NdpLayer.h:259
uint32_t reserved
Reserved.
Definition: NdpLayer.h:191
uint8_t targetIP[16]
Target address - Target address of solicitation message.
Definition: NdpLayer.h:193
Definition: IcmpV6Layer.h:96