PcapPlusPlus  Next
GeneveLayer.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "EthLayer.h"
4 #include "Layer.h"
5 
7 
10 namespace pcpp
11 {
12  class GeneveLayer;
13 
18  {
19  friend class GeneveLayer;
20 
21  private:
22 #pragma pack(push, 1)
23  struct geneve_option_header
24  {
25  uint16_t optionClass;
26  uint8_t type;
27 #if (BYTE_ORDER == LITTLE_ENDIAN)
28  uint8_t length : 5;
29  uint8_t reserved : 3;
30 #else
31  uint8_t reserved : 3;
32  uint8_t length : 5;
33 #endif
34  };
35 #pragma pack(pop)
36  static_assert(sizeof(geneve_option_header) == 4, "geneve_option_header size is not 4 bytes");
37 
38  static constexpr size_t HeaderLength = sizeof(geneve_option_header);
39  static constexpr size_t DataLengthUnit = 4;
40  static constexpr size_t MaxDataLength = ((1 << 5) - 1) * DataLengthUnit;
41  static constexpr uint8_t TypeMask = 0x7f;
42  static constexpr uint8_t CriticalBitMask = 0x80;
43 
44  geneve_option_header* m_Data;
45 
47  explicit GeneveOption(uint8_t* optionData) : m_Data(reinterpret_cast<geneve_option_header*>(optionData))
48  {}
49 
50  static bool canAssign(const uint8_t* optionRawData, size_t optionDataLen);
51  void setOptionClass(uint16_t value);
52  void setType(uint8_t value, bool critical);
53  void setDataSize(size_t value);
54 
55  static uint8_t extractType(uint8_t value)
56  {
57  return static_cast<uint8_t>(value & TypeMask);
58  }
59 
60  static size_t alignDataSize(size_t value)
61  {
62  constexpr size_t AlignmentMask = DataLengthUnit - 1;
63  return (value + AlignmentMask) & ~AlignmentMask;
64  }
65 
66  uint8_t* getRecordBasePtr() const
67  {
68  return reinterpret_cast<uint8_t*>(m_Data);
69  }
70 
71  public:
73  GeneveOption() : m_Data(nullptr)
74  {}
75 
77  bool isNull() const
78  {
79  return m_Data == nullptr;
80  }
81 
83  uint16_t getOptionClass() const;
84 
86  uint8_t getType() const;
87 
89  bool isCritical() const;
90 
92  size_t getDataSize() const;
93 
95  size_t getTotalSize() const;
96 
98  uint8_t* getData() const;
99 
101  bool operator==(const GeneveOption& other) const;
102 
104  bool operator!=(const GeneveOption& other) const
105  {
106  return !(*this == other);
107  }
108  };
115  class GeneveLayer : public Layer
116  {
117  public:
119  static constexpr uint16_t DefaultPort = 6081;
120 
128  GeneveLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
129  : Layer(data, dataLen, prevLayer, packet, Geneve)
130  {}
131 
136  explicit GeneveLayer(uint32_t vni = 0, uint16_t protocolType = PCPP_ETHERTYPE_ETHBRIDGE, bool oamFlag = false);
137 
138  ~GeneveLayer() override = default;
139 
146  static bool isDataValid(const uint8_t* data, size_t dataLen);
147 
151  static bool isGenevePort(uint16_t port)
152  {
153  return port == DefaultPort;
154  }
155 
157  uint32_t getVNI() const;
158 
161  void setVNI(uint32_t vni);
162 
164  uint16_t getProtocolType() const;
165 
168  void setProtocolType(uint16_t protocolType);
169 
171  bool getOamFlag() const;
172 
175  void setOamFlag(bool value);
176 
178  bool getCriticalFlag() const;
179 
181  size_t getOptionsLength() const;
182 
184  size_t getOptionCount() const;
185 
188 
194 
199  GeneveOption getOption(uint16_t optionClass, uint8_t optionType) const;
200 
208  bool addOption(uint16_t optionClass, uint8_t optionType, const uint8_t* optionData, size_t optionDataLen,
209  bool critical = false);
210 
215  bool removeOption(uint16_t optionClass, uint8_t optionType);
216 
220 
224  void parseNextLayer() override;
225 
227  size_t getHeaderLen() const override;
228 
230  void computeCalculateFields() override;
231 
232  std::string toString() const override;
233 
235  {
236  return OsiModelDataLinkLayer;
237  }
238 
243  {
245  static std::vector<FieldDescriptor> all()
246  {
247  auto result = Layer::SerializedFields::all();
248  std::initializer_list<FieldDescriptor> extra{ OptionsLength, ProtocolType, VNI,
250  std::copy(extra.begin(), extra.end(), std::back_inserter(result));
251  return result;
252  }
253 
256  struct OptionObject : ObjectFieldDescriptor<OptionObject>
257  {
259 
261  static std::vector<FieldDescriptor> all()
262  {
263  return { OptionClass, Type, Critical, DataSize };
264  }
265 
268 
270  static const FieldDescriptor Type;
271 
273  static const FieldDescriptor Critical;
274 
276  static const FieldDescriptor DataSize;
277  };
278 
281 
284 
286  static const FieldDescriptor VNI;
287 
289  static const FieldDescriptor OamFlag;
290 
293 
295  static const FieldDescriptor Options;
296 
298  static const OptionObject Option;
299  };
300 
301  protected:
302  void serializeLayer(ObjectScope& serializer) const override;
303 
304  private:
305 #pragma pack(push, 1)
306  struct geneve_header
307  {
308 #if (BYTE_ORDER == LITTLE_ENDIAN)
309  uint8_t optionsLength : 6;
310  uint8_t version : 2;
311  uint8_t reserved1 : 6;
312  uint8_t criticalFlag : 1;
313  uint8_t oamFlag : 1;
314 #else
315  uint8_t version : 2;
316  uint8_t optionsLength : 6;
317  uint8_t oamFlag : 1;
318  uint8_t criticalFlag : 1;
319  uint8_t reserved1 : 6;
320 #endif
321  uint16_t protocolType;
322  uint8_t vni[3];
323  uint8_t reserved2;
324  };
325 #pragma pack(pop)
326  static_assert(sizeof(geneve_header) == 8, "geneve_header size is not 8 bytes");
327 
328  static constexpr size_t HeaderLength = sizeof(geneve_header);
329  static constexpr size_t OptionsLengthUnit = 4;
330  static constexpr size_t MaxOptionsLength = ((1 << 6) - 1) * OptionsLengthUnit;
331 
332  geneve_header* getGeneveHeader() const
333  {
334  return reinterpret_cast<geneve_header*>(m_Data);
335  }
336 
337  void setOptionsLength(size_t value);
338 
339  void updateCriticalFlag();
340  };
341 } // namespace pcpp
#define PCPP_ETHERTYPE_ETHBRIDGE
Transparent Ethernet Bridging.
Definition: EthLayer.h:37
Definition: GeneveLayer.h:116
void setOamFlag(bool value)
static bool isDataValid(const uint8_t *data, size_t dataLen)
void serializeLayer(ObjectScope &serializer) const override
void computeCalculateFields() override
Update the Protocol Type and Critical flag from the following layer and options.
OsiModelLayer getOsiModelLayer() const override
Definition: GeneveLayer.h:234
size_t getHeaderLen() const override
GeneveLayer(uint8_t *data, size_t dataLen, Layer *prevLayer, Packet *packet)
Definition: GeneveLayer.h:128
static constexpr uint16_t DefaultPort
The IANA-assigned UDP destination port for GENEVE.
Definition: GeneveLayer.h:119
size_t getOptionCount() const
uint32_t getVNI() const
GeneveLayer(uint32_t vni=0, uint16_t protocolType=0x6558, bool oamFlag=false)
void parseNextLayer() override
GeneveOption getOption(uint16_t optionClass, uint8_t optionType) const
bool removeOption(uint16_t optionClass, uint8_t optionType)
uint16_t getProtocolType() const
bool getCriticalFlag() const
void setVNI(uint32_t vni)
GeneveOption getFirstOption() const
std::string toString() const override
void setProtocolType(uint16_t protocolType)
bool getOamFlag() const
static bool isGenevePort(uint16_t port)
Definition: GeneveLayer.h:151
size_t getOptionsLength() const
GeneveOption getNextOption(const GeneveOption &option) const
bool addOption(uint16_t optionClass, uint8_t optionType, const uint8_t *optionData, size_t optionDataLen, bool critical=false)
Definition: GeneveLayer.h:18
bool isNull() const
Definition: GeneveLayer.h:77
bool isCritical() const
bool operator!=(const GeneveOption &other) const
Definition: GeneveLayer.h:104
uint8_t getType() const
GeneveOption()
Construct a null option view.
Definition: GeneveLayer.h:73
uint8_t * getData() const
size_t getDataSize() const
bool operator==(const GeneveOption &other) const
uint16_t getOptionClass() const
size_t getTotalSize() const
Definition: Layer.h:117
Definition: Serializers.h:230
Definition: Packet.h:49
const ProtocolType Geneve
GENEVE protocol.
Definition: ProtocolType.h:273
The main namespace for the PcapPlusPlus lib.
Definition: AssertionUtils.h:19
OsiModelLayer
An enum representing OSI model layers.
Definition: ProtocolType.h:425
@ OsiModelDataLinkLayer
Data link layer (layer 2)
Definition: ProtocolType.h:429
Definition: Serializers.h:18
static const FieldDescriptor DataSize
Option data length in bytes.
Definition: GeneveLayer.h:276
static const FieldDescriptor OptionClass
Option class in host byte order.
Definition: GeneveLayer.h:267
static std::vector< FieldDescriptor > all()
Definition: GeneveLayer.h:261
static const FieldDescriptor Critical
True if the option critical bit is set.
Definition: GeneveLayer.h:273
static const FieldDescriptor Type
Option type without the critical bit.
Definition: GeneveLayer.h:270
Definition: GeneveLayer.h:243
static std::vector< FieldDescriptor > all()
Definition: GeneveLayer.h:245
static const FieldDescriptor Options
GENEVE options.
Definition: GeneveLayer.h:295
static const FieldDescriptor VNI
The 24-bit virtual network identifier.
Definition: GeneveLayer.h:286
static const FieldDescriptor ProtocolType
Encapsulated protocol EtherType in host byte order.
Definition: GeneveLayer.h:283
static const OptionObject Option
Descriptor for one element of the options array.
Definition: GeneveLayer.h:298
static const FieldDescriptor CriticalFlag
True if the GENEVE critical options flag is set.
Definition: GeneveLayer.h:292
static const FieldDescriptor OamFlag
True if the GENEVE OAM flag is set.
Definition: GeneveLayer.h:289
static const FieldDescriptor OptionsLength
Total options length in bytes declared by the GENEVE header.
Definition: GeneveLayer.h:280
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