2 * Copyright (c) 2017, The OpenThread Authors.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. Neither the name of the copyright holder nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
31 * This file includes definitions for generating and processing DNS headers.
34 #ifndef DNS_HEADER_HPP_
35 #define DNS_HEADER_HPP_
37 #include "openthread-core-config.h"
39 #include "common/encoding.hpp"
40 #include "common/message.hpp"
47 * This namespace includes definitions for DNS.
52 using ot::Encoding::BigEndian::HostSwap16;
53 using ot::Encoding::BigEndian::HostSwap32;
56 * @addtogroup core-dns
59 * This module includes definitions for DNS.
66 * This class implements DNS header generation and parsing.
74 * Default constructor for DNS Header.
77 Header(void) { memset(this, 0, sizeof(*this)); }
80 * This method returns the Message ID.
82 * @returns The Message ID value.
85 uint16_t GetMessageId(void) const { return HostSwap16(mMessageId); }
88 * This method sets the Message ID.
90 * @param[in] aMessageId The Message ID value.
93 void SetMessageId(uint16_t aMessageId) { mMessageId = HostSwap16(aMessageId); }
96 * Defines types of DNS message.
106 * This method returns the type of the message.
108 * @returns The type of the message.
110 Type GetType(void) const { return static_cast<Type>((mFlags[0] & kQrFlagMask) >> kQrFlagOffset); }
113 * This method sets the type of the message.
115 * @param[in] aType The type of the message.
118 void SetType(Type aType)
120 mFlags[0] &= ~kQrFlagMask;
121 mFlags[0] |= static_cast<uint8_t>(aType) << kQrFlagOffset;
125 * Defines types of query.
130 kQueryTypeStandard = 0,
131 kQueryTypeInverse = 1,
132 kQueryTypeStatus = 2,
133 kQueryTypeNotify = 4,
138 * This method returns the type of the query.
140 * @returns The type of the query.
142 QueryType GetQueryType(void) const { return static_cast<QueryType>((mFlags[0] & kOpCodeMask) >> kOpCodeOffset); }
145 * This method sets the type of the query.
147 * @param[in] aType The type of the query.
150 void SetQueryType(QueryType aType)
152 mFlags[0] &= ~kOpCodeMask;
153 mFlags[0] |= static_cast<uint8_t>(aType) << kOpCodeOffset;
157 * This method specifies in response message if the responding name server is an
158 * authority for the domain name in question section.
160 * @returns True if Authoritative Answer flag (AA) is set in the header, false otherwise.
162 bool IsAuthoritativeAnswerFlagSet(void) const { return (mFlags[0] & kAaFlagMask) == kAaFlagMask; }
165 * This method clears the Authoritative Answer flag (AA) in the header.
168 void ClearAuthoritativeAnswerFlag(void) { mFlags[0] &= ~kAaFlagMask; }
171 * This method sets the Authoritative Answer flag (AA) in the header.
174 void SetAuthoritativeAnswerFlag(void) { mFlags[0] |= kAaFlagMask; }
177 * This method specifies if message is truncated.
179 * @returns True if Truncation flag (TC) is set in the header, false otherwise.
181 bool IsTruncationFlagSet(void) const { return (mFlags[0] & kTcFlagMask) == kTcFlagMask; }
184 * This method clears the Truncation flag (TC) in the header.
187 void ClearTruncationFlag(void) { mFlags[0] &= ~kTcFlagMask; }
190 * This method sets the Truncation flag (TC) in the header.
193 void SetTruncationFlag(void) { mFlags[0] |= kTcFlagMask; }
196 * This method specifies if resolver wants to direct the name server to pursue
197 * the query recursively.
199 * @returns True if Recursion Desired flag (RD) is set in the header, false otherwise.
201 bool IsRecursionDesiredFlagSet(void) const { return (mFlags[0] & kRdFlagMask) == kRdFlagMask; }
204 * This method clears the Recursion Desired flag (RD) in the header.
207 void ClearRecursionDesiredFlag(void) { mFlags[0] &= ~kRdFlagMask; }
210 * This method sets the Recursion Desired flag (RD) in the header.
213 void SetRecursionDesiredFlag(void) { mFlags[0] |= kRdFlagMask; }
216 * This method denotes whether recursive query support is available in the name server.
218 * @returns True if Recursion Available flag (RA) is set in the header, false otherwise.
220 bool IsRecursionAvailableFlagSet(void) const { return (mFlags[1] & kRaFlagMask) == kRaFlagMask; }
223 * This method clears the Recursion Available flag (RA) in the header.
226 void ClearRecursionAvailableFlag(void) { mFlags[1] &= ~kRaFlagMask; }
229 * This method sets the Recursion Available flag (RA) in the header.
232 void SetRecursionAvailableFlag(void) { mFlags[1] |= kRaFlagMask; }
235 * Defines response codes.
240 kResponseSuccess = 0,
241 kResponseFormatError = 1,
242 kResponseServerFailure = 2,
243 kResponseNameError = 3,
244 kResponseNotImplemented = 4,
245 kResponseRefused = 5,
246 kResponseNotAuth = 9,
247 kResponseNotZone = 10,
248 kResponseBadName = 20,
249 kResponseBadAlg = 21,
250 kResponseBadTruncation = 22,
254 * This method returns the response code.
256 * @returns The response code from the header.
258 Response GetResponseCode(void) const { return static_cast<Response>((mFlags[1] & kRCodeMask) >> kRCodeOffset); }
261 * This method sets the response code.
263 * @param[in] aResponse The type of the response.
266 void SetResponseCode(Response aResponse)
268 mFlags[1] &= ~kRCodeMask;
269 mFlags[1] |= static_cast<uint8_t>(aResponse) << kRCodeOffset;
273 * This method returns the number of entries in question section.
275 * @returns The number of entries in question section.
278 uint16_t GetQuestionCount(void) const { return HostSwap16(mQdCount); }
281 * This method sets the number of entries in question section.
283 * @param[in] aCount The number of entries in question section.
286 void SetQuestionCount(uint16_t aCount) { mQdCount = HostSwap16(aCount); }
289 * This method returns the number of entries in answer section.
291 * @returns The number of entries in answer section.
294 uint16_t GetAnswerCount(void) const { return HostSwap16(mAnCount); }
297 * This method sets the number of entries in answer section.
299 * @param[in] aCount The number of entries in answer section.
302 void SetAnswerCount(uint16_t aCount) { mAnCount = HostSwap16(aCount); }
305 * This method returns the number of entries in authority records section.
307 * @returns The number of entries in authority records section.
310 uint16_t GetAuthorityRecordsCount(void) const { return HostSwap16(mNsCount); }
313 * This method sets the number of entries in authority records section.
315 * @param[in] aCount The number of entries in authority records section.
318 void SetAuthorityRecordsCount(uint16_t aCount) { mNsCount = HostSwap16(aCount); }
321 * This method returns the number of entries in additional records section.
323 * @returns The number of entries in additional records section.
326 uint16_t GetAdditionalRecordsCount(void) const { return HostSwap16(mArCount); }
329 * This method sets the number of entries in additional records section.
331 * @param[in] aCount The number of entries in additional records section.
334 void SetAdditionalRecordsCount(uint16_t aCount) { mArCount = HostSwap16(aCount); }
338 * Protocol Constants (RFC 1035).
343 kQrFlagOffset = 7, ///< QR Flag offset.
344 kQrFlagMask = 0x01 << kQrFlagOffset, ///< QR Flag mask.
345 kOpCodeOffset = 3, ///< OpCode field offset.
346 kOpCodeMask = 0x0f << kOpCodeOffset, ///< OpCode field mask.
347 kAaFlagOffset = 2, ///< AA Flag offset.
348 kAaFlagMask = 0x01 << kAaFlagOffset, ///< AA Flag mask.
349 kTcFlagOffset = 1, ///< TC Flag offset.
350 kTcFlagMask = 0x01 << kTcFlagOffset, ///< TC Flag mask.
351 kRdFlagOffset = 0, ///< RD Flag offset.
352 kRdFlagMask = 0x01 << kRdFlagOffset, ///< RD Flag mask.
354 kRaFlagOffset = 7, ///< RA Flag offset.
355 kRaFlagMask = 0x01 << kRaFlagOffset, ///< RA Flag mask.
356 kRCodeOffset = 0, ///< RCODE field offset.
357 kRCodeMask = 0x0f << kRCodeOffset, ///< RCODE field mask.
361 mMessageId; ///< A message identifier that is used by the requester to match up replies to outstanding queries.
362 uint8_t mFlags[2]; ///< DNS header flags.
363 uint16_t mQdCount; ///< A number specifying the number of entries in the question section.
364 uint16_t mAnCount; ///< A number specifying the number of entries in the answer section.
365 uint16_t mNsCount; ///< A number specifying the number of entries in the authority records section.
366 uint16_t mArCount; ///< A number specifying the number of entries in the additional records section.
368 } OT_TOOL_PACKED_END;
371 * This class implements Resource Record body format (RR).
379 * This method returns the type of the resource record.
381 * @returns The type of the resource record.
383 uint16_t GetType(void) const { return HostSwap16(mType); }
386 * This method sets the type of the resource record.
388 * @param[in] aType The type of the resource record.
391 void SetType(uint16_t aType) { mType = HostSwap16(aType); }
394 * This method returns the class of the resource record.
396 * @returns The class of the resource record.
398 uint16_t GetClass(void) const { return HostSwap16(mClass); }
401 * This method sets the class of the resource record.
403 * @param[in] aClass The class of the resource record.
406 void SetClass(uint16_t aClass) { mClass = HostSwap16(aClass); }
409 * This method returns the time to live field of the resource record.
411 * @returns The time to live field of the resource record.
413 uint32_t GetTtl(void) const { return HostSwap32(mTtl); }
416 * This method sets the time to live field of the resource record.
418 * @param[in] aTtl The time to live field of the resource record.
421 void SetTtl(uint32_t aTtl) { mTtl = HostSwap32(aTtl); }
424 * This method returns the length of the resource record.
426 * @returns The length of the resource record.
428 uint16_t GetLength(void) const { return HostSwap16(mLength); }
431 * This method sets the length of the resource record.
433 * @param[in] aLength The length of the resource record.
436 void SetLength(uint16_t aLength) { mLength = HostSwap16(aLength); }
439 uint16_t mType; ///< The type of the data in RDATA section.
440 uint16_t mClass; ///< The class of the data in RDATA section.
441 uint32_t mTtl; ///< Specifies the maximum time that the resource record may be cached.
442 uint16_t mLength; ///< The length of RDATA section in bytes.
444 } OT_TOOL_PACKED_END;
447 * This class implements Resource Record body format of AAAA type.
451 class ResourceRecordAaaa : public ResourceRecord
456 kType = 0x1C, ///< AAAA Resource Record type.
457 kClass = 0x01, ///< The value of the Internet class.
458 kLength = 16, ///< Size of the AAAA Resource Record type.
462 * This method initializes the AAAA Resource Record.
467 ResourceRecord::SetType(kType);
468 ResourceRecord::SetClass(kClass);
469 ResourceRecord::SetTtl(0);
470 ResourceRecord::SetLength(kLength);
471 memset(&mAddress, 0, sizeof(mAddress));
475 * This method sets the IPv6 address of the resource record.
477 * @param[in] aAddress The IPv6 address of the resource record.
480 void SetAddress(otIp6Address &aAddress) { mAddress = aAddress; }
483 * This method returns the reference to IPv6 address of the resource record.
485 * @returns The reference to IPv6 address of the resource record.
487 otIp6Address &GetAddress(void) { return mAddress; }
490 otIp6Address mAddress; ///< IPv6 Address of AAAA Resource Record.
492 } OT_TOOL_PACKED_END;
495 * This class implements Question format.
503 * Constructor for Question.
506 Question(uint16_t aType, uint16_t aClass)
513 * This method returns the type of the question.
515 * @returns The type of the question.
517 uint16_t GetType(void) const { return HostSwap16(mType); }
520 * This method sets the type of the question.
522 * @param[in] aType The type of the question.
525 void SetType(uint16_t aType) { mType = HostSwap16(aType); }
528 * This method returns the class of the question.
530 * @returns The class of the question.
532 uint16_t GetClass(void) const { return HostSwap16(mClass); }
535 * This method sets the class of the question.
537 * @param[in] aClass The class of the question.
540 void SetClass(uint16_t aClass) { mClass = HostSwap16(aClass); }
543 uint16_t mType; ///< The type of the data in question section.
544 uint16_t mClass; ///< The class of the data in question section.
546 } OT_TOOL_PACKED_END;
549 * This class implements Question format of AAAA type.
552 class QuestionAaaa : public Question
557 kType = 0x1C, ///< AAAA Resource Record type.
558 kClass = 0x01, ///< The value of the Internet class.
562 * Default constructor for AAAA Question.
566 : Question(kType, kClass)
571 * This method appends request data to the message.
573 * @param[in] aMessage A reference to the message.
575 * @retval OT_ERROR_NONE Successfully appended the bytes.
576 * @retval OT_ERROR_NO_BUFS Insufficient available buffers to grow the message.
579 otError AppendTo(Message &aMessage) const { return aMessage.Append(this, sizeof(*this)); }
590 #endif // DNS_HEADER_HPP_