/src/PcapPlusPlus/Packet++/header/DnsResourceData.h
Line | Count | Source (jump to first uncovered line) |
1 | | #pragma once |
2 | | |
3 | | #include "DnsResource.h" |
4 | | #include "IpAddress.h" |
5 | | #include <memory> |
6 | | #include <string> |
7 | | #include <stdint.h> |
8 | | |
9 | | /// @file |
10 | | |
11 | | /** |
12 | | * \namespace pcpp |
13 | | * \brief The main namespace for the PcapPlusPlus lib |
14 | | */ |
15 | | namespace pcpp |
16 | | { |
17 | | |
18 | | //Visual studio has always been stupid about returning something useful for __cplusplus |
19 | | //Only recently was this fixed - and even then it requires a specific hack to the command line during build |
20 | | //Its easier/more consistent to test _MSC_VER in VS |
21 | | //https://docs.microsoft.com/en-us/cpp/build/reference/zc-cplusplus?view=vs-2017 |
22 | | |
23 | | #if __cplusplus > 199711L || _MSC_VER >= 1800 //Maybe this can be 1600 for VS2010 |
24 | | #define PCPP_SMART_PTR(T) std::unique_ptr<T> |
25 | | #else |
26 | | #define PCPP_SMART_PTR(T) std::auto_ptr<T> |
27 | | #endif |
28 | | |
29 | | // forward declarations |
30 | | class IDnsResource; |
31 | | |
32 | | /** |
33 | | * @class IDnsResourceData |
34 | | * A wrapper class for storing DNS RR (resource record) data. This is the base class which introduces several abstract |
35 | | * methods for derived classes to implement for setting and retrieving the stored data. Each derived class will store |
36 | | * different type of DNS RR data and implement these methods accordingly (for example: IPv4/IPv6 addresses, MX data, |
37 | | * hostnames, raw byte data etc.) |
38 | | */ |
39 | | class IDnsResourceData |
40 | | { |
41 | | protected: |
42 | | |
43 | | // unimplemented private copy c'tor |
44 | | IDnsResourceData(const IDnsResourceData& other); |
45 | 49.8k | IDnsResourceData() { } |
46 | | |
47 | | size_t decodeName(const char* encodedName, char* result, IDnsResource* dnsResource) const; |
48 | | void encodeName(const std::string& decodedName, char* result, size_t& resultLen, IDnsResource* dnsResource) const; |
49 | | |
50 | | public: |
51 | | /** |
52 | | * A virtual d'tor, does nothing |
53 | | */ |
54 | 49.8k | virtual ~IDnsResourceData() { } |
55 | | |
56 | | /** |
57 | | * A templated method which takes a class that derives from IDnsResourceData as the template argument and |
58 | | * checks whether this instance is of this type |
59 | | * @return True if this instance is of the requested type, false otherwise |
60 | | */ |
61 | | template <class IDnsResourceDataType> |
62 | 49.8k | bool isTypeOf() const { return dynamic_cast<const IDnsResourceDataType*>(this) != NULL; } bool pcpp::IDnsResourceData::isTypeOf<pcpp::IPv4DnsResourceData>() const Line | Count | Source | 62 | 49.8k | bool isTypeOf() const { return dynamic_cast<const IDnsResourceDataType*>(this) != NULL; } |
Unexecuted instantiation: bool pcpp::IDnsResourceData::isTypeOf<pcpp::IPv6DnsResourceData>() const Unexecuted instantiation: bool pcpp::IDnsResourceData::isTypeOf<pcpp::StringDnsResourceData>() const Unexecuted instantiation: bool pcpp::IDnsResourceData::isTypeOf<pcpp::MxDnsResourceData>() const |
63 | | |
64 | | /** |
65 | | * A templated method which take a class that derives from IDnsResourceData as the template argument and tries to |
66 | | * cast the current instance as that type |
67 | | * @return A pointer to the current instance casted as the requested type or NULL if this instance isn't of this type |
68 | | */ |
69 | | template <class IDnsResourceDataType> |
70 | | IDnsResourceDataType* castAs() { return dynamic_cast<IDnsResourceDataType*>(this); } |
71 | | |
72 | | /** |
73 | | * @return A string that represents the current DNS RR data |
74 | | */ |
75 | | virtual std::string toString() const = 0; |
76 | | |
77 | | /** |
78 | | * Convert the DNS RR data into a byte array |
79 | | * @param[out] arr A pointer to a pre-allocated byte array where the result will be written to |
80 | | * @param[out] arrLength A reference to a 2-byte number where the result array length will be written to |
81 | | * @param[in] dnsResource A pointer to a DNS resource object where this DNS RR data will be stored |
82 | | * @return True if the DNS RR data was successfully converted into a byte array and written to the given array or |
83 | | * false if stored DNS RR data is invalid or if it could not be written to the given array |
84 | | */ |
85 | | virtual bool toByteArr(uint8_t* arr, size_t& arrLength, IDnsResource* dnsResource) const = 0; |
86 | | }; |
87 | | |
88 | | |
89 | | /** |
90 | | * @class DnsResourceDataPtr |
91 | | * A smart pointer class that holds pointers of type IDnsResourceData. This object is used in DnsResource#getData() |
92 | | */ |
93 | | class DnsResourceDataPtr : public PCPP_SMART_PTR(IDnsResourceData) |
94 | | { |
95 | | public: |
96 | | |
97 | | /** |
98 | | * A c'tor to this class |
99 | | * @param[in] ptr A pointer to IDnsResourceData |
100 | | */ |
101 | 0 | explicit DnsResourceDataPtr(IDnsResourceData* ptr) : PCPP_SMART_PTR(IDnsResourceData)(ptr) {} |
102 | | |
103 | | //Visual studio has always been stupid about returning something useful for __cplusplus |
104 | | //Only recently was this fixed - and even then it requires a specific hack to the command line during build |
105 | | //Its easier/more consistent to test _MSC_VER in VS |
106 | | //https://docs.microsoft.com/en-us/cpp/build/reference/zc-cplusplus?view=vs-2017 |
107 | | |
108 | | #if __cplusplus <= 199711L && _MSC_VER < 1800 //Maybe this can be 1600 for VS2010 |
109 | | DnsResourceDataPtr(const DnsResourceDataPtr& other) : PCPP_SMART_PTR(IDnsResourceData)((DnsResourceDataPtr&)other) {} |
110 | | #endif |
111 | | |
112 | | /** |
113 | | * A templated method which takes a class that derives from IDnsResourceData as the template argument and |
114 | | * checks whether the pointer stored in this object is of this type |
115 | | * @return True if the stored pointer is of the requested type, false otherwise |
116 | | */ |
117 | | template <class IDnsResourceDataType> |
118 | | bool isTypeOf() const { return get()->isTypeOf<IDnsResourceDataType>(); } |
119 | | |
120 | | /** |
121 | | * A templated method which take a class that derives from IDnsResourceData as the template argument and tries to |
122 | | * cast the pointer stored in this object as that type |
123 | | * @return A pointer to the stored pointer casted as the requested type or NULL if it isn't of this type |
124 | | */ |
125 | | template <class IDnsResourceDataType> |
126 | | IDnsResourceDataType* castAs() { return get()->castAs<IDnsResourceDataType>();} |
127 | | }; |
128 | | |
129 | | |
130 | | /** |
131 | | * @class StringDnsResourceData |
132 | | * A class that represents DNS RR string data, mainly used in DNS RRs that store hostnames (like CNAME, DNAME, NS, etc.) |
133 | | */ |
134 | | class StringDnsResourceData : public IDnsResourceData |
135 | | { |
136 | | private: |
137 | | std::string m_Data; |
138 | | |
139 | | public: |
140 | | |
141 | | /** |
142 | | * A c'tor for this class |
143 | | * @param[in] data The string data to store in this object. If this string represents a hostname it's possible |
144 | | * to include a pointer to another string in the DNS layer (as explained here: http://www.zytrax.com/books/dns/ch15/#name). |
145 | | * These pointers are often used to reduce the DNS packet size and avoid unnecessary duplications. The way to include pointers |
146 | | * in a hostname string is to use the following format: 'some.domain.#{offset}' where '#{offset}' is the offset from the |
147 | | * start of the DNS layer. For example: if the string 'yahoo.com' already appears in offset 12 in the packet and you want |
148 | | * to set the DNS RR data as 'my.subdomain.yahoo.com' you may use the following string: 'my.subdomain.#12'. |
149 | | * This will result in writing 'my.subdomain' and a pointer to offset 12 |
150 | | */ |
151 | 0 | explicit StringDnsResourceData(const std::string& data) : m_Data(data) {} |
152 | | |
153 | | StringDnsResourceData(const uint8_t* dataPtr, size_t dataLen, IDnsResource* dnsResource); |
154 | | |
155 | 0 | ~StringDnsResourceData() {} |
156 | | |
157 | | /** |
158 | | * Equality operator overload for this class that compares the strings stored in each object |
159 | | * @param[in] other The object to compare with |
160 | | * @return True if the string data is the same in both objects, false otherwise |
161 | | */ |
162 | 0 | bool operator==(const StringDnsResourceData& other) const { return m_Data == other.m_Data; } |
163 | | |
164 | | // implement abstract methods |
165 | | |
166 | 0 | std::string toString() const { return m_Data; } |
167 | | bool toByteArr(uint8_t* arr, size_t& arrLength, IDnsResource* dnsResource) const; |
168 | | }; |
169 | | |
170 | | |
171 | | /** |
172 | | * @class IPv4DnsResourceData |
173 | | * A class that represents DNS RR IPv4 data, mainly used in DNS RRs of type ::DNS_TYPE_A |
174 | | */ |
175 | | class IPv4DnsResourceData : public IDnsResourceData |
176 | | { |
177 | | private: |
178 | | IPv4Address m_Data; |
179 | | |
180 | | public: |
181 | | |
182 | | /** |
183 | | * A c'tor for this class |
184 | | * @param[in] dataPtr A byte array of size 4 that contains an IPv4 address (each byte represents 1 octet) |
185 | | * @param[in] dataLen The byte array size, expected to be 4 |
186 | | */ |
187 | | IPv4DnsResourceData(const uint8_t* dataPtr, size_t dataLen); |
188 | | |
189 | | /** |
190 | | * A c'tor for this class |
191 | | * @param[in] addr The IPv4 address to store in this object |
192 | | */ |
193 | 0 | explicit IPv4DnsResourceData(const IPv4Address& addr) : m_Data(addr) {} |
194 | | |
195 | | /** |
196 | | * A c'tor for this class |
197 | | * @param[in] addrAsString A string representation of an IPv4 address to store in this object |
198 | | */ |
199 | 24.9k | explicit IPv4DnsResourceData(const std::string& addrAsString) : m_Data(addrAsString) {} |
200 | | |
201 | | /** |
202 | | * Equality operator overload for this class that compares the IPv4 addresses stored in each object |
203 | | * @param[in] other The object to compare with |
204 | | * @return True if IPv4 addresses are the same in both objects, false otherwise |
205 | | */ |
206 | 0 | bool operator==(const IPv4DnsResourceData& other) const { return m_Data == other.m_Data; } |
207 | | |
208 | | /** |
209 | | * @return The IPv4 address stored in this object |
210 | | */ |
211 | 0 | IPv4Address getIpAddress() const { return m_Data; } |
212 | | |
213 | | // implement abstract methods |
214 | | |
215 | 0 | std::string toString() const { return m_Data.toString(); } |
216 | | bool toByteArr(uint8_t* arr, size_t& arrLength, IDnsResource* dnsResource) const; |
217 | | }; |
218 | | |
219 | | |
220 | | /** |
221 | | * @class IPv6DnsResourceData |
222 | | * A class that represents DNS RR IPv6 data, mainly used in DNS RRs of type ::DNS_TYPE_AAAA |
223 | | */ |
224 | | class IPv6DnsResourceData : public IDnsResourceData |
225 | | { |
226 | | private: |
227 | | IPv6Address m_Data; |
228 | | |
229 | | public: |
230 | | |
231 | | /** |
232 | | * A c'tor for this class |
233 | | * @param[in] dataPtr A byte array of size 16 that contains an IPv6 address (each byte represents 1 octet) |
234 | | * @param[in] dataLen The byte array size, expected to be 16 |
235 | | */ |
236 | | IPv6DnsResourceData(const uint8_t* dataPtr, size_t dataLen); |
237 | | |
238 | | /** |
239 | | * A c'tor for this class |
240 | | * @param[in] addr The IPv6 address to store in this object |
241 | | */ |
242 | 0 | explicit IPv6DnsResourceData(const IPv6Address& addr) : m_Data(addr) {} |
243 | | |
244 | | /** |
245 | | * A c'tor for this class |
246 | | * @param[in] addrAsString A string representation of an IPv6 address to store in this object |
247 | | */ |
248 | 0 | explicit IPv6DnsResourceData(const std::string& addrAsString) : m_Data(addrAsString) {} |
249 | | |
250 | | /** |
251 | | * Equality operator overload for this class that compares the IPv6 addresses stored in each object |
252 | | * @param[in] other The object to compare with |
253 | | * @return True if IPv6 addresses are the same in both objects, false otherwise |
254 | | */ |
255 | 0 | bool operator==(const IPv6DnsResourceData& other) const { return m_Data == other.m_Data; } |
256 | | |
257 | | /** |
258 | | * @return The IPv6 address stored in this object |
259 | | */ |
260 | 0 | IPv6Address getIpAddress() const { return m_Data; } |
261 | | |
262 | | // implement abstract methods |
263 | | |
264 | 0 | std::string toString() const { return m_Data.toString(); } |
265 | | bool toByteArr(uint8_t* arr, size_t& arrLength, IDnsResource* dnsResource) const; |
266 | | }; |
267 | | |
268 | | |
269 | | /** |
270 | | * @class MxDnsResourceData |
271 | | * A class that represents DNS RR mail exchange (MX) data, used in DNS RRs of type ::DNS_TYPE_MX |
272 | | */ |
273 | | class MxDnsResourceData : public IDnsResourceData |
274 | | { |
275 | | public: |
276 | | |
277 | | /** |
278 | | * A struct that represents mail exchange (MX) data |
279 | | */ |
280 | | struct MxData |
281 | | { |
282 | | /** Preference value */ |
283 | | uint16_t preference; |
284 | | /** Mail exchange hostname */ |
285 | | std::string mailExchange; |
286 | | }; |
287 | | |
288 | | /** |
289 | | * A c'tor for this class |
290 | | * @param[in] dataPtr A byte array that contains the raw MX data (as written in the DNS packet) |
291 | | * @param[in] dataLen The byte array size |
292 | | * @param[in] dnsResource A pointer to a DNS resource object where this DNS RR data will be stored |
293 | | */ |
294 | | MxDnsResourceData(uint8_t* dataPtr, size_t dataLen, IDnsResource* dnsResource); |
295 | | |
296 | | /** |
297 | | * A c'tor for this class |
298 | | * @param[in] preference The MX preference value to store in this object |
299 | | * @param[in] mailExchange The MX hostname value to store in this object. It's possible to include a pointer to |
300 | | * another string in the DNS layer (as explained here: http://www.zytrax.com/books/dns/ch15/#name). These pointers |
301 | | * are often used to reduce the DNS packet size and avoid unnecessary duplications. The way to include pointers |
302 | | * in the hostname string is to use the following format: 'some.domain.#{offset}' where '#{offset}' is the offset |
303 | | * from the start of the DNS layer. For example: if the string 'yahoo.com' already appears in offset 12 in the |
304 | | * packet and you want to set the DNS RR data as 'my.subdomain.yahoo.com' you may use the following string: |
305 | | * 'my.subdomain.#12'. This will result in writing 'my.subdomain' and a pointer to offset 12 |
306 | | */ |
307 | | MxDnsResourceData(const uint16_t& preference, const std::string& mailExchange); |
308 | | |
309 | 0 | ~MxDnsResourceData() {} |
310 | | |
311 | | /** |
312 | | * Equality operator overload for this class that compares the MX data stored in each object |
313 | | * @param[in] other The object to compare with |
314 | | * @return True if MX data is the same in both objects, meaning both preference and MX hostname are the same, |
315 | | * false otherwise |
316 | | */ |
317 | | bool operator==(const MxDnsResourceData& other) const; |
318 | | |
319 | | /** |
320 | | * @return The MX data stored in this object |
321 | | */ |
322 | 0 | MxData getMxData() const { return m_Data; } |
323 | | |
324 | | /** |
325 | | * Set the MX data stored in this object |
326 | | * @param[in] preference The MX preference value to store in this object |
327 | | * @param[in] mailExchange The MX hostname value to store in this object |
328 | | */ |
329 | | void setMxData(uint16_t preference, std::string mailExchange); |
330 | | |
331 | | // implement abstract methods |
332 | | |
333 | | /** |
334 | | * A string representation of the MX data stored in this object. The string format is as follows: |
335 | | * 'pref: {preference_value}; mx: {mail_exchange_hostname_value}' |
336 | | */ |
337 | | std::string toString() const; |
338 | | |
339 | | bool toByteArr(uint8_t* arr, size_t& arrLength, IDnsResource* dnsResource) const; |
340 | | |
341 | | private: |
342 | | MxData m_Data; |
343 | | }; |
344 | | |
345 | | |
346 | | /** |
347 | | * @class GenericDnsResourceData |
348 | | * A class that represents generic DNS RR data which cannot be represented in any of the other classes. It stores the |
349 | | * DNS RR data as byte array |
350 | | */ |
351 | | class GenericDnsResourceData : public IDnsResourceData |
352 | | { |
353 | | private: |
354 | | uint8_t* m_Data; |
355 | | size_t m_DataLen; |
356 | | |
357 | | public: |
358 | | |
359 | | /** |
360 | | * A c'tor for this class |
361 | | * @param[in] dataPtr A byte array that contains the raw data (as it written in the DNS packet). The data will be |
362 | | * copied from this byte array to the object |
363 | | * @param[in] dataLen The byte array size |
364 | | */ |
365 | | GenericDnsResourceData(const uint8_t* dataPtr, size_t dataLen); |
366 | | |
367 | | /** |
368 | | * A c'tor for this class |
369 | | * @param[in] dataAsHexString A hex string that represents the DNS RR data |
370 | | */ |
371 | | explicit GenericDnsResourceData(const std::string& dataAsHexString); |
372 | | |
373 | | /** |
374 | | * A copy c'tor for this class |
375 | | * @param[in] other The instance to copy from |
376 | | */ |
377 | | GenericDnsResourceData(const GenericDnsResourceData& other); |
378 | | |
379 | 24.9k | ~GenericDnsResourceData() { if (m_Data != NULL) delete [] m_Data; } |
380 | | |
381 | | GenericDnsResourceData& operator=(const GenericDnsResourceData& other); |
382 | | |
383 | | /** |
384 | | * Equality operator overload for this class that compares the raw data stored in each object |
385 | | * @param[in] other The object to compare with |
386 | | * @return True if data is the same in both objects, meaning byte streams are equal, false otherwise |
387 | | */ |
388 | | bool operator==(const GenericDnsResourceData& other) const; |
389 | | |
390 | | // implement abstract methods |
391 | | |
392 | | std::string toString() const; |
393 | | bool toByteArr(uint8_t* arr, size_t& arrLength, IDnsResource* dnsResource) const; |
394 | | }; |
395 | | |
396 | | } |