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 
13 namespace pcpp
14 {
22  template <typename TRecType, typename TRecLen> class TLVRecord
23  {
24  protected:
26 #pragma pack(push, 1)
27  struct TLVRawData
28  {
30  TRecType recordType;
32  TRecLen recordLen;
34  uint8_t recordValue[];
35  };
36 #pragma pack(pop)
37 
38  TLVRawData* m_Data;
39 
40  public:
45  TLVRecord(uint8_t* recordRawData)
46  {
47  assign(recordRawData);
48  }
49 
55  TLVRecord(const TLVRecord& other)
56  {
57  m_Data = other.m_Data;
58  }
59 
63  virtual ~TLVRecord() = default;
64 
69  void assign(uint8_t* recordRawData)
70  {
71  m_Data = reinterpret_cast<TLVRawData*>(recordRawData);
72  }
73 
80  static bool canAssign(const uint8_t* recordRawData, size_t tlvDataLen)
81  {
82  return recordRawData != nullptr &&
83  tlvDataLen >= (sizeof(TLVRawData::recordType) + sizeof(TLVRawData::recordLen));
84  }
85 
92  TLVRecord& operator=(const TLVRecord& other)
93  {
94  m_Data = other.m_Data;
95  return *this;
96  }
97 
104  bool operator==(const TLVRecord& rhs) const
105  {
106  if (m_Data == rhs.m_Data)
107  return true;
108 
109  if (getTotalSize() != rhs.getTotalSize())
110  return false;
111 
112  if (isNull() || ((TLVRecord&)rhs).isNull())
113  return false;
114 
115  return (memcmp(m_Data, rhs.m_Data, getTotalSize()) == 0);
116  }
117 
123  bool operator!=(const TLVRecord& rhs) const
124  {
125  return !operator==(rhs);
126  }
127 
131  TRecType getType() const
132  {
133  if (m_Data == nullptr)
134  return 0;
135 
136  return m_Data->recordType;
137  }
138 
142  uint8_t* getValue() const
143  {
144  if (m_Data == nullptr)
145  return nullptr;
146 
147  return m_Data->recordValue;
148  }
149 
153  bool isNull() const
154  {
155  return (m_Data == nullptr);
156  }
157 
161  bool isNotNull() const
162  {
163  return (m_Data != nullptr);
164  }
165 
169  uint8_t* getRecordBasePtr() const
170  {
171  return reinterpret_cast<uint8_t*>(m_Data);
172  }
173 
178  {
179  if (!isNull())
180  {
181  delete[] m_Data;
182  m_Data = nullptr;
183  }
184  }
185 
195  template <typename T> T getValueAs(size_t offset = 0) const
196  {
197  if (getDataSize() - offset < sizeof(T))
198  return 0;
199 
200  T result;
201  memcpy(&result, m_Data->recordValue + getValueOffset() + offset, sizeof(T));
202  return result;
203  }
204 
214  template <typename T> bool setValue(T newValue, int valueOffset = 0)
215  {
216  if (getDataSize() < sizeof(T))
217  return false;
218 
219  memcpy(m_Data->recordValue + getValueOffset() + valueOffset, &newValue, sizeof(T));
220  return true;
221  }
222 
226  virtual size_t getTotalSize() const = 0;
227 
231  virtual size_t getDataSize() const = 0;
232 
233  protected:
234  virtual size_t getValueOffset() const
235  {
236  return 0;
237  }
238  };
239 
245  template <typename TLVRecordType> class TLVRecordReader
246  {
247  private:
248  mutable size_t m_RecordCount;
249 
250  public:
255  {
256  m_RecordCount = static_cast<size_t>(-1);
257  }
258 
263  {
264  m_RecordCount = other.m_RecordCount;
265  }
266 
270  virtual ~TLVRecordReader() = default;
271 
277  {
278  m_RecordCount = other.m_RecordCount;
279  return *this;
280  }
281 
290  TLVRecordType getFirstTLVRecord(uint8_t* tlvDataBasePtr, size_t tlvDataLen) const
291  {
292  TLVRecordType resRec(nullptr); // for NRVO optimization
293  if (!TLVRecordType::canAssign(tlvDataBasePtr, tlvDataLen))
294  return resRec;
295 
296  resRec.assign(tlvDataBasePtr);
297  // resRec pointer is out-bounds of the TLV records memory
298  if (resRec.getRecordBasePtr() + resRec.getTotalSize() > tlvDataBasePtr + tlvDataLen)
299  resRec.assign(nullptr);
300 
301  // check if there are records at all and the total size is not zero
302  if (!resRec.isNull() && (tlvDataLen == 0 || resRec.getTotalSize() == 0))
303  resRec.assign(nullptr);
304 
305  return resRec;
306  }
307 
317  TLVRecordType getNextTLVRecord(TLVRecordType& record, const uint8_t* tlvDataBasePtr, size_t tlvDataLen) const
318  {
319  TLVRecordType resRec(nullptr); // for NRVO optimization
320 
321  if (record.isNull())
322  return resRec;
323 
324  if (!TLVRecordType::canAssign(record.getRecordBasePtr() + record.getTotalSize(),
325  tlvDataBasePtr - record.getRecordBasePtr() + tlvDataLen -
326  record.getTotalSize()))
327  return resRec;
328 
329  resRec.assign(record.getRecordBasePtr() + record.getTotalSize());
330 
331  if (resRec.getTotalSize() == 0)
332  resRec.assign(nullptr);
333 
334  // resRec pointer is out-bounds of the TLV records memory
335  if ((resRec.getRecordBasePtr() - tlvDataBasePtr) < 0)
336  resRec.assign(nullptr);
337 
338  // resRec pointer is out-bounds of the TLV records memory
339  if (!resRec.isNull() && resRec.getRecordBasePtr() + resRec.getTotalSize() > tlvDataBasePtr + tlvDataLen)
340  resRec.assign(nullptr);
341 
342  return resRec;
343  }
344 
353  TLVRecordType getTLVRecord(uint32_t recordType, uint8_t* tlvDataBasePtr, size_t tlvDataLen) const
354  {
355  TLVRecordType curRec = getFirstTLVRecord(tlvDataBasePtr, tlvDataLen);
356  while (!curRec.isNull())
357  {
358  if (curRec.getType() == recordType)
359  {
360  return curRec;
361  }
362 
363  curRec = getNextTLVRecord(curRec, tlvDataBasePtr, tlvDataLen);
364  }
365 
366  curRec.assign(nullptr);
367  return curRec; // for NRVO optimization
368  }
369 
379  size_t getTLVRecordCount(uint8_t* tlvDataBasePtr, size_t tlvDataLen) const
380  {
381  if (m_RecordCount != static_cast<size_t>(-1))
382  return m_RecordCount;
383 
384  m_RecordCount = 0;
385  TLVRecordType curRec = getFirstTLVRecord(tlvDataBasePtr, tlvDataLen);
386  while (!curRec.isNull())
387  {
388  m_RecordCount++;
389  curRec = getNextTLVRecord(curRec, tlvDataBasePtr, tlvDataLen);
390  }
391 
392  return m_RecordCount;
393  }
394 
402  void changeTLVRecordCount(int changedBy)
403  {
404  if (m_RecordCount != static_cast<size_t>(-1))
405  m_RecordCount += changedBy;
406  }
407  };
408 
419  {
420  protected:
422 
423  TLVRecordBuilder(uint32_t recType, const uint8_t* recValue, uint8_t recValueLen);
424 
425  TLVRecordBuilder(uint32_t recType, uint8_t recValue);
426 
427  TLVRecordBuilder(uint32_t recType, uint16_t recValue);
428 
429  TLVRecordBuilder(uint32_t recType, uint32_t recValue);
430 
431  TLVRecordBuilder(uint32_t recType, const IPv4Address& recValue);
432 
433  TLVRecordBuilder(uint32_t recType, const std::string& recValue, bool valueIsHexString = false);
434 
435  TLVRecordBuilder(const TLVRecordBuilder& other);
436 
437  TLVRecordBuilder& operator=(const TLVRecordBuilder& other);
438 
439  virtual ~TLVRecordBuilder();
440 
441  void init(uint32_t recType, const uint8_t* recValue, size_t recValueLen);
442 
443  uint8_t* m_RecValue;
444  size_t m_RecValueLen;
445  uint32_t m_RecType;
446 
447  private:
448  void copyData(const TLVRecordBuilder& other);
449  };
450 } // namespace pcpp
Definition: IpAddress.h:32
Definition: TLVData.h:419
Definition: TLVData.h:23
TLVRecord(uint8_t *recordRawData)
Definition: TLVData.h:45
TLVRecord(const TLVRecord &other)
Definition: TLVData.h:55
virtual size_t getTotalSize() const =0
virtual ~TLVRecord()=default
TRecType getType() const
Definition: TLVData.h:131
bool setValue(T newValue, int valueOffset=0)
Definition: TLVData.h:214
bool operator!=(const TLVRecord &rhs) const
Definition: TLVData.h:123
uint8_t * getRecordBasePtr() const
Definition: TLVData.h:169
uint8_t * getValue() const
Definition: TLVData.h:142
bool operator==(const TLVRecord &rhs) const
Definition: TLVData.h:104
static bool canAssign(const uint8_t *recordRawData, size_t tlvDataLen)
Definition: TLVData.h:80
virtual size_t getDataSize() const =0
bool isNotNull() const
Definition: TLVData.h:161
bool isNull() const
Definition: TLVData.h:153
T getValueAs(size_t offset=0) const
Definition: TLVData.h:195
TLVRecord & operator=(const TLVRecord &other)
Definition: TLVData.h:92
void purgeRecordData()
Definition: TLVData.h:177
void assign(uint8_t *recordRawData)
Definition: TLVData.h:69
Definition: TLVData.h:246
void changeTLVRecordCount(int changedBy)
Definition: TLVData.h:402
TLVRecordReader & operator=(const TLVRecordReader &other)
Definition: TLVData.h:276
virtual ~TLVRecordReader()=default
TLVRecordType getTLVRecord(uint32_t recordType, uint8_t *tlvDataBasePtr, size_t tlvDataLen) const
Definition: TLVData.h:353
TLVRecordReader(const TLVRecordReader &other)
Definition: TLVData.h:262
TLVRecordType getNextTLVRecord(TLVRecordType &record, const uint8_t *tlvDataBasePtr, size_t tlvDataLen) const
Definition: TLVData.h:317
TLVRecordReader()
Definition: TLVData.h:254
TLVRecordType getFirstTLVRecord(uint8_t *tlvDataBasePtr, size_t tlvDataLen) const
Definition: TLVData.h:290
size_t getTLVRecordCount(uint8_t *tlvDataBasePtr, size_t tlvDataLen) const
Definition: TLVData.h:379
The main namespace for the PcapPlusPlus lib.
Definition: TLVData.h:28
uint8_t recordValue[]
Definition: TLVData.h:34
TRecType recordType
Definition: TLVData.h:30
TRecLen recordLen
Definition: TLVData.h:32