PcapPlusPlus  Next
Layer.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <stdint.h>
4 #include <stdio.h>
5 #include "ProtocolType.h"
6 #include <string>
7 #include <stdexcept>
8 #include <utility>
9 
11 
14 namespace pcpp
15 {
16 
21  {
22  public:
26  virtual uint8_t* getDataPtr(size_t offset = 0) const = 0;
27 
28  virtual ~IDataContainer() = default;
29  };
30 
31  class Packet;
32 
61  class Layer : public IDataContainer
62  {
63  friend class Packet;
64 
65  public:
68  ~Layer() override;
69 
72  {
73  return m_NextLayer;
74  }
75 
78  {
79  return m_PrevLayer;
80  }
81 
84  {
85  return m_Protocol;
86  }
87 
91  bool isMemberOfProtocolFamily(ProtocolTypeFamily protocolTypeFamily) const;
92 
94  uint8_t* getData() const
95  {
96  return m_Data;
97  }
98 
100  size_t getDataLen() const
101  {
102  return m_DataLen;
103  }
104 
106  uint8_t* getLayerPayload() const
107  {
108  return m_Data + getHeaderLen();
109  }
110 
112  size_t getLayerPayloadSize() const
113  {
114  return m_DataLen - getHeaderLen();
115  }
116 
126  bool isAllocatedToPacket() const
127  {
128  return m_Packet != nullptr;
129  }
130 
133  void copyData(uint8_t* toArr) const;
134 
135  // implement abstract methods
136 
137  uint8_t* getDataPtr(size_t offset = 0) const override
138  {
139  return static_cast<uint8_t*>(m_Data + offset);
140  }
141 
142  // abstract methods
143 
145  virtual void parseNextLayer() = 0;
146 
148  virtual size_t getHeaderLen() const = 0;
149 
151  virtual void computeCalculateFields() = 0;
152 
155  virtual std::string toString() const = 0;
156 
158  virtual OsiModelLayer getOsiModelLayer() const = 0;
159 
160  protected:
161  uint8_t* m_Data;
162  size_t m_DataLen;
163  Packet* m_Packet;
164  ProtocolType m_Protocol;
165  Layer* m_NextLayer;
166  Layer* m_PrevLayer;
167  bool m_IsAllocatedInPacket;
168 
169  Layer()
170  : m_Data(nullptr), m_DataLen(0), m_Packet(nullptr), m_Protocol(UnknownProtocol), m_NextLayer(nullptr),
171  m_PrevLayer(nullptr), m_IsAllocatedInPacket(false)
172  {}
173 
174  Layer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet, ProtocolType protocol = UnknownProtocol)
175  : m_Data(data), m_DataLen(dataLen), m_Packet(packet), m_Protocol(protocol), m_NextLayer(nullptr),
176  m_PrevLayer(prevLayer), m_IsAllocatedInPacket(false)
177  {}
178 
179  // Copy c'tor
180  Layer(const Layer& other);
181  Layer& operator=(const Layer& other);
182 
183  void setNextLayer(Layer* nextLayer)
184  {
185  m_NextLayer = nextLayer;
186  }
187  void setPrevLayer(Layer* prevLayer)
188  {
189  m_PrevLayer = prevLayer;
190  }
191 
192  virtual bool extendLayer(int offsetInLayer, size_t numOfBytesToExtend);
193  virtual bool shortenLayer(int offsetInLayer, size_t numOfBytesToShorten);
194 
195  bool hasNextLayer() const
196  {
197  return m_NextLayer != nullptr;
198  }
199 
208  template <typename T, typename... Args>
209  Layer* constructNextLayer(uint8_t* data, size_t dataLen, Packet* packet, Args&&... extraArgs)
210  {
211  if (hasNextLayer())
212  {
213  throw std::runtime_error("Next layer already exists");
214  }
215 
216  Layer* newLayer = new T(data, dataLen, this, packet, std::forward<Args>(extraArgs)...);
217  setNextLayer(newLayer);
218  return newLayer;
219  }
220 
234  template <typename T, typename TFallback, typename... Args>
235  Layer* tryConstructNextLayerWithFallback(uint8_t* data, size_t dataLen, Packet* packet, Args&&... extraArgs)
236  {
237  if (tryConstructNextLayer<T>(data, dataLen, packet, std::forward<Args>(extraArgs)...))
238  {
239  return m_NextLayer;
240  }
241 
242  return constructNextLayer<TFallback>(data, dataLen, packet);
243  }
244 
253  template <typename T> static bool canReinterpretAs(const uint8_t* data, size_t dataLen)
254  {
255  return data != nullptr && dataLen >= sizeof(T);
256  }
257 
258  private:
271  template <typename T, typename... Args>
272  Layer* tryConstructNextLayer(uint8_t* data, size_t dataLen, Packet* packet, Args&&... extraArgs)
273  {
274  if (T::isDataValid(data, dataLen))
275  {
276  return constructNextLayer<T>(data, dataLen, packet, std::forward<Args>(extraArgs)...);
277  }
278  return nullptr;
279  }
280  };
281 
282  inline std::ostream& operator<<(std::ostream& os, const pcpp::Layer& layer)
283  {
284  os << layer.toString();
285  return os;
286  }
287 } // namespace pcpp
Definition: Layer.h:21
virtual uint8_t * getDataPtr(size_t offset=0) const =0
Definition: Layer.h:62
void copyData(uint8_t *toArr) const
uint8_t * getLayerPayload() const
Definition: Layer.h:106
virtual std::string toString() const =0
size_t getDataLen() const
Definition: Layer.h:100
uint8_t * getDataPtr(size_t offset=0) const override
Definition: Layer.h:137
uint8_t * getData() const
Definition: Layer.h:94
virtual void parseNextLayer()=0
Each layer is responsible for parsing the next layer.
Layer * constructNextLayer(uint8_t *data, size_t dataLen, Packet *packet, Args &&... extraArgs)
Definition: Layer.h:209
bool isMemberOfProtocolFamily(ProtocolTypeFamily protocolTypeFamily) const
Layer * getNextLayer() const
Definition: Layer.h:71
bool isAllocatedToPacket() const
Definition: Layer.h:126
Layer * getPrevLayer() const
Definition: Layer.h:77
ProtocolType getProtocol() const
Definition: Layer.h:83
size_t getLayerPayloadSize() const
Definition: Layer.h:112
virtual void computeCalculateFields()=0
Each layer can compute field values automatically using this method. This is an abstract method.
Layer * tryConstructNextLayerWithFallback(uint8_t *data, size_t dataLen, Packet *packet, Args &&... extraArgs)
Definition: Layer.h:235
virtual size_t getHeaderLen() const =0
static bool canReinterpretAs(const uint8_t *data, size_t dataLen)
Check if the data is large enough to reinterpret as a type.
Definition: Layer.h:253
~Layer() override
virtual OsiModelLayer getOsiModelLayer() const =0
Definition: Packet.h:22
The main namespace for the PcapPlusPlus lib.
uint8_t ProtocolType
Definition: ProtocolType.h:13
OsiModelLayer
An enum representing OSI model layers.
Definition: ProtocolType.h:225
uint32_t ProtocolTypeFamily
Definition: ProtocolType.h:17
const ProtocolType UnknownProtocol
Unknown protocol (or unsupported by PcapPlusPlus)
Definition: ProtocolType.h:20