/src/PcapPlusPlus/Packet++/header/DnsLayer.h
Line | Count | Source (jump to first uncovered line) |
1 | | #ifndef PACKETPP_DNS_LAYER |
2 | | #define PACKETPP_DNS_LAYER |
3 | | |
4 | | #include "DnsLayerEnums.h" |
5 | | #include "DnsResource.h" |
6 | | #include "DnsResourceData.h" |
7 | | #include "Layer.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 | | /** |
19 | | * @struct dnshdr |
20 | | * Represents the fixed part of the DNS header, meaning the part that doesn't include the DNS data (queries, answers, authorities |
21 | | * and additional records) |
22 | | */ |
23 | | #pragma pack(push, 1) |
24 | | struct dnshdr |
25 | | { |
26 | | /** DNS query identification */ |
27 | | uint16_t transactionID; |
28 | | #if (BYTE_ORDER == LITTLE_ENDIAN) |
29 | | uint16_t |
30 | | /** Recursion desired flag */ |
31 | | recursionDesired:1, |
32 | | /** Truncated flag */ |
33 | | truncation:1, |
34 | | /** Authoritative answer flag */ |
35 | | authoritativeAnswer:1, |
36 | | /** Operation Code */ |
37 | | opcode:4, |
38 | | /** Query/Response flag */ |
39 | | queryOrResponse:1, |
40 | | /** Return Code */ |
41 | | responseCode:4, |
42 | | /** Checking disabled flag */ |
43 | | checkingDisabled:1, |
44 | | /** Authenticated data flag */ |
45 | | authenticData:1, |
46 | | /** Zero flag (Reserved) */ |
47 | | zero:1, |
48 | | /** Recursion available flag */ |
49 | | recursionAvailable:1; |
50 | | #elif (BYTE_ORDER == BIG_ENDIAN) |
51 | | uint16_t |
52 | | /** Query/Response flag */ |
53 | | queryOrResponse:1, |
54 | | /** Operation Code */ |
55 | | opcode:4, |
56 | | /** Authoritative answer flag */ |
57 | | authoritativeAnswer:1, |
58 | | /** Truncated flag */ |
59 | | truncation:1, |
60 | | /** Recursion desired flag */ |
61 | | recursionDesired:1, |
62 | | /** Recursion available flag */ |
63 | | recursionAvailable:1, |
64 | | /** Zero flag (Reserved) */ |
65 | | zero:1, |
66 | | /** Authenticated data flag */ |
67 | | authenticData:1, |
68 | | /** Checking disabled flag */ |
69 | | checkingDisabled:1, |
70 | | /** Return Code */ |
71 | | responseCode:4; |
72 | | #endif |
73 | | /** Number of DNS query records in packet */ |
74 | | uint16_t numberOfQuestions; |
75 | | /** Number of DNS answer records in packet */ |
76 | | uint16_t numberOfAnswers; |
77 | | /** Number of authority records in packet */ |
78 | | uint16_t numberOfAuthority; |
79 | | /** Number of additional records in packet */ |
80 | | uint16_t numberOfAdditional; |
81 | | }; |
82 | | #pragma pack(pop) |
83 | | |
84 | | |
85 | | // forward declarations |
86 | | class DnsQuery; |
87 | | class IDnsResource; |
88 | | class DnsResource; |
89 | | class IDnsResourceData; |
90 | | |
91 | | |
92 | | /** |
93 | | * @class DnsLayer |
94 | | * Represents the DNS protocol layer |
95 | | */ |
96 | | class DnsLayer : public Layer |
97 | | { |
98 | | friend class IDnsResource; |
99 | | friend class DnsQuery; |
100 | | friend class DnsResource; |
101 | | |
102 | | public: |
103 | | |
104 | | /** |
105 | | * A constructor that creates the layer from an existing packet raw data |
106 | | * @param[in] data A pointer to the raw data |
107 | | * @param[in] dataLen Size of the data in bytes |
108 | | * @param[in] prevLayer A pointer to the previous layer |
109 | | * @param[in] packet A pointer to the Packet instance where layer will be stored in |
110 | | */ |
111 | | DnsLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet); |
112 | | |
113 | | /** |
114 | | * A constructor that creates an empty DNS layer: all members of dnshdr are set to 0 and layer will contain no records |
115 | | */ |
116 | | DnsLayer(); |
117 | | |
118 | | /** |
119 | | * A copy constructor for this layer |
120 | | * @param[in] other The DNS layer to copy from |
121 | | */ |
122 | | DnsLayer(const DnsLayer& other); |
123 | | |
124 | | /** |
125 | | * An assignment operator for this layer |
126 | | * @param[in] other The DNS layer to assign |
127 | | * @return A reference to the assignee |
128 | | */ |
129 | | DnsLayer& operator=(const DnsLayer& other); |
130 | | |
131 | | virtual ~DnsLayer(); |
132 | | |
133 | | /** |
134 | | * Get a pointer to the DNS header (as opposed to the DNS data which is the queries, answers, etc. Data can be retrieved through the |
135 | | * other methods of this layer. Notice the return value points directly to the data, so every change will change the actual packet data |
136 | | * @return A pointer to the @ref dnshdr |
137 | | */ |
138 | | dnshdr* getDnsHeader() const; |
139 | | |
140 | | /** |
141 | | * Searches for a DNS query by its name field. Notice this method returns only a query which its name equals to the requested name. If |
142 | | * several queries match the requested name, the first one will be returned. If no queries match the requested name, NULL will be returned |
143 | | * @param[in] name The name of the query to search |
144 | | * @param[in] exactMatch Indicate whether to match the whole name or just a part of it |
145 | | * @return The first matching DNS query or NULL if no queries were found |
146 | | */ |
147 | | DnsQuery* getQuery(const std::string& name, bool exactMatch) const; |
148 | | |
149 | | /** |
150 | | * @return The first DNS query in the packet or NULL if packet doesn't contain any queries |
151 | | */ |
152 | | DnsQuery* getFirstQuery() const; |
153 | | |
154 | | /** |
155 | | * Get the DNS query following a certain query |
156 | | * @param[in] query A pointer to a DNS query that exist in the packet |
157 | | * @return The DNS query following 'query'. If 'query' is NULL or 'query' is the last query in the packet NULL will be returned |
158 | | */ |
159 | | DnsQuery* getNextQuery(DnsQuery* query) const; |
160 | | |
161 | | /** |
162 | | * @return The number of DNS queries in the packet |
163 | | */ |
164 | | size_t getQueryCount() const; |
165 | | |
166 | | /** |
167 | | * Add a new DNS query to the layer |
168 | | * @param[in] name The value that shall be set in the name field of the query |
169 | | * @param[in] dnsType The value that shall be set in the DNS type field of the query |
170 | | * @param[in] dnsClass The value that shall be set in the DNS class field of the query |
171 | | * @return A pointer to the newly created DNS query or NULL if query could not be created (an appropriate error log message will be |
172 | | * printed in this case) |
173 | | */ |
174 | | DnsQuery* addQuery(const std::string& name, DnsType dnsType, DnsClass dnsClass); |
175 | | |
176 | | /** |
177 | | * Add a new DNS query similar to an already existing DNS query. All query fields will be copied from the existing query |
178 | | * @param[in] copyQuery The record to create the new record from. copyQuery won't be changed in any way |
179 | | * @return A pointer to the newly created DNS query or NULL if query could not be created (an appropriate error log message will be |
180 | | * printed in this case) |
181 | | */ |
182 | | DnsQuery* addQuery(DnsQuery* const copyQuery); |
183 | | |
184 | | /** |
185 | | * Remove an existing query by name. If several queries matches the name, the first match will be removed |
186 | | * @param[in] queryNameToRemove The name of the query to remove |
187 | | * @param[in] exactMatch Indicate whether to match the whole name or just a part of it |
188 | | * @return True if query was found and successfully removed or false if query was not found or couldn't be removed |
189 | | */ |
190 | | bool removeQuery(const std::string& queryNameToRemove, bool exactMatch); |
191 | | |
192 | | /** |
193 | | * Remove an existing query |
194 | | * @param[in] queryToRemove A pointer to the query to remove |
195 | | * @return True if query was found and successfully removed or false if query was not found or couldn't be removed |
196 | | */ |
197 | | bool removeQuery(DnsQuery* queryToRemove); |
198 | | |
199 | | /** |
200 | | * Searches for a DNS answer by its name field. Notice this method returns only an answer which its name equals to the requested name. If |
201 | | * several answers match the requested name, the first one will be returned. If no answers match the requested name, NULL will be returned |
202 | | * @param[in] name The name of the answer to search |
203 | | * @param[in] exactMatch Indicate whether to match the whole name or just a part of it |
204 | | * @return The first matching DNS answer or NULL if no answers were found |
205 | | */ |
206 | | DnsResource* getAnswer(const std::string& name, bool exactMatch) const; |
207 | | |
208 | | /** |
209 | | * @return The first DNS answer in the packet or NULL if packet doesn't contain any answers |
210 | | */ |
211 | | DnsResource* getFirstAnswer() const; |
212 | | |
213 | | /** |
214 | | * Get the DNS answer following a certain answer |
215 | | * @param[in] answer A pointer to a DNS answer that exist in the packet |
216 | | * @return The DNS answer following 'answer'. If 'answer' is NULL or 'answer' is the last answer in the packet NULL will be returned |
217 | | */ |
218 | | DnsResource* getNextAnswer(DnsResource* answer) const; |
219 | | |
220 | | /** |
221 | | * @return The number of DNS answers in the packet |
222 | | */ |
223 | | size_t getAnswerCount() const; |
224 | | |
225 | | /** |
226 | | * Add a new DNS answer to the layer |
227 | | * @param[in] name The value that shall be set in the name field of the answer |
228 | | * @param[in] dnsType The value that shall be set in the DNS type field of the answer |
229 | | * @param[in] dnsClass The value that shall be set in the DNS class field of the answer |
230 | | * @param[in] ttl The value that shall be set in the 'time-to-leave' field of the answer |
231 | | * @param[in] data The answer data to be set. The type of the data should match the type of the DNS record |
232 | | * (for example: DNS record of type A should have data of type IPv4DnsResourceData. Please see DnsResource#setData() |
233 | | * for more info on this |
234 | | * @return A pointer to the newly created DNS answer or NULL if answer could not be created (an appropriate error log message will be |
235 | | * printed in this case) |
236 | | */ |
237 | | DnsResource* addAnswer(const std::string& name, DnsType dnsType, DnsClass dnsClass, uint32_t ttl, IDnsResourceData* data); |
238 | | |
239 | | /** |
240 | | * Add a new DNS answer similar to an already existing DNS answer. All answer fields will be copied from the existing answer |
241 | | * @param[in] copyAnswer The record to create the new record from. copyAnswer won't be changed in any way |
242 | | * @return A pointer to the newly created DNS answer or NULL if query could not be created (an appropriate error log message will be |
243 | | * printed in this case) |
244 | | */ |
245 | | DnsResource* addAnswer(DnsResource* const copyAnswer); |
246 | | |
247 | | /** |
248 | | * Remove an existing answer by name. If several answers matches the name, the first match will be removed |
249 | | * @param[in] answerNameToRemove The name of the answer to remove |
250 | | * @param[in] exactMatch Indicate whether to match the whole name or just a part of it |
251 | | * @return True if answer was found and successfully removed or false if answer was not found or couldn't be removed |
252 | | */ |
253 | | bool removeAnswer(const std::string& answerNameToRemove, bool exactMatch); |
254 | | |
255 | | /** |
256 | | * Remove an existing answer |
257 | | * @param[in] answerToRemove A pointer to the answer to remove |
258 | | * @return True if answer was found and successfully removed or false if answer was not found or couldn't be removed |
259 | | */ |
260 | | bool removeAnswer(DnsResource* answerToRemove); |
261 | | |
262 | | |
263 | | /** |
264 | | * Searches for a DNS authority by its name field. Notice this method returns only an authority which its name equals to the requested name. If |
265 | | * several authorities match the requested name, the first one will be returned. If no authorities match the requested name, NULL will be returned |
266 | | * @param[in] name The name of the authority to search |
267 | | * @param[in] exactMatch Indicate whether to match the whole name or just a part of it |
268 | | * @return The first matching DNS authority or NULL if no authorities were found |
269 | | */ |
270 | | DnsResource* getAuthority(const std::string& name, bool exactMatch) const; |
271 | | |
272 | | /** |
273 | | * @return The first DNS authority in the packet or NULL if packet doesn't contain any authorities |
274 | | */ |
275 | | DnsResource* getFirstAuthority() const; |
276 | | |
277 | | /** |
278 | | * Get the DNS authority following a certain authority |
279 | | * @param[in] authority A pointer to a DNS authority that exist in the packet |
280 | | * @return The DNS authority following 'authority'. If 'authority' is NULL or 'authority' is the last authority in the packet NULL will be returned |
281 | | */ |
282 | | DnsResource* getNextAuthority(DnsResource* authority) const; |
283 | | |
284 | | /** |
285 | | * @return The number of DNS authorities in the packet |
286 | | */ |
287 | | size_t getAuthorityCount() const; |
288 | | |
289 | | /** |
290 | | * Add a new DNS authority to the layer |
291 | | * @param[in] name The value that shall be set in the name field of the authority |
292 | | * @param[in] dnsType The value that shall be set in the DNS type field of the authority |
293 | | * @param[in] dnsClass The value that shall be set in the DNS class field of the authority |
294 | | * @param[in] ttl The value that shall be set in the 'time-to-leave' field of the authority |
295 | | * @param[in] data The authority data to be set. The type of the data should match the type of the DNS record |
296 | | * (for example: DNS record of type A should have data of type IPv4DnsResourceData. Please see DnsResource#setData() |
297 | | * for more info on this |
298 | | * @return A pointer to the newly created DNS authority or NULL if authority could not be created (an appropriate error log message will be |
299 | | * printed in this case) |
300 | | */ |
301 | | DnsResource* addAuthority(const std::string& name, DnsType dnsType, DnsClass dnsClass, uint32_t ttl, IDnsResourceData* data); |
302 | | |
303 | | /** |
304 | | * Add a new DNS authority similar to an already existing DNS authority. All authority fields will be copied from the existing authority |
305 | | * @param[in] copyAuthority The record to create the new record from. copyAuthority won't be changed in any way |
306 | | * @return A pointer to the newly created DNS authority or NULL if query could not be created (an appropriate error log message will be |
307 | | * printed in this case) |
308 | | */ |
309 | | DnsResource* addAuthority(DnsResource* const copyAuthority); |
310 | | |
311 | | /** |
312 | | * Remove an existing authority by name. If several authorities matches the name, the first match will be removed |
313 | | * @param[in] authorityNameToRemove The name of the authority to remove |
314 | | * @param[in] exactMatch Indicate whether to match the whole name or just a part of it |
315 | | * @return True if authority was found and successfully removed or false if authority was not found or couldn't be removed |
316 | | */ |
317 | | bool removeAuthority(const std::string& authorityNameToRemove, bool exactMatch); |
318 | | |
319 | | /** |
320 | | * Remove an existing authority |
321 | | * @param[in] authorityToRemove A pointer to the authority to remove |
322 | | * @return True if authority was found and successfully removed or false if authority was not found or couldn't be removed |
323 | | */ |
324 | | bool removeAuthority(DnsResource* authorityToRemove); |
325 | | |
326 | | |
327 | | /** |
328 | | * Searches for a DNS additional record by its name field. Notice this method returns only an additional record which its name equals to |
329 | | * the requested name. If several additional records match the requested name, the first one will be returned. If no additional records |
330 | | * match the requested name, NULL will be returned |
331 | | * @param[in] name The name of the additional record to search |
332 | | * @param[in] exactMatch Indicate whether to match the whole name or just a part of it |
333 | | * @return The first matching DNS additional record or NULL if no additional records were found |
334 | | */ |
335 | | DnsResource* getAdditionalRecord(const std::string& name, bool exactMatch) const; |
336 | | |
337 | | /** |
338 | | * @return The first DNS additional record in the packet or NULL if packet doesn't contain any additional records |
339 | | */ |
340 | | DnsResource* getFirstAdditionalRecord() const; |
341 | | |
342 | | /** |
343 | | * Get the DNS additional record following a certain additional record |
344 | | * @param[in] additionalRecord A pointer to a DNS additional record that exist in the packet |
345 | | * @return The DNS additional record following 'additionalRecord'. If 'additionalRecord' is NULL or 'additionalRecord' is the |
346 | | * last additional record in the packet NULL will be returned |
347 | | */ |
348 | | DnsResource* getNextAdditionalRecord(DnsResource* additionalRecord) const; |
349 | | |
350 | | /** |
351 | | * @return The number of DNS additional records in the packet |
352 | | */ |
353 | | size_t getAdditionalRecordCount() const; |
354 | | |
355 | | /** |
356 | | * Add a new DNS additional record to the layer |
357 | | * @param[in] name The value that shall be set in the name field of the additional record |
358 | | * @param[in] dnsType The value that shall be set in the DNS type field of the additional record |
359 | | * @param[in] dnsClass The value that shall be set in the DNS class field of the additional record |
360 | | * @param[in] ttl The value that shall be set in the 'time-to-leave' field of the additional record |
361 | | * @param[in] data The additional record data to be set. The type of the data should match the type of the DNS record |
362 | | * (for example: DNS record of type A should have data of type IPv4DnsResourceData. Please see DnsResource#setData() |
363 | | * for more info on this |
364 | | * @return A pointer to the newly created DNS additional record or NULL if additional record could not be created (an appropriate error |
365 | | * log message will be printed in this case) |
366 | | */ |
367 | | DnsResource* addAdditionalRecord(const std::string& name, DnsType dnsType, DnsClass dnsClass, uint32_t ttl, IDnsResourceData* data); |
368 | | |
369 | | /** |
370 | | * Add a new DNS additional record to the layer that doesn't have DNS class and TTL. Instead these bytes may contains some arbitrary |
371 | | * data. In the future I may add support for these kinds of additional data records. For now, these bytes are set as raw |
372 | | * @param[in] name The value that shall be set in the name field of the additional record |
373 | | * @param[in] dnsType The value that shall be set in the DNS type field of the additional record |
374 | | * @param[in] customData1 Two bytes of the arbitrary data that will be set in the offset usually used for the DNS class |
375 | | * @param[in] customData2 Four bytes of the arbitrary data that will be set in the offset usually used for the TTL |
376 | | * @param[in] data The additional record data to be set. The type of the data should match the type of the DNS record. |
377 | | * (for example: DNS record of type A should have data of type IPv4DnsResourceData. Please see DnsResource#setData() |
378 | | * for more info on this |
379 | | * @return A pointer to the newly created DNS additional record or NULL if additional record could not be created (an appropriate error |
380 | | * log message will be printed in this case) |
381 | | */ |
382 | | DnsResource* addAdditionalRecord(const std::string& name, DnsType dnsType, uint16_t customData1, uint32_t customData2, IDnsResourceData* data); |
383 | | |
384 | | /** |
385 | | * Add a new DNS additional record similar to an already existing DNS additional record. All additional record fields will be copied from the |
386 | | * existing additional record |
387 | | * @param[in] copyAdditionalRecord The record to create the new record from. copyAdditionalRecord won't be changed in any way |
388 | | * @return A pointer to the newly created DNS additional record or NULL if query could not be created (an appropriate error log message will |
389 | | * be printed in this case) |
390 | | */ |
391 | | DnsResource* addAdditionalRecord(DnsResource* const copyAdditionalRecord); |
392 | | |
393 | | /** |
394 | | * Remove an existing additional record by name. If several additional records matches the name, the first match will be removed |
395 | | * @param[in] additionalRecordNameToRemove The name of the additional record to remove |
396 | | * @param[in] exactMatch Indicate whether to match the whole name or just a part of it |
397 | | * @return True if additional record was found and successfully removed or false if additional record was not found or couldn't be removed |
398 | | */ |
399 | | bool removeAdditionalRecord(const std::string& additionalRecordNameToRemove, bool exactMatch); |
400 | | |
401 | | /** |
402 | | * Remove an existing additional record |
403 | | * @param[in] additionalRecordToRemove A pointer to the additional record to remove |
404 | | * @return True if additional record was found and successfully removed or false if additional record was not found or couldn't be removed |
405 | | */ |
406 | | bool removeAdditionalRecord(DnsResource* additionalRecordToRemove); |
407 | | |
408 | | // implement abstract methods |
409 | | |
410 | | /** |
411 | | * Does nothing for this layer (DnsLayer is always last) |
412 | | */ |
413 | 7.33k | void parseNextLayer() {} |
414 | | |
415 | | /** |
416 | | * @return The size of the DNS data in the packet including he DNS header and size of all queries, answers, authorities and additional |
417 | | * records |
418 | | */ |
419 | 0 | size_t getHeaderLen() const { return m_DataLen; } //No layer above DNS |
420 | | |
421 | | /** |
422 | | * Does nothing for this layer |
423 | | * @return No return value |
424 | | */ |
425 | 0 | virtual void computeCalculateFields() {} |
426 | | |
427 | | std::string toString() const; |
428 | | |
429 | 7.33k | OsiModelLayer getOsiModelLayer() const { return OsiModelApplicationLayer; } |
430 | | |
431 | | /** |
432 | | * A static method that checks whether the port is considered as DNS |
433 | | * @param[in] port The port number to be checked |
434 | | * @return True if the port is associated with the DNS protocol |
435 | | */ |
436 | | static inline bool isDnsPort(uint16_t port); |
437 | | |
438 | | /** |
439 | | * A static method that validates the input data |
440 | | * @param[in] data The pointer to the beginning of a byte stream of a DNS packet |
441 | | * @param[in] dataLen The length of the byte stream |
442 | | * @param[in] dnsOverTcp Should be set to "true" if this is DNS is over TCP, otherwise set to "false" |
443 | | * (which is also the default value) |
444 | | * @return True if the data is valid and can represent a DNS packet |
445 | | */ |
446 | | static inline bool isDataValid(const uint8_t* data, size_t dataLen, bool dnsOverTcp = false); |
447 | | |
448 | | protected: |
449 | | DnsLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet, size_t offsetAdjustment); |
450 | | explicit DnsLayer(size_t offsetAdjustment); |
451 | | |
452 | | private: |
453 | | IDnsResource* m_ResourceList; |
454 | | DnsQuery* m_FirstQuery; |
455 | | DnsResource* m_FirstAnswer; |
456 | | DnsResource* m_FirstAuthority; |
457 | | DnsResource* m_FirstAdditional; |
458 | | uint16_t m_OffsetAdjustment; |
459 | | |
460 | | size_t getBasicHeaderSize(); |
461 | | void init(size_t offsetAdjustment, bool callParseResource); |
462 | | void initNewLayer(size_t offsetAdjustment); |
463 | | |
464 | | IDnsResource* getFirstResource(DnsResourceType resType) const; |
465 | | void setFirstResource(DnsResourceType resType, IDnsResource* resource); |
466 | | |
467 | | using Layer::extendLayer; |
468 | | bool extendLayer(int offsetInLayer, size_t numOfBytesToExtend, IDnsResource* resource); |
469 | | |
470 | | using Layer::shortenLayer; |
471 | | bool shortenLayer(int offsetInLayer, size_t numOfBytesToShorten, IDnsResource* resource); |
472 | | |
473 | | IDnsResource* getResourceByName(IDnsResource* startFrom, size_t resourceCount, const std::string& name, bool exactMatch) const; |
474 | | |
475 | | void parseResources(); |
476 | | |
477 | | DnsResource* addResource(DnsResourceType resType, const std::string& name, DnsType dnsType, DnsClass dnsClass, |
478 | | uint32_t ttl, IDnsResourceData* data); |
479 | | |
480 | | bool removeResource(IDnsResource* resourceToRemove); |
481 | | |
482 | | }; |
483 | | |
484 | | |
485 | | |
486 | | /** |
487 | | * @class DnsOverTcpLayer |
488 | | * Represents the DNS over TCP layer. |
489 | | * DNS over TCP is described here: https://tools.ietf.org/html/rfc7766 . |
490 | | * It is very similar to DNS over UDP, except for one field: TCP message length which is added in the beginning of the message |
491 | | * before the other DNS data properties. The rest of the data is similar. |
492 | | * |
493 | | * Note: DNS over TCP can spread over more than one packet, but this implementation doesn't support this use-case and assumes |
494 | | * the whole message fits in a single packet. |
495 | | */ |
496 | | class DnsOverTcpLayer : public DnsLayer |
497 | | { |
498 | | public: |
499 | | |
500 | | /** |
501 | | * A constructor that creates the layer from an existing packet raw data |
502 | | * @param[in] data A pointer to the raw data |
503 | | * @param[in] dataLen Size of the data in bytes |
504 | | * @param[in] prevLayer A pointer to the previous layer |
505 | | * @param[in] packet A pointer to the Packet instance where layer will be stored in |
506 | | */ |
507 | | DnsOverTcpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet) |
508 | 3.02k | : DnsLayer(data, dataLen, prevLayer, packet, sizeof(uint16_t)) {} |
509 | | |
510 | | /** |
511 | | * A constructor that creates an empty DNS layer: all members of dnshdr are set to 0 and layer will contain no records |
512 | | */ |
513 | 0 | DnsOverTcpLayer() : DnsLayer(sizeof(uint16_t)) {} |
514 | | |
515 | | /** |
516 | | * A copy constructor for this layer |
517 | | * @param[in] other The DNS over TCP layer to copy from |
518 | | */ |
519 | 0 | DnsOverTcpLayer(const DnsOverTcpLayer& other) : DnsLayer(other) {} |
520 | | |
521 | | /** |
522 | | * @return The value of the TCP message length as described in https://tools.ietf.org/html/rfc7766#section-8 |
523 | | */ |
524 | | uint16_t getTcpMessageLength(); |
525 | | |
526 | | /** |
527 | | * Set the TCP message length value as described in https://tools.ietf.org/html/rfc7766#section-8 |
528 | | * @param[in] value The value to set |
529 | | */ |
530 | | void setTcpMessageLength(uint16_t value); |
531 | | |
532 | | |
533 | | // overridden methods |
534 | | |
535 | | /** |
536 | | * Calculate the TCP message length field |
537 | | */ |
538 | | void computeCalculateFields(); |
539 | | }; |
540 | | |
541 | | |
542 | | // implementation of inline methods |
543 | | |
544 | | bool DnsLayer::isDnsPort(uint16_t port) |
545 | 241k | { |
546 | 241k | switch (port) |
547 | 241k | { |
548 | 3.09k | case 53: |
549 | 4.73k | case 5353: |
550 | 7.33k | case 5355: |
551 | 7.33k | return true; |
552 | 233k | default: |
553 | 233k | return false; |
554 | 241k | } |
555 | 241k | } |
556 | | |
557 | | bool DnsLayer::isDataValid(const uint8_t* data, size_t dataLen, bool dnsOverTcp) |
558 | 234k | { |
559 | 234k | size_t minSize = sizeof(dnshdr) + (dnsOverTcp ? sizeof(uint16_t) : 0); |
560 | 234k | return dataLen >= minSize; |
561 | 234k | } |
562 | | |
563 | | } // namespace pcpp |
564 | | |
565 | | #endif /* PACKETPP_DNS_LAYER */ |