/src/PcapPlusPlus/Packet++/header/TLVData.h
Line | Count | Source (jump to first uncovered line) |
1 | | #ifndef PACKETPP_TLV_DATA |
2 | | #define PACKETPP_TLV_DATA |
3 | | |
4 | | #include "Layer.h" |
5 | | #include "IpAddress.h" |
6 | | #include <string.h> |
7 | | |
8 | | /// @file |
9 | | |
10 | | /** |
11 | | * \namespace pcpp |
12 | | * \brief The main namespace for the PcapPlusPlus lib |
13 | | */ |
14 | | namespace pcpp |
15 | | { |
16 | | /** |
17 | | * @class TLVRecord |
18 | | * A wrapper class for a Type-Length-Value (TLV) record. This class does not create or modify TLV records, but rather |
19 | | * serves as a wrapper and provides useful methods for retrieving data from them. This class has several abstract methods |
20 | | * that should be implemented in derived classes. These methods are for record length value calculation (the 'L' in TLV) |
21 | | * which is implemented differently in different protocols |
22 | | */ |
23 | | template<typename TRecType, typename TRecLen> |
24 | | class TLVRecord |
25 | | { |
26 | | protected: |
27 | | |
28 | | /** A struct representing the TLV construct */ |
29 | | struct TLVRawData |
30 | | { |
31 | | /** Record type */ |
32 | | TRecType recordType; |
33 | | /** Record length in bytes */ |
34 | | TRecLen recordLen; |
35 | | /** Record value (variable size) */ |
36 | | uint8_t recordValue[]; |
37 | | }; |
38 | | |
39 | | TLVRawData* m_Data; |
40 | | |
41 | | public: |
42 | | |
43 | | /** |
44 | | * A c'tor for this class that gets a pointer to the TLV record raw data (byte array) |
45 | | * @param[in] recordRawData A pointer to the TLV record raw data |
46 | | */ |
47 | | TLVRecord(uint8_t* recordRawData) |
48 | 0 | { |
49 | 0 | assign(recordRawData); |
50 | 0 | } Unexecuted instantiation: pcpp::TLVRecord<unsigned char, unsigned char>::TLVRecord(unsigned char*) Unexecuted instantiation: pcpp::TLVRecord<unsigned short, unsigned short>::TLVRecord(unsigned char*) |
51 | | |
52 | | /** |
53 | | * A copy c'tor for this class. This copy c'tor doesn't copy the TLV data, but only the pointer to it, |
54 | | * which means that after calling it both the old and the new instance will point to the same TLV raw data |
55 | | * @param[in] other The TLVRecord instance to copy from |
56 | | */ |
57 | | TLVRecord(const TLVRecord& other) |
58 | 0 | { |
59 | 0 | m_Data = other.m_Data; |
60 | 0 | } |
61 | | |
62 | | /** |
63 | | * A d'tor for this class, currently does nothing |
64 | | */ |
65 | 0 | virtual ~TLVRecord() { } Unexecuted instantiation: pcpp::TLVRecord<unsigned char, unsigned char>::~TLVRecord() Unexecuted instantiation: pcpp::TLVRecord<unsigned short, unsigned short>::~TLVRecord() |
66 | | |
67 | | /** |
68 | | * Assign a pointer to the TLV record raw data (byte array) |
69 | | * @param[in] recordRawData A pointer to the TLV record raw data |
70 | | */ |
71 | | void assign(uint8_t* recordRawData) |
72 | 0 | { |
73 | 0 | if(recordRawData == NULL) |
74 | 0 | m_Data = NULL; |
75 | 0 | else |
76 | 0 | m_Data = (TLVRawData*)recordRawData; |
77 | 0 | } Unexecuted instantiation: pcpp::TLVRecord<unsigned char, unsigned char>::assign(unsigned char*) Unexecuted instantiation: pcpp::TLVRecord<unsigned short, unsigned short>::assign(unsigned char*) |
78 | | |
79 | | /** |
80 | | * Overload of the assignment operator. This operator doesn't copy the TLV data, but rather copies the pointer to it, |
81 | | * which means that after calling it both the old and the new instance will point to the same TLV raw data |
82 | | * @param[in] other The TLVRecord instance to assign |
83 | | */ |
84 | | TLVRecord& operator=(const TLVRecord& other) |
85 | 0 | { |
86 | 0 | m_Data = other.m_Data; |
87 | 0 | return *this; |
88 | 0 | } Unexecuted instantiation: pcpp::TLVRecord<unsigned char, unsigned char>::operator=(pcpp::TLVRecord<unsigned char, unsigned char> const&) Unexecuted instantiation: pcpp::TLVRecord<unsigned short, unsigned short>::operator=(pcpp::TLVRecord<unsigned short, unsigned short> const&) |
89 | | |
90 | | /** |
91 | | * Overload of the equality operator. Two record are equal if both of them point to the same data, or if they point |
92 | | * to different data but their total size is equal and the raw data they both contain is similar. |
93 | | * @param[in] rhs The object to compare to |
94 | | * @return True if both objects are equal, false otherwise |
95 | | */ |
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 | | |
110 | | /** |
111 | | * Overload of the not equal operator. |
112 | | * @param[in] rhs The object to compare to |
113 | | * @return True if objects are not equal, false otherwise |
114 | | */ |
115 | | bool operator!=(const TLVRecord& rhs) const |
116 | | { |
117 | | return !operator==(rhs); |
118 | | } |
119 | | |
120 | | /** |
121 | | * @return The type field of the record (the 'T' in __Type__-Length-Value) |
122 | | */ |
123 | 0 | TRecType getType() const { return m_Data->recordType; } |
124 | | |
125 | | /** |
126 | | * @return A pointer to the value of the record as byte array (the 'V' in Type-Length- __Value__) |
127 | | */ |
128 | 0 | uint8_t* getValue() const { return m_Data->recordValue; } |
129 | | |
130 | | /** |
131 | | * @return True if the TLV record raw data is NULL, false otherwise |
132 | | */ |
133 | 0 | bool isNull() const { return (m_Data == NULL); } Unexecuted instantiation: pcpp::TLVRecord<unsigned char, unsigned char>::isNull() const Unexecuted instantiation: pcpp::TLVRecord<unsigned short, unsigned short>::isNull() const |
134 | | |
135 | | /** |
136 | | * @return True if the TLV record raw data is not NULL, false otherwise |
137 | | */ |
138 | 0 | bool isNotNull() const { return (m_Data != NULL); } |
139 | | |
140 | | /** |
141 | | * @return A pointer to the TLV record raw data byte stream |
142 | | */ |
143 | 0 | uint8_t* getRecordBasePtr() const { return (uint8_t*)m_Data; } Unexecuted instantiation: pcpp::TLVRecord<unsigned char, unsigned char>::getRecordBasePtr() const Unexecuted instantiation: pcpp::TLVRecord<unsigned short, unsigned short>::getRecordBasePtr() const |
144 | | |
145 | | /** |
146 | | * Free the memory of the TLV record raw data |
147 | | */ |
148 | 0 | void purgeRecordData() { if (!isNull()) delete [] m_Data; } Unexecuted instantiation: pcpp::TLVRecord<unsigned char, unsigned char>::purgeRecordData() Unexecuted instantiation: pcpp::TLVRecord<unsigned short, unsigned short>::purgeRecordData() |
149 | | |
150 | | /** |
151 | | * A templated method to retrieve the record data as a certain type T. For example, if record data is 4B long |
152 | | * (integer) then this method should be used as getValueAs<int>() and it will return the record data as an integer.<BR> |
153 | | * Notice this return value is a copy of the data, not a pointer to the actual data |
154 | | * @param[in] offset The offset in the record data to start reading the value from. Useful for cases when you want |
155 | | * to read some of the data that doesn't start at offset 0. This is an optional parameter and the default value |
156 | | * is 0, meaning start reading the value at the beginning of the record data |
157 | | * @return The record data as type T |
158 | | */ |
159 | | template<typename T> |
160 | | T getValueAs(size_t offset = 0) const |
161 | 0 | { |
162 | 0 | if (getDataSize() - offset < sizeof(T)) |
163 | 0 | return 0; |
164 | | |
165 | 0 | T result; |
166 | 0 | memcpy(&result, m_Data->recordValue + offset, sizeof(T)); |
167 | 0 | return result; |
168 | 0 | } Unexecuted instantiation: unsigned int pcpp::TLVRecord<unsigned char, unsigned char>::getValueAs<unsigned int>(unsigned long) const Unexecuted instantiation: unsigned char pcpp::TLVRecord<unsigned char, unsigned char>::getValueAs<unsigned char>(unsigned long) const |
169 | | |
170 | | /** |
171 | | * A templated method to copy data of type T into the TLV record data. For example: if record data is 4[Bytes] long use |
172 | | * this method with \<int\> to set an integer value into the record data: setValue<int>(num) |
173 | | * @param[in] newValue The value of type T to copy to the record data |
174 | | * @param[in] valueOffset An optional parameter that specifies where to start setting the record data (default set to 0). For example: |
175 | | * if record data is 20 bytes long and you only need to set the 4 last bytes as integer then use this method like this: |
176 | | * setValue<int>(num, 16) |
177 | | * @return True if value was set successfully or false if the size of T is larger than the record data size |
178 | | */ |
179 | | template<typename T> |
180 | | bool setValue(T newValue, int valueOffset = 0) |
181 | 0 | { |
182 | 0 | if (getDataSize() < sizeof(T)) |
183 | 0 | return false; |
184 | | |
185 | 0 | memcpy(m_Data->recordValue + valueOffset, &newValue, sizeof(T)); |
186 | 0 | return true; |
187 | 0 | } Unexecuted instantiation: bool pcpp::TLVRecord<unsigned char, unsigned char>::setValue<unsigned int>(unsigned int, int) Unexecuted instantiation: bool pcpp::TLVRecord<unsigned char, unsigned char>::setValue<unsigned char>(unsigned char, int) |
188 | | |
189 | | /** |
190 | | * @return The total size of the TLV record (in bytes) |
191 | | */ |
192 | | virtual size_t getTotalSize() const = 0; |
193 | | |
194 | | /** |
195 | | * @return The size of the record value (meaning the size of the 'V' part in TLV) |
196 | | */ |
197 | | virtual size_t getDataSize() const = 0; |
198 | | }; |
199 | | |
200 | | |
201 | | /** |
202 | | * @class TLVRecordReader |
203 | | * A class for reading TLV records data out of a byte stream. This class contains helper methods for retrieving and |
204 | | * counting TLV records. This is a template class that expects template argument class derived from TLVRecord. |
205 | | */ |
206 | | template<typename TLVRecordType> |
207 | | class TLVRecordReader |
208 | | { |
209 | | private: |
210 | | mutable size_t m_RecordCount; |
211 | | |
212 | | public: |
213 | | |
214 | | /** |
215 | | * A default c'tor for this class |
216 | | */ |
217 | 502k | TLVRecordReader() { m_RecordCount = (size_t)-1; } pcpp::TLVRecordReader<pcpp::IPv4Option>::TLVRecordReader() Line | Count | Source | 217 | 346k | TLVRecordReader() { m_RecordCount = (size_t)-1; } |
pcpp::TLVRecordReader<pcpp::PPPoEDiscoveryLayer::PPPoETag>::TLVRecordReader() Line | Count | Source | 217 | 908 | TLVRecordReader() { m_RecordCount = (size_t)-1; } |
pcpp::TLVRecordReader<pcpp::NdpOption>::TLVRecordReader() Line | Count | Source | 217 | 388 | TLVRecordReader() { m_RecordCount = (size_t)-1; } |
pcpp::TLVRecordReader<pcpp::RadiusAttribute>::TLVRecordReader() Line | Count | Source | 217 | 172 | TLVRecordReader() { m_RecordCount = (size_t)-1; } |
pcpp::TLVRecordReader<pcpp::DhcpV6Option>::TLVRecordReader() Line | Count | Source | 217 | 739 | TLVRecordReader() { m_RecordCount = (size_t)-1; } |
pcpp::TLVRecordReader<pcpp::DhcpOption>::TLVRecordReader() Line | Count | Source | 217 | 448 | TLVRecordReader() { m_RecordCount = (size_t)-1; } |
pcpp::TLVRecordReader<pcpp::IPv6TLVOptionHeader::IPv6Option>::TLVRecordReader() Line | Count | Source | 217 | 7.25k | TLVRecordReader() { m_RecordCount = (size_t)-1; } |
pcpp::TLVRecordReader<pcpp::TcpOption>::TLVRecordReader() Line | Count | Source | 217 | 145k | TLVRecordReader() { m_RecordCount = (size_t)-1; } |
|
218 | | |
219 | | /** |
220 | | * A default copy c'tor for this class |
221 | | */ |
222 | | TLVRecordReader(const TLVRecordReader& other) |
223 | | { |
224 | | m_RecordCount = other.m_RecordCount; |
225 | | } |
226 | | |
227 | | /** |
228 | | * A d'tor for this class which currently does nothing |
229 | | */ |
230 | 502k | virtual ~TLVRecordReader() { } pcpp::TLVRecordReader<pcpp::IPv4Option>::~TLVRecordReader() Line | Count | Source | 230 | 346k | virtual ~TLVRecordReader() { } |
pcpp::TLVRecordReader<pcpp::PPPoEDiscoveryLayer::PPPoETag>::~TLVRecordReader() Line | Count | Source | 230 | 908 | virtual ~TLVRecordReader() { } |
pcpp::TLVRecordReader<pcpp::IPv6TLVOptionHeader::IPv6Option>::~TLVRecordReader() Line | Count | Source | 230 | 7.25k | virtual ~TLVRecordReader() { } |
pcpp::TLVRecordReader<pcpp::NdpOption>::~TLVRecordReader() Line | Count | Source | 230 | 388 | virtual ~TLVRecordReader() { } |
pcpp::TLVRecordReader<pcpp::RadiusAttribute>::~TLVRecordReader() Line | Count | Source | 230 | 172 | virtual ~TLVRecordReader() { } |
pcpp::TLVRecordReader<pcpp::DhcpV6Option>::~TLVRecordReader() Line | Count | Source | 230 | 739 | virtual ~TLVRecordReader() { } |
pcpp::TLVRecordReader<pcpp::DhcpOption>::~TLVRecordReader() Line | Count | Source | 230 | 448 | virtual ~TLVRecordReader() { } |
pcpp::TLVRecordReader<pcpp::TcpOption>::~TLVRecordReader() Line | Count | Source | 230 | 145k | virtual ~TLVRecordReader() { } |
|
231 | | |
232 | | /** |
233 | | * Overload of the assignment operator for this class |
234 | | * @param[in] other The TLVRecordReader instance to assign |
235 | | */ |
236 | | TLVRecordReader& operator=(const TLVRecordReader& other) |
237 | 0 | { |
238 | 0 | m_RecordCount = other.m_RecordCount; |
239 | 0 | return *this; |
240 | 0 | } Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::IPv4Option>::operator=(pcpp::TLVRecordReader<pcpp::IPv4Option> const&) Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::TcpOption>::operator=(pcpp::TLVRecordReader<pcpp::TcpOption> const&) |
241 | | |
242 | | /** |
243 | | * Get the first TLV record out of a byte stream |
244 | | * @param[in] tlvDataBasePtr A pointer to the TLV data byte stream |
245 | | * @param[in] tlvDataLen The TLV data byte stream length |
246 | | * @return An instance of type TLVRecordType that contains the first TLV record. If tlvDataBasePtr is NULL or |
247 | | * tlvDataLen is zero the returned TLVRecordType instance will be logically NULL, meaning TLVRecordType.isNull() will |
248 | | * return true |
249 | | */ |
250 | | TLVRecordType getFirstTLVRecord(uint8_t* tlvDataBasePtr, size_t tlvDataLen) const |
251 | 0 | { |
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 | 0 | TLVRecordType resRec(tlvDataBasePtr); // for NRVO optimization |
254 | | |
255 | | // check if there are records at all and the total size is not zero |
256 | 0 | if (tlvDataLen == 0 || resRec.getTotalSize() == 0) |
257 | 0 | resRec.assign(NULL); |
258 | |
|
259 | 0 | return resRec; |
260 | 0 | } Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::IPv4Option>::getFirstTLVRecord(unsigned char*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::DhcpV6Option>::getFirstTLVRecord(unsigned char*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::DhcpOption>::getFirstTLVRecord(unsigned char*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::IPv6TLVOptionHeader::IPv6Option>::getFirstTLVRecord(unsigned char*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::PPPoEDiscoveryLayer::PPPoETag>::getFirstTLVRecord(unsigned char*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::TcpOption>::getFirstTLVRecord(unsigned char*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::RadiusAttribute>::getFirstTLVRecord(unsigned char*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::NdpOption>::getFirstTLVRecord(unsigned char*, unsigned long) const |
261 | | |
262 | | /** |
263 | | * Get a TLV record that follows a given TLV record in a byte stream |
264 | | * @param[in] record A given TLV record |
265 | | * @param[in] tlvDataBasePtr A pointer to the TLV data byte stream |
266 | | * @param[in] tlvDataLen The TLV data byte stream length |
267 | | * @return An instance of type TLVRecordType that wraps the record following the record given as input. If the |
268 | | * input record.isNull() is true or if the next record is out of bounds of the byte stream, a logical NULL instance |
269 | | * of TLVRecordType will be returned, meaning TLVRecordType.isNull() will return true |
270 | | */ |
271 | | TLVRecordType getNextTLVRecord(TLVRecordType& record, const uint8_t* tlvDataBasePtr, size_t tlvDataLen) const |
272 | 0 | { |
273 | 0 | TLVRecordType resRec(NULL); // for NRVO optimization |
274 | |
|
275 | 0 | if (record.isNull()) |
276 | 0 | return resRec; |
277 | | |
278 | | // record pointer is out-bounds of the TLV records memory |
279 | 0 | if ((record.getRecordBasePtr() - tlvDataBasePtr) < 0) |
280 | 0 | return resRec; |
281 | | |
282 | | // record pointer is out-bounds of the TLV records memory |
283 | 0 | if (record.getRecordBasePtr() - tlvDataBasePtr + (int)record.getTotalSize() >= (int)tlvDataLen) |
284 | 0 | return resRec; |
285 | | |
286 | 0 | resRec.assign(record.getRecordBasePtr() + record.getTotalSize()); |
287 | 0 | if (resRec.getTotalSize() == 0) |
288 | 0 | resRec.assign(NULL); |
289 | |
|
290 | 0 | return resRec; |
291 | 0 | } Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::IPv4Option>::getNextTLVRecord(pcpp::IPv4Option&, unsigned char const*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::DhcpV6Option>::getNextTLVRecord(pcpp::DhcpV6Option&, unsigned char const*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::DhcpOption>::getNextTLVRecord(pcpp::DhcpOption&, unsigned char const*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::IPv6TLVOptionHeader::IPv6Option>::getNextTLVRecord(pcpp::IPv6TLVOptionHeader::IPv6Option&, unsigned char const*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::PPPoEDiscoveryLayer::PPPoETag>::getNextTLVRecord(pcpp::PPPoEDiscoveryLayer::PPPoETag&, unsigned char const*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::TcpOption>::getNextTLVRecord(pcpp::TcpOption&, unsigned char const*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::RadiusAttribute>::getNextTLVRecord(pcpp::RadiusAttribute&, unsigned char const*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::NdpOption>::getNextTLVRecord(pcpp::NdpOption&, unsigned char const*, unsigned long) const |
292 | | |
293 | | /** |
294 | | * Search for the first TLV record that corresponds to a given record type (the 'T' in __Type__-Length-Value) |
295 | | * @param[in] recordType The record type to search for |
296 | | * @param[in] tlvDataBasePtr A pointer to the TLV data byte stream |
297 | | * @param[in] tlvDataLen The TLV data byte stream length |
298 | | * @return An instance of type TLVRecordType that contains the result record. If record was not found a logical |
299 | | * NULL instance of TLVRecordType will be returned, meaning TLVRecordType.isNull() will return true |
300 | | */ |
301 | | TLVRecordType getTLVRecord(uint32_t recordType, uint8_t* tlvDataBasePtr, size_t tlvDataLen) const |
302 | 0 | { |
303 | 0 | TLVRecordType curRec = getFirstTLVRecord(tlvDataBasePtr, tlvDataLen); |
304 | 0 | while (!curRec.isNull()) |
305 | 0 | { |
306 | 0 | if (curRec.getType() == recordType) |
307 | 0 | { |
308 | 0 | return curRec; |
309 | 0 | } |
310 | | |
311 | 0 | curRec = getNextTLVRecord(curRec, tlvDataBasePtr, tlvDataLen); |
312 | 0 | } |
313 | | |
314 | 0 | curRec.assign(NULL); |
315 | 0 | return curRec; // for NRVO optimization |
316 | 0 | } Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::IPv4Option>::getTLVRecord(unsigned int, unsigned char*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::DhcpV6Option>::getTLVRecord(unsigned int, unsigned char*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::DhcpOption>::getTLVRecord(unsigned int, unsigned char*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::IPv6TLVOptionHeader::IPv6Option>::getTLVRecord(unsigned int, unsigned char*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::PPPoEDiscoveryLayer::PPPoETag>::getTLVRecord(unsigned int, unsigned char*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::TcpOption>::getTLVRecord(unsigned int, unsigned char*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::RadiusAttribute>::getTLVRecord(unsigned int, unsigned char*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::NdpOption>::getTLVRecord(unsigned int, unsigned char*, unsigned long) const |
317 | | |
318 | | /** |
319 | | * Get the TLV record count in a given TLV data byte stream. For efficiency purposes the count is being cached |
320 | | * so only the first call to this method will go over all the TLV records, while all consequent calls will return |
321 | | * the cached number. This implies that if there is a change in the number of records, it's the user's responsibility |
322 | | * to call changeTLVRecordCount() with the record count change |
323 | | * @param[in] tlvDataBasePtr A pointer to the TLV data byte stream |
324 | | * @param[in] tlvDataLen The TLV data byte stream length |
325 | | * @return The TLV record count |
326 | | */ |
327 | | size_t getTLVRecordCount(uint8_t* tlvDataBasePtr, size_t tlvDataLen) const |
328 | 0 | { |
329 | 0 | if (m_RecordCount != (size_t)-1) |
330 | 0 | return m_RecordCount; |
331 | | |
332 | 0 | m_RecordCount = 0; |
333 | 0 | TLVRecordType curRec = getFirstTLVRecord(tlvDataBasePtr, tlvDataLen); |
334 | 0 | while (!curRec.isNull()) |
335 | 0 | { |
336 | 0 | m_RecordCount++; |
337 | 0 | curRec = getNextTLVRecord(curRec, tlvDataBasePtr, tlvDataLen); |
338 | 0 | } |
339 | |
|
340 | 0 | return m_RecordCount; |
341 | 0 | } Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::IPv4Option>::getTLVRecordCount(unsigned char*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::DhcpV6Option>::getTLVRecordCount(unsigned char*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::DhcpOption>::getTLVRecordCount(unsigned char*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::IPv6TLVOptionHeader::IPv6Option>::getTLVRecordCount(unsigned char*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::PPPoEDiscoveryLayer::PPPoETag>::getTLVRecordCount(unsigned char*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::TcpOption>::getTLVRecordCount(unsigned char*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::RadiusAttribute>::getTLVRecordCount(unsigned char*, unsigned long) const Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::NdpOption>::getTLVRecordCount(unsigned char*, unsigned long) const |
342 | | |
343 | | /** |
344 | | * As described in getTLVRecordCount(), the TLV record count is being cached for efficiency purposes. So if the |
345 | | * number of TLV records change, it's the user's responsibility to call this method with the number of TLV records |
346 | | * being added or removed. If records were added the change should be a positive number, or a negative number |
347 | | * if records were removed |
348 | | * @param[in] changedBy Number of records that were added or removed |
349 | | */ |
350 | 0 | void changeTLVRecordCount(int changedBy) { if (m_RecordCount != (size_t)-1) m_RecordCount += changedBy; } Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::IPv4Option>::changeTLVRecordCount(int) Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::DhcpV6Option>::changeTLVRecordCount(int) Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::DhcpOption>::changeTLVRecordCount(int) Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::IPv6TLVOptionHeader::IPv6Option>::changeTLVRecordCount(int) Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::PPPoEDiscoveryLayer::PPPoETag>::changeTLVRecordCount(int) Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::TcpOption>::changeTLVRecordCount(int) Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::RadiusAttribute>::changeTLVRecordCount(int) Unexecuted instantiation: pcpp::TLVRecordReader<pcpp::NdpOption>::changeTLVRecordCount(int) |
351 | | }; |
352 | | |
353 | | |
354 | | /** |
355 | | * @class TLVRecordBuilder |
356 | | * A base class for building Type-Length-Value (TLV) records. This builder receives the record parameters in its c'tor, |
357 | | * builds the record raw buffer and provides a method to build a TLVRecord object out of it. Please notice this is |
358 | | * a base class that lacks the capability of actually building TLVRecord objects and also cannot be instantiated. The |
359 | | * reason for that is that different protocols build TLV records in different ways, so these missing capabilities will |
360 | | * be implemented by the derived classes which are specific to each protocol. This class only provides the common |
361 | | * infrastructure that will be used by them |
362 | | */ |
363 | | class TLVRecordBuilder |
364 | | { |
365 | | protected: |
366 | | |
367 | | TLVRecordBuilder(); |
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 | | |
383 | | TLVRecordBuilder& operator=(const TLVRecordBuilder& other); |
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 |