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