Coverage Report

Created: 2026-11-12 06:50

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