PcapPlusPlus  24.09
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 
13 namespace pcpp
14 {
22  template <typename TRecType, typename TRecLen> class TLVRecord
23  {
24  protected:
26  struct TLVRawData
27  {
29  TRecType recordType;
31  TRecLen recordLen;
33  uint8_t recordValue[];
34  };
35 
36  TLVRawData* m_Data;
37 
38  public:
43  TLVRecord(uint8_t* recordRawData)
44  {
45  assign(recordRawData);
46  }
47 
53  TLVRecord(const TLVRecord& other)
54  {
55  m_Data = other.m_Data;
56  }
57 
61  virtual ~TLVRecord()
62  {}
63 
68  void assign(uint8_t* recordRawData)
69  {
70  m_Data = reinterpret_cast<TLVRawData*>(recordRawData);
71  }
72 
79  static bool canAssign(const uint8_t* recordRawData, size_t tlvDataLen)
80  {
81  return recordRawData != nullptr &&
82  tlvDataLen >= (sizeof(TLVRawData::recordType) + sizeof(TLVRawData::recordLen));
83  }
84 
91  TLVRecord& operator=(const TLVRecord& other)
92  {
93  m_Data = other.m_Data;
94  return *this;
95  }
96 
103  bool operator==(const TLVRecord& rhs) const
104  {
105  if (m_Data == rhs.m_Data)
106  return true;
107 
108  if (getTotalSize() != rhs.getTotalSize())
109  return false;
110 
111  if (isNull() || ((TLVRecord&)rhs).isNull())
112  return false;
113 
114  return (memcmp(m_Data, rhs.m_Data, getTotalSize()) == 0);
115  }
116 
122  bool operator!=(const TLVRecord& rhs) const
123  {
124  return !operator==(rhs);
125  }
126 
130  TRecType getType() const
131  {
132  if (m_Data == nullptr)
133  return 0;
134 
135  return m_Data->recordType;
136  }
137 
141  uint8_t* getValue() const
142  {
143  if (m_Data == nullptr)
144  return nullptr;
145 
146  return m_Data->recordValue;
147  }
148 
152  bool isNull() const
153  {
154  return (m_Data == nullptr);
155  }
156 
160  bool isNotNull() const
161  {
162  return (m_Data != nullptr);
163  }
164 
168  uint8_t* getRecordBasePtr() const
169  {
170  return (uint8_t*)m_Data;
171  }
172 
177  {
178  if (!isNull())
179  {
180  delete[] m_Data;
181  m_Data = nullptr;
182  }
183  }
184 
194  template <typename T> T getValueAs(size_t offset = 0) const
195  {
196  if (getDataSize() - offset < sizeof(T))
197  return 0;
198 
199  T result;
200  memcpy(&result, m_Data->recordValue + offset, sizeof(T));
201  return result;
202  }
203 
213  template <typename T> bool setValue(T newValue, int valueOffset = 0)
214  {
215  if (getDataSize() < sizeof(T))
216  return false;
217 
218  memcpy(m_Data->recordValue + valueOffset, &newValue, sizeof(T));
219  return true;
220  }
221 
225  virtual size_t getTotalSize() const = 0;
226 
230  virtual size_t getDataSize() const = 0;
231  };
232 
238  template <typename TLVRecordType> class TLVRecordReader
239  {
240  private:
241  mutable size_t m_RecordCount;
242 
243  public:
248  {
249  m_RecordCount = (size_t)-1;
250  }
251 
256  {
257  m_RecordCount = other.m_RecordCount;
258  }
259 
264  {}
265 
271  {
272  m_RecordCount = other.m_RecordCount;
273  return *this;
274  }
275 
284  TLVRecordType getFirstTLVRecord(uint8_t* tlvDataBasePtr, size_t tlvDataLen) const
285  {
286  TLVRecordType resRec(nullptr); // for NRVO optimization
287  if (!TLVRecordType::canAssign(tlvDataBasePtr, tlvDataLen))
288  return resRec;
289 
290  resRec.assign(tlvDataBasePtr);
291  // resRec pointer is out-bounds of the TLV records memory
292  if (resRec.getRecordBasePtr() + resRec.getTotalSize() > tlvDataBasePtr + tlvDataLen)
293  resRec.assign(nullptr);
294 
295  // check if there are records at all and the total size is not zero
296  if (!resRec.isNull() && (tlvDataLen == 0 || resRec.getTotalSize() == 0))
297  resRec.assign(nullptr);
298 
299  return resRec;
300  }
301 
311  TLVRecordType getNextTLVRecord(TLVRecordType& record, const uint8_t* tlvDataBasePtr, size_t tlvDataLen) const
312  {
313  TLVRecordType resRec(nullptr); // for NRVO optimization
314 
315  if (record.isNull())
316  return resRec;
317 
318  if (!TLVRecordType::canAssign(record.getRecordBasePtr() + record.getTotalSize(),
319  tlvDataBasePtr - record.getRecordBasePtr() + tlvDataLen -
320  record.getTotalSize()))
321  return resRec;
322 
323  resRec.assign(record.getRecordBasePtr() + record.getTotalSize());
324 
325  if (resRec.getTotalSize() == 0)
326  resRec.assign(nullptr);
327 
328  // resRec pointer is out-bounds of the TLV records memory
329  if ((resRec.getRecordBasePtr() - tlvDataBasePtr) < 0)
330  resRec.assign(nullptr);
331 
332  // resRec pointer is out-bounds of the TLV records memory
333  if (!resRec.isNull() && resRec.getRecordBasePtr() + resRec.getTotalSize() > tlvDataBasePtr + tlvDataLen)
334  resRec.assign(nullptr);
335 
336  return resRec;
337  }
338 
347  TLVRecordType getTLVRecord(uint32_t recordType, uint8_t* tlvDataBasePtr, size_t tlvDataLen) const
348  {
349  TLVRecordType curRec = getFirstTLVRecord(tlvDataBasePtr, tlvDataLen);
350  while (!curRec.isNull())
351  {
352  if (curRec.getType() == recordType)
353  {
354  return curRec;
355  }
356 
357  curRec = getNextTLVRecord(curRec, tlvDataBasePtr, tlvDataLen);
358  }
359 
360  curRec.assign(nullptr);
361  return curRec; // for NRVO optimization
362  }
363 
373  size_t getTLVRecordCount(uint8_t* tlvDataBasePtr, size_t tlvDataLen) const
374  {
375  if (m_RecordCount != (size_t)-1)
376  return m_RecordCount;
377 
378  m_RecordCount = 0;
379  TLVRecordType curRec = getFirstTLVRecord(tlvDataBasePtr, tlvDataLen);
380  while (!curRec.isNull())
381  {
382  m_RecordCount++;
383  curRec = getNextTLVRecord(curRec, tlvDataBasePtr, tlvDataLen);
384  }
385 
386  return m_RecordCount;
387  }
388 
396  void changeTLVRecordCount(int changedBy)
397  {
398  if (m_RecordCount != (size_t)-1)
399  m_RecordCount += changedBy;
400  }
401  };
402 
413  {
414  protected:
416 
417  TLVRecordBuilder(uint32_t recType, const uint8_t* recValue, uint8_t recValueLen);
418 
419  TLVRecordBuilder(uint32_t recType, uint8_t recValue);
420 
421  TLVRecordBuilder(uint32_t recType, uint16_t recValue);
422 
423  TLVRecordBuilder(uint32_t recType, uint32_t recValue);
424 
425  TLVRecordBuilder(uint32_t recType, const IPv4Address& recValue);
426 
427  TLVRecordBuilder(uint32_t recType, const std::string& recValue, bool valueIsHexString = false);
428 
429  TLVRecordBuilder(const TLVRecordBuilder& other);
430 
431  TLVRecordBuilder& operator=(const TLVRecordBuilder& other);
432 
433  virtual ~TLVRecordBuilder();
434 
435  void init(uint32_t recType, const uint8_t* recValue, size_t recValueLen);
436 
437  uint8_t* m_RecValue;
438  size_t m_RecValueLen;
439  uint32_t m_RecType;
440 
441  private:
442  void copyData(const TLVRecordBuilder& other);
443  };
444 } // namespace pcpp
Definition: IpAddress.h:32
Definition: TLVData.h:413
Definition: TLVData.h:23
TLVRecord(uint8_t *recordRawData)
Definition: TLVData.h:43
TLVRecord(const TLVRecord &other)
Definition: TLVData.h:53
virtual size_t getTotalSize() const =0
TRecType getType() const
Definition: TLVData.h:130
bool setValue(T newValue, int valueOffset=0)
Definition: TLVData.h:213
bool operator!=(const TLVRecord &rhs) const
Definition: TLVData.h:122
uint8_t * getRecordBasePtr() const
Definition: TLVData.h:168
uint8_t * getValue() const
Definition: TLVData.h:141
bool operator==(const TLVRecord &rhs) const
Definition: TLVData.h:103
static bool canAssign(const uint8_t *recordRawData, size_t tlvDataLen)
Definition: TLVData.h:79
virtual size_t getDataSize() const =0
bool isNotNull() const
Definition: TLVData.h:160
bool isNull() const
Definition: TLVData.h:152
T getValueAs(size_t offset=0) const
Definition: TLVData.h:194
TLVRecord & operator=(const TLVRecord &other)
Definition: TLVData.h:91
void purgeRecordData()
Definition: TLVData.h:176
virtual ~TLVRecord()
Definition: TLVData.h:61
void assign(uint8_t *recordRawData)
Definition: TLVData.h:68
Definition: TLVData.h:239
void changeTLVRecordCount(int changedBy)
Definition: TLVData.h:396
TLVRecordReader & operator=(const TLVRecordReader &other)
Definition: TLVData.h:270
TLVRecordType getTLVRecord(uint32_t recordType, uint8_t *tlvDataBasePtr, size_t tlvDataLen) const
Definition: TLVData.h:347
TLVRecordReader(const TLVRecordReader &other)
Definition: TLVData.h:255
TLVRecordType getNextTLVRecord(TLVRecordType &record, const uint8_t *tlvDataBasePtr, size_t tlvDataLen) const
Definition: TLVData.h:311
TLVRecordReader()
Definition: TLVData.h:247
TLVRecordType getFirstTLVRecord(uint8_t *tlvDataBasePtr, size_t tlvDataLen) const
Definition: TLVData.h:284
size_t getTLVRecordCount(uint8_t *tlvDataBasePtr, size_t tlvDataLen) const
Definition: TLVData.h:373
virtual ~TLVRecordReader()
Definition: TLVData.h:263
The main namespace for the PcapPlusPlus lib.
Definition: TLVData.h:27
uint8_t recordValue[]
Definition: TLVData.h:33
TRecType recordType
Definition: TLVData.h:29
TRecLen recordLen
Definition: TLVData.h:31