PcapPlusPlus  Next
TLVData.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "Layer.h"
4 #include "IpAddress.h"
5 #include <string.h>
6 
8 
11 namespace pcpp
12 {
18  template <typename TRecType, typename TRecLen> class TLVRecord
19  {
20  protected:
22 #pragma pack(push, 1)
23  struct TLVRawData
24  {
26  TRecType recordType;
28  TRecLen recordLen;
30  uint8_t recordValue[];
31  };
32 #pragma pack(pop)
33 
34  TLVRawData* m_Data;
35 
36  public:
39  TLVRecord(uint8_t* recordRawData)
40  {
41  assign(recordRawData);
42  }
43 
47  TLVRecord(const TLVRecord& other)
48  {
49  m_Data = other.m_Data;
50  }
51 
53  virtual ~TLVRecord() = default;
54 
57  void assign(uint8_t* recordRawData)
58  {
59  m_Data = reinterpret_cast<TLVRawData*>(recordRawData);
60  }
61 
66  static bool canAssign(const uint8_t* recordRawData, size_t tlvDataLen)
67  {
68  return recordRawData != nullptr &&
69  tlvDataLen >= (sizeof(TLVRawData::recordType) + sizeof(TLVRawData::recordLen));
70  }
71 
76  TLVRecord& operator=(const TLVRecord& other)
77  {
78  m_Data = other.m_Data;
79  return *this;
80  }
81 
86  bool operator==(const TLVRecord& rhs) const
87  {
88  if (m_Data == rhs.m_Data)
89  return true;
90 
91  if (getTotalSize() != rhs.getTotalSize())
92  return false;
93 
94  if (isNull() || ((TLVRecord&)rhs).isNull())
95  return false;
96 
97  return (memcmp(m_Data, rhs.m_Data, getTotalSize()) == 0);
98  }
99 
103  bool operator!=(const TLVRecord& rhs) const
104  {
105  return !operator==(rhs);
106  }
107 
109  TRecType getType() const
110  {
111  if (m_Data == nullptr)
112  return 0;
113 
114  return m_Data->recordType;
115  }
116 
118  uint8_t* getValue() const
119  {
120  if (m_Data == nullptr)
121  return nullptr;
122 
123  return m_Data->recordValue;
124  }
125 
127  bool isNull() const
128  {
129  return (m_Data == nullptr);
130  }
131 
133  bool isNotNull() const
134  {
135  return (m_Data != nullptr);
136  }
137 
139  uint8_t* getRecordBasePtr() const
140  {
141  return reinterpret_cast<uint8_t*>(m_Data);
142  }
143 
146  {
147  if (!isNull())
148  {
149  delete[] m_Data;
150  m_Data = nullptr;
151  }
152  }
153 
161  template <typename T> T getValueAs(size_t offset = 0) const
162  {
163  if (getDataSize() - offset < sizeof(T))
164  return 0;
165 
166  T result;
167  memcpy(&result, m_Data->recordValue + getValueOffset() + offset, sizeof(T));
168  return result;
169  }
170 
178  template <typename T> bool setValue(T newValue, int valueOffset = 0)
179  {
180  if (getDataSize() < sizeof(T))
181  return false;
182 
183  memcpy(m_Data->recordValue + getValueOffset() + valueOffset, &newValue, sizeof(T));
184  return true;
185  }
186 
188  virtual size_t getTotalSize() const = 0;
189 
191  virtual size_t getDataSize() const = 0;
192 
193  protected:
194  virtual size_t getValueOffset() const
195  {
196  return 0;
197  }
198  };
199 
203  template <typename TLVRecordType> class TLVRecordReader
204  {
205  private:
206  mutable size_t m_RecordCount;
207 
208  public:
211  {
212  m_RecordCount = static_cast<size_t>(-1);
213  }
214 
217  {
218  m_RecordCount = other.m_RecordCount;
219  }
220 
222  virtual ~TLVRecordReader() = default;
223 
227  {
228  m_RecordCount = other.m_RecordCount;
229  return *this;
230  }
231 
238  TLVRecordType getFirstTLVRecord(uint8_t* tlvDataBasePtr, size_t tlvDataLen) const
239  {
240  TLVRecordType resRec(nullptr); // for NRVO optimization
241  if (!TLVRecordType::canAssign(tlvDataBasePtr, tlvDataLen))
242  return resRec;
243 
244  resRec.assign(tlvDataBasePtr);
245  // resRec pointer is out-bounds of the TLV records memory
246  if (resRec.getRecordBasePtr() + resRec.getTotalSize() > tlvDataBasePtr + tlvDataLen)
247  resRec.assign(nullptr);
248 
249  // check if there are records at all and the total size is not zero
250  if (!resRec.isNull() && (tlvDataLen == 0 || resRec.getTotalSize() == 0))
251  resRec.assign(nullptr);
252 
253  return resRec;
254  }
255 
263  TLVRecordType getNextTLVRecord(TLVRecordType& record, const uint8_t* tlvDataBasePtr, size_t tlvDataLen) const
264  {
265  TLVRecordType resRec(nullptr); // for NRVO optimization
266 
267  if (record.isNull())
268  return resRec;
269 
270  if (!TLVRecordType::canAssign(record.getRecordBasePtr() + record.getTotalSize(),
271  tlvDataBasePtr - record.getRecordBasePtr() + tlvDataLen -
272  record.getTotalSize()))
273  return resRec;
274 
275  resRec.assign(record.getRecordBasePtr() + record.getTotalSize());
276 
277  if (resRec.getTotalSize() == 0)
278  resRec.assign(nullptr);
279 
280  // resRec pointer is out-bounds of the TLV records memory
281  if ((resRec.getRecordBasePtr() - tlvDataBasePtr) < 0)
282  resRec.assign(nullptr);
283 
284  // resRec pointer is out-bounds of the TLV records memory
285  if (!resRec.isNull() && resRec.getRecordBasePtr() + resRec.getTotalSize() > tlvDataBasePtr + tlvDataLen)
286  resRec.assign(nullptr);
287 
288  return resRec;
289  }
290 
297  TLVRecordType getTLVRecord(uint32_t recordType, uint8_t* tlvDataBasePtr, size_t tlvDataLen) const
298  {
299  TLVRecordType curRec = getFirstTLVRecord(tlvDataBasePtr, tlvDataLen);
300  while (!curRec.isNull())
301  {
302  if (curRec.getType() == recordType)
303  {
304  return curRec;
305  }
306 
307  curRec = getNextTLVRecord(curRec, tlvDataBasePtr, tlvDataLen);
308  }
309 
310  curRec.assign(nullptr);
311  return curRec; // for NRVO optimization
312  }
313 
321  size_t getTLVRecordCount(uint8_t* tlvDataBasePtr, size_t tlvDataLen) const
322  {
323  if (m_RecordCount != static_cast<size_t>(-1))
324  return m_RecordCount;
325 
326  m_RecordCount = 0;
327  TLVRecordType curRec = getFirstTLVRecord(tlvDataBasePtr, tlvDataLen);
328  while (!curRec.isNull())
329  {
330  m_RecordCount++;
331  curRec = getNextTLVRecord(curRec, tlvDataBasePtr, tlvDataLen);
332  }
333 
334  return m_RecordCount;
335  }
336 
342  void changeTLVRecordCount(int changedBy)
343  {
344  if (m_RecordCount != static_cast<size_t>(-1))
345  m_RecordCount += changedBy;
346  }
347  };
348 
357  {
358  protected:
360 
361  TLVRecordBuilder(uint32_t recType, const uint8_t* recValue, uint8_t recValueLen);
362 
363  TLVRecordBuilder(uint32_t recType, uint8_t recValue);
364 
365  TLVRecordBuilder(uint32_t recType, uint16_t recValue);
366 
367  TLVRecordBuilder(uint32_t recType, uint32_t recValue);
368 
369  TLVRecordBuilder(uint32_t recType, const IPv4Address& recValue);
370 
371  TLVRecordBuilder(uint32_t recType, const std::string& recValue, bool valueIsHexString = false);
372 
373  TLVRecordBuilder(const TLVRecordBuilder& other);
374 
375  TLVRecordBuilder& operator=(const TLVRecordBuilder& other);
376 
377  virtual ~TLVRecordBuilder();
378 
379  void init(uint32_t recType, const uint8_t* recValue, size_t recValueLen);
380 
381  uint8_t* m_RecValue;
382  size_t m_RecValueLen;
383  uint32_t m_RecType;
384 
385  private:
386  void copyData(const TLVRecordBuilder& other);
387  };
388 } // namespace pcpp
Definition: IpAddress.h:28
Definition: TLVData.h:357
Definition: TLVData.h:19
TLVRecord(uint8_t *recordRawData)
Definition: TLVData.h:39
TLVRecord(const TLVRecord &other)
Definition: TLVData.h:47
virtual size_t getTotalSize() const =0
virtual ~TLVRecord()=default
A d'tor for this class, currently does nothing.
TRecType getType() const
Definition: TLVData.h:109
bool setValue(T newValue, int valueOffset=0)
Definition: TLVData.h:178
bool operator!=(const TLVRecord &rhs) const
Definition: TLVData.h:103
uint8_t * getRecordBasePtr() const
Definition: TLVData.h:139
uint8_t * getValue() const
Definition: TLVData.h:118
bool operator==(const TLVRecord &rhs) const
Definition: TLVData.h:86
static bool canAssign(const uint8_t *recordRawData, size_t tlvDataLen)
Definition: TLVData.h:66
virtual size_t getDataSize() const =0
bool isNotNull() const
Definition: TLVData.h:133
bool isNull() const
Definition: TLVData.h:127
T getValueAs(size_t offset=0) const
Definition: TLVData.h:161
TLVRecord & operator=(const TLVRecord &other)
Definition: TLVData.h:76
void purgeRecordData()
Free the memory of the TLV record raw data.
Definition: TLVData.h:145
void assign(uint8_t *recordRawData)
Definition: TLVData.h:57
Definition: TLVData.h:204
void changeTLVRecordCount(int changedBy)
Definition: TLVData.h:342
TLVRecordReader & operator=(const TLVRecordReader &other)
Definition: TLVData.h:226
virtual ~TLVRecordReader()=default
A d'tor for this class which currently does nothing.
TLVRecordType getTLVRecord(uint32_t recordType, uint8_t *tlvDataBasePtr, size_t tlvDataLen) const
Definition: TLVData.h:297
TLVRecordReader(const TLVRecordReader &other)
A default copy c'tor for this class.
Definition: TLVData.h:216
TLVRecordType getNextTLVRecord(TLVRecordType &record, const uint8_t *tlvDataBasePtr, size_t tlvDataLen) const
Definition: TLVData.h:263
TLVRecordReader()
A default c'tor for this class.
Definition: TLVData.h:210
TLVRecordType getFirstTLVRecord(uint8_t *tlvDataBasePtr, size_t tlvDataLen) const
Definition: TLVData.h:238
size_t getTLVRecordCount(uint8_t *tlvDataBasePtr, size_t tlvDataLen) const
Definition: TLVData.h:321
The main namespace for the PcapPlusPlus lib.
A struct representing the TLV construct.
Definition: TLVData.h:24
uint8_t recordValue[]
Record value (variable size)
Definition: TLVData.h:30
TRecType recordType
Record type.
Definition: TLVData.h:26
TRecLen recordLen
Record length in bytes.
Definition: TLVData.h:28