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