PcapPlusPlus  23.09
TLVData.h
Go to the documentation of this file.
1 #ifndef PACKETPP_TLV_DATA
2 #define PACKETPP_TLV_DATA
3 
4 #include "Layer.h"
5 #include "IpAddress.h"
6 #include <string.h>
7 
9 
14 namespace pcpp
15 {
23  template<typename TRecType, typename TRecLen>
24  class TLVRecord
25  {
26  protected:
27 
29  struct TLVRawData
30  {
32  TRecType recordType;
34  TRecLen recordLen;
36  uint8_t recordValue[];
37  };
38 
39  TLVRawData* m_Data;
40 
41  public:
42 
47  TLVRecord(uint8_t* recordRawData)
48  {
49  assign(recordRawData);
50  }
51 
57  TLVRecord(const TLVRecord& other)
58  {
59  m_Data = other.m_Data;
60  }
61 
65  virtual ~TLVRecord() { }
66 
71  void assign(uint8_t* recordRawData)
72  {
73  if(recordRawData == NULL)
74  m_Data = NULL;
75  else
76  m_Data = (TLVRawData*)recordRawData;
77  }
78 
84  TLVRecord& operator=(const TLVRecord& other)
85  {
86  m_Data = other.m_Data;
87  return *this;
88  }
89 
96  bool operator==(const TLVRecord& rhs) const
97  {
98  if (m_Data == rhs.m_Data)
99  return true;
100 
101  if (getTotalSize() != rhs.getTotalSize())
102  return false;
103 
104  if (isNull() || ((TLVRecord&)rhs).isNull())
105  return false;
106 
107  return (memcmp(m_Data, rhs.m_Data, getTotalSize()) == 0);
108  }
109 
115  bool operator!=(const TLVRecord& rhs) const
116  {
117  return !operator==(rhs);
118  }
119 
123  TRecType getType() const {
124  if (m_Data == nullptr)
125  return 0;
126 
127  return m_Data->recordType;
128  }
129 
133  uint8_t* getValue() const {
134  if (m_Data == nullptr)
135  return nullptr;
136 
137  return m_Data->recordValue;
138  }
139 
143  bool isNull() const { return (m_Data == nullptr); }
144 
148  bool isNotNull() const { return (m_Data != nullptr); }
149 
153  uint8_t* getRecordBasePtr() const { return (uint8_t*)m_Data; }
154 
158  void purgeRecordData() { if (!isNull()) delete [] m_Data; }
159 
169  template<typename T>
170  T getValueAs(size_t offset = 0) const
171  {
172  if (getDataSize() - offset < sizeof(T))
173  return 0;
174 
175  T result;
176  memcpy(&result, m_Data->recordValue + offset, sizeof(T));
177  return result;
178  }
179 
189  template<typename T>
190  bool setValue(T newValue, int valueOffset = 0)
191  {
192  if (getDataSize() < sizeof(T))
193  return false;
194 
195  memcpy(m_Data->recordValue + valueOffset, &newValue, sizeof(T));
196  return true;
197  }
198 
202  virtual size_t getTotalSize() const = 0;
203 
207  virtual size_t getDataSize() const = 0;
208  };
209 
210 
216  template<typename TLVRecordType>
218  {
219  private:
220  mutable size_t m_RecordCount;
221 
222  public:
223 
227  TLVRecordReader() { m_RecordCount = (size_t)-1; }
228 
233  {
234  m_RecordCount = other.m_RecordCount;
235  }
236 
240  virtual ~TLVRecordReader() { }
241 
247  {
248  m_RecordCount = other.m_RecordCount;
249  return *this;
250  }
251 
260  TLVRecordType getFirstTLVRecord(uint8_t* tlvDataBasePtr, size_t tlvDataLen) const
261  {
262  TLVRecordType resRec(tlvDataBasePtr); // for NRVO optimization
263 
264  // resRec pointer is out-bounds of the TLV records memory
265  if (resRec.getRecordBasePtr() + resRec.getTotalSize() > tlvDataBasePtr + tlvDataLen)
266  resRec.assign(NULL);
267 
268  // check if there are records at all and the total size is not zero
269  if (!resRec.isNull() && (tlvDataLen == 0 || resRec.getTotalSize() == 0))
270  resRec.assign(NULL);
271 
272  return resRec;
273  }
274 
284  TLVRecordType getNextTLVRecord(TLVRecordType& record, const uint8_t* tlvDataBasePtr, size_t tlvDataLen) const
285  {
286  TLVRecordType resRec(NULL); // for NRVO optimization
287 
288  if (record.isNull())
289  return resRec;
290 
291  resRec.assign(record.getRecordBasePtr() + record.getTotalSize());
292  if (resRec.getTotalSize() == 0)
293  resRec.assign(NULL);
294 
295  // resRec pointer is out-bounds of the TLV records memory
296  if ((resRec.getRecordBasePtr() - tlvDataBasePtr) < 0)
297  resRec.assign(NULL);
298 
299  // resRec pointer is out-bounds of the TLV records memory
300  if (!resRec.isNull() && resRec.getRecordBasePtr() + resRec.getTotalSize() > tlvDataBasePtr + tlvDataLen)
301  resRec.assign(NULL);
302 
303  return resRec;
304  }
305 
314  TLVRecordType getTLVRecord(uint32_t recordType, uint8_t* tlvDataBasePtr, size_t tlvDataLen) const
315  {
316  TLVRecordType curRec = getFirstTLVRecord(tlvDataBasePtr, tlvDataLen);
317  while (!curRec.isNull())
318  {
319  if (curRec.getType() == recordType)
320  {
321  return curRec;
322  }
323 
324  curRec = getNextTLVRecord(curRec, tlvDataBasePtr, tlvDataLen);
325  }
326 
327  curRec.assign(NULL);
328  return curRec; // for NRVO optimization
329  }
330 
340  size_t getTLVRecordCount(uint8_t* tlvDataBasePtr, size_t tlvDataLen) const
341  {
342  if (m_RecordCount != (size_t)-1)
343  return m_RecordCount;
344 
345  m_RecordCount = 0;
346  TLVRecordType curRec = getFirstTLVRecord(tlvDataBasePtr, tlvDataLen);
347  while (!curRec.isNull())
348  {
349  m_RecordCount++;
350  curRec = getNextTLVRecord(curRec, tlvDataBasePtr, tlvDataLen);
351  }
352 
353  return m_RecordCount;
354  }
355 
363  void changeTLVRecordCount(int changedBy) { if (m_RecordCount != (size_t)-1) m_RecordCount += changedBy; }
364  };
365 
366 
377  {
378  protected:
379 
381 
382  TLVRecordBuilder(uint32_t recType, const uint8_t* recValue, uint8_t recValueLen);
383 
384  TLVRecordBuilder(uint32_t recType, uint8_t recValue);
385 
386  TLVRecordBuilder(uint32_t recType, uint16_t recValue);
387 
388  TLVRecordBuilder(uint32_t recType, uint32_t recValue);
389 
390  TLVRecordBuilder(uint32_t recType, const IPv4Address& recValue);
391 
392  TLVRecordBuilder(uint32_t recType, const std::string& recValue, bool valueIsHexString = false);
393 
394  TLVRecordBuilder(const TLVRecordBuilder& other);
395 
397 
398  virtual ~TLVRecordBuilder();
399 
400  void init(uint32_t recType, const uint8_t* recValue, size_t recValueLen);
401 
402  uint8_t* m_RecValue;
403  size_t m_RecValueLen;
404  uint32_t m_RecType;
405 
406  private:
407 
408  void copyData(const TLVRecordBuilder& other);
409  };
410 }
411 #endif // PACKETPP_TLV_DATA
The main namespace for the PcapPlusPlus lib.
TLVRecordType getTLVRecord(uint32_t recordType, uint8_t *tlvDataBasePtr, size_t tlvDataLen) const
Definition: TLVData.h:314
uint8_t * getRecordBasePtr() const
Definition: TLVData.h:153
TLVRecord(uint8_t *recordRawData)
Definition: TLVData.h:47
TRecType recordType
Definition: TLVData.h:32
TRecType getType() const
Definition: TLVData.h:123
Definition: TLVData.h:376
Definition: TLVData.h:24
size_t getTLVRecordCount(uint8_t *tlvDataBasePtr, size_t tlvDataLen) const
Definition: TLVData.h:340
TLVRecordType getFirstTLVRecord(uint8_t *tlvDataBasePtr, size_t tlvDataLen) const
Definition: TLVData.h:260
void changeTLVRecordCount(int changedBy)
Definition: TLVData.h:363
TLVRecordType getNextTLVRecord(TLVRecordType &record, const uint8_t *tlvDataBasePtr, size_t tlvDataLen) const
Definition: TLVData.h:284
TLVRecordReader & operator=(const TLVRecordReader &other)
Definition: TLVData.h:246
virtual ~TLVRecord()
Definition: TLVData.h:65
Definition: TLVData.h:217
void assign(uint8_t *recordRawData)
Definition: TLVData.h:71
Definition: TLVData.h:29
virtual size_t getDataSize() const =0
bool operator!=(const TLVRecord &rhs) const
Definition: TLVData.h:115
bool isNull() const
Definition: TLVData.h:143
Definition: IpAddress.h:42
TLVRecord & operator=(const TLVRecord &other)
Definition: TLVData.h:84
TLVRecordReader(const TLVRecordReader &other)
Definition: TLVData.h:232
virtual ~TLVRecordReader()
Definition: TLVData.h:240
bool setValue(T newValue, int valueOffset=0)
Definition: TLVData.h:190
TRecLen recordLen
Definition: TLVData.h:34
uint8_t recordValue[]
Definition: TLVData.h:36
TLVRecordReader()
Definition: TLVData.h:227
T getValueAs(size_t offset=0) const
Definition: TLVData.h:170
bool operator==(const TLVRecord &rhs) const
Definition: TLVData.h:96
bool isNotNull() const
Definition: TLVData.h:148
uint8_t * getValue() const
Definition: TLVData.h:133
TLVRecord(const TLVRecord &other)
Definition: TLVData.h:57
void purgeRecordData()
Definition: TLVData.h:158
virtual size_t getTotalSize() const =0