PcapPlusPlus  20.08+
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  class TLVRecord
24  {
25  protected:
26 
28  struct TLVRawData
29  {
31  uint8_t recordType;
33  uint8_t recordLen;
35  uint8_t recordValue[];
36  };
37 
38  TLVRawData* m_Data;
39 
40  public:
41 
46  TLVRecord(uint8_t* recordRawData)
47  {
48  assign(recordRawData);
49  }
50 
56  TLVRecord(const TLVRecord& other)
57  {
58  m_Data = other.m_Data;
59  }
60 
64  virtual ~TLVRecord() { }
65 
70  void assign(uint8_t* recordRawData)
71  {
72  if(recordRawData == NULL)
73  m_Data = NULL;
74  else
75  m_Data = (TLVRawData*)recordRawData;
76  }
77 
83  TLVRecord& operator=(const TLVRecord& other)
84  {
85  m_Data = other.m_Data;
86  return *this;
87  }
88 
95  bool operator==(const TLVRecord& rhs) const
96  {
97  if (m_Data == rhs.m_Data)
98  return true;
99 
100  if (getTotalSize() != rhs.getTotalSize())
101  return false;
102 
103  if (isNull() || ((TLVRecord&)rhs).isNull())
104  return false;
105 
106  return (memcmp(m_Data, rhs.m_Data, getTotalSize()) == 0);
107  }
108 
109 
113  uint8_t getType() const { return m_Data->recordType; }
114 
118  uint8_t* getValue() const { return m_Data->recordValue; }
119 
123  bool isNull() const { return (m_Data == NULL); }
124 
128  bool isNotNull() const { return (m_Data != NULL); }
129 
133  uint8_t* getRecordBasePtr() const { return (uint8_t*)m_Data; }
134 
138  void purgeRecordData() { if (!isNull()) delete [] m_Data; }
139 
149  template<typename T>
150  T getValueAs(size_t offset = 0) const
151  {
152  if (getDataSize() - offset < sizeof(T))
153  return 0;
154 
155  T result;
156  memcpy(&result, m_Data->recordValue + offset, sizeof(T));
157  return result;
158  }
159 
169  template<typename T>
170  bool setValue(T newValue, int valueOffset = 0)
171  {
172  if (getDataSize() < sizeof(T))
173  return false;
174 
175  memcpy(m_Data->recordValue + valueOffset, &newValue, sizeof(T));
176  return true;
177  }
178 
182  virtual size_t getTotalSize() const = 0;
183 
187  virtual size_t getDataSize() const = 0;
188  };
189 
190 
196  template<typename TLVRecordType>
198  {
199  private:
200  mutable size_t m_RecordCount;
201 
202  public:
203 
207  TLVRecordReader() { m_RecordCount = (size_t)-1; }
208 
213  {
214  m_RecordCount = other.m_RecordCount;
215  }
216 
220  virtual ~TLVRecordReader() { }
221 
227  {
228  m_RecordCount = other.m_RecordCount;
229  return *this;
230  }
231 
240  TLVRecordType getFirstTLVRecord(uint8_t* tlvDataBasePtr, size_t tlvDataLen) const
241  {
242  // In most cases tlvDataLen is not zero and the size is correct therefore the overhead is not significant if the checks will be done later
243  TLVRecordType resRec(tlvDataBasePtr); // for NRVO optimization
244 
245  // check if there are records at all and the total size is not zero
246  if (tlvDataLen == 0 || resRec.getTotalSize() == 0)
247  resRec.assign(NULL);
248 
249  return resRec;
250  }
251 
261  TLVRecordType getNextTLVRecord(TLVRecordType& record, uint8_t* tlvDataBasePtr, size_t tlvDataLen) const
262  {
263  TLVRecordType resRec(NULL); // for NRVO optimization
264 
265  if (record.isNull())
266  return resRec;
267 
268  // record pointer is out-bounds of the TLV records memory
269  if ((record.getRecordBasePtr() - tlvDataBasePtr) < 0)
270  return resRec;
271 
272  // record pointer is out-bounds of the TLV records memory
273  if (record.getRecordBasePtr() - tlvDataBasePtr + (int)record.getTotalSize() >= (int)tlvDataLen)
274  return resRec;
275 
276  resRec.assign(record.getRecordBasePtr() + record.getTotalSize());
277  if (resRec.getTotalSize() == 0)
278  resRec.assign(NULL);
279 
280  return resRec;
281  }
282 
291  TLVRecordType getTLVRecord(uint8_t recordType, uint8_t* tlvDataBasePtr, size_t tlvDataLen) const
292  {
293  TLVRecordType curRec = getFirstTLVRecord(tlvDataBasePtr, tlvDataLen);
294  while (!curRec.isNull())
295  {
296  if (curRec.getType() == recordType)
297  return curRec;
298 
299  curRec = getNextTLVRecord(curRec, tlvDataBasePtr, tlvDataLen);
300  }
301 
302  curRec.assign(NULL);
303  return curRec; // for NRVO optimization
304  }
305 
315  size_t getTLVRecordCount(uint8_t* tlvDataBasePtr, size_t tlvDataLen) const
316  {
317  if (m_RecordCount != (size_t)-1)
318  return m_RecordCount;
319 
320  m_RecordCount = 0;
321  TLVRecordType curRec = getFirstTLVRecord(tlvDataBasePtr, tlvDataLen);
322  while (!curRec.isNull())
323  {
324  m_RecordCount++;
325  curRec = getNextTLVRecord(curRec, tlvDataBasePtr, tlvDataLen);
326  }
327 
328  return m_RecordCount;
329  }
330 
338  void changeTLVRecordCount(int changedBy) { if (m_RecordCount != (size_t)-1) m_RecordCount += changedBy; }
339  };
340 
341 
352  {
353  protected:
354 
356 
357  TLVRecordBuilder(uint8_t recType, const uint8_t* recValue, uint8_t recValueLen);
358 
359  TLVRecordBuilder(uint8_t recType, uint8_t recValue);
360 
361  TLVRecordBuilder(uint8_t recType, uint16_t recValue);
362 
363  TLVRecordBuilder(uint8_t recType, uint32_t recValue);
364 
365  TLVRecordBuilder(uint8_t recType, const IPv4Address& recValue);
366 
367  TLVRecordBuilder(uint8_t recType, const std::string& recValue);
368 
369  TLVRecordBuilder(const TLVRecordBuilder& other);
370 
372 
373  virtual ~TLVRecordBuilder();
374 
375  void init(uint8_t recType, const uint8_t* recValue, uint8_t recValueLen);
376 
377  uint8_t* m_RecValue;
378  uint8_t m_RecValueLen;
379  uint8_t m_RecType;
380 
381  private:
382 
383  void copyData(const TLVRecordBuilder& other);
384  };
385 }
386 #endif // PACKETPP_TLV_DATA
The main namespace for the PcapPlusPlus lib.
uint8_t getType() const
Definition: TLVData.h:113
virtual size_t getDataSize() const =0
uint8_t recordType
Definition: TLVData.h:31
void purgeRecordData()
Definition: TLVData.h:138
Definition: TLVData.h:351
Definition: TLVData.h:23
uint8_t * getRecordBasePtr() const
Definition: TLVData.h:133
virtual ~TLVRecord()
Definition: TLVData.h:64
virtual size_t getTotalSize() const =0
size_t getTLVRecordCount(uint8_t *tlvDataBasePtr, size_t tlvDataLen) const
Definition: TLVData.h:315
TLVRecordType getFirstTLVRecord(uint8_t *tlvDataBasePtr, size_t tlvDataLen) const
Definition: TLVData.h:240
void changeTLVRecordCount(int changedBy)
Definition: TLVData.h:338
TLVRecord(const TLVRecord &other)
Definition: TLVData.h:56
TLVRecordReader & operator=(const TLVRecordReader &other)
Definition: TLVData.h:226
Definition: TLVData.h:197
TLVRecord & operator=(const TLVRecord &other)
Definition: TLVData.h:83
Definition: TLVData.h:28
bool isNotNull() const
Definition: TLVData.h:128
Definition: IpAddress.h:26
T getValueAs(size_t offset=0) const
Definition: TLVData.h:150
TLVRecordReader(const TLVRecordReader &other)
Definition: TLVData.h:212
uint8_t * getValue() const
Definition: TLVData.h:118
virtual ~TLVRecordReader()
Definition: TLVData.h:220
void assign(uint8_t *recordRawData)
Definition: TLVData.h:70
TLVRecordType getNextTLVRecord(TLVRecordType &record, uint8_t *tlvDataBasePtr, size_t tlvDataLen) const
Definition: TLVData.h:261
bool setValue(T newValue, int valueOffset=0)
Definition: TLVData.h:170
TLVRecordType getTLVRecord(uint8_t recordType, uint8_t *tlvDataBasePtr, size_t tlvDataLen) const
Definition: TLVData.h:291
TLVRecordReader()
Definition: TLVData.h:207
bool isNull() const
Definition: TLVData.h:123
TLVRecord(uint8_t *recordRawData)
Definition: TLVData.h:46
uint8_t recordValue[]
Definition: TLVData.h:35
bool operator==(const TLVRecord &rhs) const
Definition: TLVData.h:95
uint8_t recordLen
Definition: TLVData.h:33