PcapPlusPlus  21.05+
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 { return m_Data->recordType; }
124 
128  uint8_t* getValue() const { return m_Data->recordValue; }
129 
133  bool isNull() const { return (m_Data == NULL); }
134 
138  bool isNotNull() const { return (m_Data != NULL); }
139 
143  uint8_t* getRecordBasePtr() const { return (uint8_t*)m_Data; }
144 
148  void purgeRecordData() { if (!isNull()) delete [] m_Data; }
149 
159  template<typename T>
160  T getValueAs(size_t offset = 0) const
161  {
162  if (getDataSize() - offset < sizeof(T))
163  return 0;
164 
165  T result;
166  memcpy(&result, m_Data->recordValue + offset, sizeof(T));
167  return result;
168  }
169 
179  template<typename T>
180  bool setValue(T newValue, int valueOffset = 0)
181  {
182  if (getDataSize() < sizeof(T))
183  return false;
184 
185  memcpy(m_Data->recordValue + valueOffset, &newValue, sizeof(T));
186  return true;
187  }
188 
192  virtual size_t getTotalSize() const = 0;
193 
197  virtual size_t getDataSize() const = 0;
198  };
199 
200 
206  template<typename TLVRecordType>
208  {
209  private:
210  mutable size_t m_RecordCount;
211 
212  public:
213 
217  TLVRecordReader() { m_RecordCount = (size_t)-1; }
218 
223  {
224  m_RecordCount = other.m_RecordCount;
225  }
226 
230  virtual ~TLVRecordReader() { }
231 
237  {
238  m_RecordCount = other.m_RecordCount;
239  return *this;
240  }
241 
250  TLVRecordType getFirstTLVRecord(uint8_t* tlvDataBasePtr, size_t tlvDataLen) const
251  {
252  // 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
253  TLVRecordType resRec(tlvDataBasePtr); // for NRVO optimization
254 
255  // check if there are records at all and the total size is not zero
256  if (tlvDataLen == 0 || resRec.getTotalSize() == 0)
257  resRec.assign(NULL);
258 
259  return resRec;
260  }
261 
271  TLVRecordType getNextTLVRecord(TLVRecordType& record, uint8_t* tlvDataBasePtr, size_t tlvDataLen) const
272  {
273  TLVRecordType resRec(NULL); // for NRVO optimization
274 
275  if (record.isNull())
276  return resRec;
277 
278  // record pointer is out-bounds of the TLV records memory
279  if ((record.getRecordBasePtr() - tlvDataBasePtr) < 0)
280  return resRec;
281 
282  // record pointer is out-bounds of the TLV records memory
283  if (record.getRecordBasePtr() - tlvDataBasePtr + (int)record.getTotalSize() >= (int)tlvDataLen)
284  return resRec;
285 
286  resRec.assign(record.getRecordBasePtr() + record.getTotalSize());
287  if (resRec.getTotalSize() == 0)
288  resRec.assign(NULL);
289 
290  return resRec;
291  }
292 
301  TLVRecordType getTLVRecord(uint32_t recordType, uint8_t* tlvDataBasePtr, size_t tlvDataLen) const
302  {
303  TLVRecordType curRec = getFirstTLVRecord(tlvDataBasePtr, tlvDataLen);
304  while (!curRec.isNull())
305  {
306  if (curRec.getType() == recordType)
307  {
308  return curRec;
309  }
310 
311  curRec = getNextTLVRecord(curRec, tlvDataBasePtr, tlvDataLen);
312  }
313 
314  curRec.assign(NULL);
315  return curRec; // for NRVO optimization
316  }
317 
327  size_t getTLVRecordCount(uint8_t* tlvDataBasePtr, size_t tlvDataLen) const
328  {
329  if (m_RecordCount != (size_t)-1)
330  return m_RecordCount;
331 
332  m_RecordCount = 0;
333  TLVRecordType curRec = getFirstTLVRecord(tlvDataBasePtr, tlvDataLen);
334  while (!curRec.isNull())
335  {
336  m_RecordCount++;
337  curRec = getNextTLVRecord(curRec, tlvDataBasePtr, tlvDataLen);
338  }
339 
340  return m_RecordCount;
341  }
342 
350  void changeTLVRecordCount(int changedBy) { if (m_RecordCount != (size_t)-1) m_RecordCount += changedBy; }
351  };
352 
353 
364  {
365  protected:
366 
368 
369  TLVRecordBuilder(uint32_t recType, const uint8_t* recValue, uint8_t recValueLen);
370 
371  TLVRecordBuilder(uint32_t recType, uint8_t recValue);
372 
373  TLVRecordBuilder(uint32_t recType, uint16_t recValue);
374 
375  TLVRecordBuilder(uint32_t recType, uint32_t recValue);
376 
377  TLVRecordBuilder(uint32_t recType, const IPv4Address& recValue);
378 
379  TLVRecordBuilder(uint32_t recType, const std::string& recValue, bool valueIsHexString = false);
380 
381  TLVRecordBuilder(const TLVRecordBuilder& other);
382 
384 
385  virtual ~TLVRecordBuilder();
386 
387  void init(uint32_t recType, const uint8_t* recValue, size_t recValueLen);
388 
389  uint8_t* m_RecValue;
390  size_t m_RecValueLen;
391  uint32_t m_RecType;
392 
393  private:
394 
395  void copyData(const TLVRecordBuilder& other);
396  };
397 }
398 #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:301
uint8_t * getRecordBasePtr() const
Definition: TLVData.h:143
TLVRecord(uint8_t *recordRawData)
Definition: TLVData.h:47
TRecType recordType
Definition: TLVData.h:32
TRecType getType() const
Definition: TLVData.h:123
Definition: TLVData.h:363
Definition: TLVData.h:24
size_t getTLVRecordCount(uint8_t *tlvDataBasePtr, size_t tlvDataLen) const
Definition: TLVData.h:327
TLVRecordType getFirstTLVRecord(uint8_t *tlvDataBasePtr, size_t tlvDataLen) const
Definition: TLVData.h:250
void changeTLVRecordCount(int changedBy)
Definition: TLVData.h:350
TLVRecordReader & operator=(const TLVRecordReader &other)
Definition: TLVData.h:236
virtual ~TLVRecord()
Definition: TLVData.h:65
Definition: TLVData.h:207
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:133
Definition: IpAddress.h:27
TLVRecord & operator=(const TLVRecord &other)
Definition: TLVData.h:84
TLVRecordReader(const TLVRecordReader &other)
Definition: TLVData.h:222
virtual ~TLVRecordReader()
Definition: TLVData.h:230
TLVRecordType getNextTLVRecord(TLVRecordType &record, uint8_t *tlvDataBasePtr, size_t tlvDataLen) const
Definition: TLVData.h:271
bool setValue(T newValue, int valueOffset=0)
Definition: TLVData.h:180
TRecLen recordLen
Definition: TLVData.h:34
uint8_t recordValue[]
Definition: TLVData.h:36
TLVRecordReader()
Definition: TLVData.h:217
T getValueAs(size_t offset=0) const
Definition: TLVData.h:160
bool operator==(const TLVRecord &rhs) const
Definition: TLVData.h:96
bool isNotNull() const
Definition: TLVData.h:138
uint8_t * getValue() const
Definition: TLVData.h:128
TLVRecord(const TLVRecord &other)
Definition: TLVData.h:57
void purgeRecordData()
Definition: TLVData.h:148
virtual size_t getTotalSize() const =0