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