--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tcpiputils/dnd/inc/dns_hdr.h Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,466 @@
+// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// dns_hdr.h - name resolver DNS protocol headers
+//
+
+#ifndef __DNS_HDR_H__
+#define __DNS_HDR_H__
+
+#include <e32base.h>
+/**
+@file dns_hdr.h
+DNS Protocol definitions
+@internalComponent Domain Name Resolver
+*/
+
+/**
+Max length of any label (raw data without the length octet)
+*/
+const TInt KDnsMaxLabel = 63;
+
+/**
+Max length of any *uncompressed* domain
+name consisting of a sequence of labels
+(this includes the length octets of the
+labels and the terminating NUL byte for
+the root label).
+*/
+const TInt KDnsMaxName = 256;
+
+const TInt KDnsPort = 53; //< Default port of the DNS server
+
+const TInt KDnsMaxMessage = 512;//< Max length of the DNS message
+
+const TInt KDnsMinHeader = 12; //< Min length of the UDP header
+
+typedef enum
+ {
+ // from RFC-1035
+ EDnsType_A = 1, //< a host address
+ EDnsType_NS = 2, //< an authoritative name server
+ EDnsType_MD = 3, //< a mail destination (Obsolete - use MX)
+ EDnsType_MF = 4, //< a mail forwarder (Obsolete - use MX)
+ EDnsType_CNAME = 5, //< the canonical name for an alias
+ EDnsType_SOA = 6, //< marks the start of a zone of authority
+ EDnsType_MB = 7, //< a mailbox domain name (EXPERIMENTAL)
+ EDnsType_MG = 8, //< a mail group member (EXPERIMENTAL)
+ EDnsType_MR = 9, //< a mail rename domain name (EXPERIMENTAL)
+ EDnsType_NULL = 10, //< a null RR (EXPERIMENTAL)
+ EDnsType_WKS = 11, //< a well known service description
+ EDnsType_PTR = 12, //< a domain name pointer
+ EDnsType_HINFO = 13, //< host information
+ EDnsType_MINFO = 14, //< mailbox or mail list information
+ EDnsType_MX = 15, //< mail exchange
+ EDnsType_TXT = 16, //< text strings
+ //
+ // later additions
+ //
+ EDnsType_AAAA = 28, //< single IPv6 address (RFC-1886)
+ EDnsType_DNAME = 29, //< Non-Terminal DNS Name Redirection (RFC-2672)
+
+ EDnsType_SRV = 33, //< Location of Services (RFC-2782)
+
+ EDnsType_NAPTR = 35, //< Naming Authority Pointer (RFC-2915)
+
+ EDnsType_OPT = 41 //< OPT pseudo-RR (RFC-2671) [never cached]
+ } EDnsType;
+
+typedef enum
+ {
+ // from RFC-1035
+ // (all values of EDnsType and following)
+ //
+ // Putting all of them together -->
+ EDnsQType_A = 1, //< a host address
+ EDnsQType_NS = 2, //< an authoritative name server
+ EDnsQType_MD = 3, //< a mail destination (Obsolete - use MX)
+ EDnsQType_MF = 4, //< a mail forwarder (Obsolete - use MX)
+ EDnsQType_CNAME = 5, //< the canonical name for an alias
+ EDnsQType_SOA = 6, //< marks the start of a zone of authority
+ EDnsQType_MB = 7, //< a mailbox domain name (EXPERIMENTAL)
+ EDnsQType_MG = 8, //< a mail group member (EXPERIMENTAL)
+ EDnsQType_MR = 9, //< a mail rename domain name (EXPERIMENTAL)
+ EDnsQType_NULL = 10, //< a null RR (EXPERIMENTAL)
+ EDnsQType_WKS = 11, //< a well known service description
+ EDnsQType_PTR = 12, //< a domain name pointer
+ EDnsQType_HINFO = 13, //< host information
+ EDnsQType_MINFO = 14, //< mailbox or mail list information
+ EDnsQType_MX = 15, //< mail exchange
+ EDnsQType_TXT = 16, //< text strings
+ //
+ // later additions
+ //
+ EDnsQType_AAAA = 28, //< single IPv6 address (RFC-1866)
+ EDnsQType_DNAME = 29, //< Non-Terminal DNS Name Redirection (RFC-2672)
+
+ EDnsQType_SRV = 33, //< Location of Services (RFC-2782)
+ EDnsQType_NAPTR = 35, //< Naming Authority Pointer (RFC-2915)
+
+ EDnsQType_OPT = 41, //< OPT pseudo-RR (RFC-2671) [never cached]
+
+ // Only Q-types (the combined types)
+ EDnsQType_AXFR = 252, //< A request for a transfer of an entire zone
+ EDnsQType_MAILB = 253, //< A request for mailbox-related records (MB, MG or MR)
+ EDnsQType_MAILA = 254, //< A request for mail agent RRs (Obsolete - see MX)
+ EDnsQType_ANY = 255 //< A request for all records
+ } EDnsQType;
+
+typedef enum
+ {
+ // from RFC-1035
+ EDnsClass_IN = 1, //< the Internet
+ EDnsClass_CS = 2, //< CSNET class (Obsolete - used only for examples in some obsolete RFCs)
+ EDnsClass_CH = 3, //< the CHAOS class
+#ifdef LLMNR_ENABLED
+ EDnsClass_HS = 4, //< Hesiod [Dyer 87]
+ EDnsClass_NONE = 254 //< for dynamic DNS/LLMNR update, RFC 2136, 1.3
+#else
+ EDnsClass_HS = 4 //< Hesiod [Dyer 87]
+#endif
+ } EDnsClass;
+
+typedef enum
+ {
+ // from RFC-1035
+ // (all values of EDnsCalss and following)
+ // Putting all of them together --->
+ EDnsQClass_IN = 1, //< the internet
+ EDnsQClass_CS = 2, //< CSNET class (Obsolete - used only for examples in some obsolete RFCs)
+ EDnsQClass_CH = 3, //< the CHAOS class
+ EDnsQClass_HS = 4, //< Hesiod [Dyer 87]
+
+ // Combined classes - only for question section
+ EDnsQClass_ANY = 255 //< any class
+ } EDnsQClass;
+
+//
+// OPCODE
+//
+typedef enum
+ {
+ EDnsOpcode_QUERY = 0x00, //< Standard Query
+ EDnsOpcode_IQUERY = 0x01, //< Inverse Query (historical)
+#ifdef LLMNR_ENABLED
+ EDnsOpcode_STATUS = 0x02, //< Server Status Query
+ EDnsOpcode_UPDATE = 0x05 //< Dynamic DNS/LLMNR update (RFC 2136, 1.3)
+#else
+ EDnsOpcode_STATUS = 0x02 //< Server Status Query
+#endif
+ } EDnsOpcode;
+
+/**
+// RCODE [0..15]
+*/
+typedef enum
+ {
+ EDnsRcode_NOERROR = 0,
+ EDnsRcode_FORMAT_ERROR = 1,
+ EDnsRcode_SERVER_FAILURE = 2,
+ EDnsRcode_NAME_ERROR = 3,
+ EDnsRcode_NOT_IMPLEMENTED = 4,
+ EDnsRcode_REFUSED = 5
+ } EDnsRcode;
+
+#ifdef LLMNR_ENABLED
+typedef enum
+ {
+ EDnsUpdateRcode_NOERROR = 0,
+ EDnsUpdateRcode_FORMERR = 1,
+ EDnsUpdateRcode_SERVFAIL = 2,
+ EDnsUpdateRcode_NXDOMAIN = 3,
+ EDnsUpdateRcode_NOTIMP = 4,
+ EDnsUpdateRcode_REFUSED = 5,
+ EDnsUpdateRcode_YXDOMAIN = 6,
+ EDnsUpdateRcode_YXRRSET = 7,
+ EDnsUpdateRcode_NXRRSET = 8
+ } EDnsUpdateRcode; //< RFC 2136, 2.2
+#endif
+
+class TInet6HeaderDNS
+/**
+Domain Protocol Message format.
+@verbatim
+ +---------------------+
+ | Header |
+ +---------------------+
+ | Question | the question for the name server
+ +---------------------+
+ | Answer | RRs answering the question
+ +---------------------+
+ | Authority | RRs pointing toward an authority
+ +---------------------+
+ | Additional | RRs holding additional information
+ +---------------------+
+
+ 4.1.1. Header section format (RFC-1035)
+
+ 1 1 1 1 1 1
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | ID |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ |QR| Opcode |AA|TC|RD|RA| Z | RCODE |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | QDCOUNT |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | ANCOUNT |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | NSCOUNT |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | ARCOUNT |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+@endverbatim
+*/
+ {
+public:
+ inline static TInt MinHeaderLength() {return 12;}
+ inline static TInt MaxHeaderLength() {return 512;}
+
+ //
+ // Access Methods
+ //
+ // A general note: unless there is a specific reason,
+ // all bit and bit field access methods return
+ // unshifted result of the masking AND (&) operation.
+ // Conversions to "pure" boolean 1 or 0 is left up to
+ // caller if it really needs the value as such.
+
+ // @return ID (16 bits)
+ inline TInt ID() const { return (i[0] << 8) + i[1]; }
+
+ // @return QR, Query (= 0) or responce ( != 0).
+ inline TInt QR() const { return i[2] & 0x80; }
+
+ // @return OPCODE (0..15)
+ inline TUint OPCODE() const { return (i[2] >> 3) & 0x0F; }
+
+ // @return AA, Authoritative Answer (if != 0)
+ inline TInt AA() const { return i[2] & 0x04; }
+
+ // @return TC, Truncation occurred (if != 0)
+ inline TInt TC() const { return i[2] & 0x02; }
+
+ // @return RD, Recursion Desired (if != 0)
+ inline TInt RD() const { return i[2] & 0x01; }
+
+ // @return RA, Recursion Available (if != 0)
+ inline TInt RA() const { return i[3] & 0x80; }
+
+ // @return Z, Reserved (masked with 0x70)
+ inline TInt Z() const { return i[3] & 0x70; }
+
+ // @return RCODE, Responce Code (0..15)
+ inline TInt RCODE() const { return i[3] & 0x0F; }
+
+ // @return QDCOUNT, the number of entries in query section
+ inline TInt QDCOUNT() const { return (i[4] << 8) + i[5]; }
+
+ // @return ANCOUNT, the number of entries in answer section
+ inline TInt ANCOUNT() const { return (i[6] << 8) + i[7]; }
+
+ // @return NSCOUNT, the number of name server records in authority records
+ inline TInt NSCOUNT() const { return (i[8] << 8) + i[9]; }
+
+ // @return ARCOUNT, the number of entries in additional section
+ inline TInt ARCOUNT() const { return (i[10] << 8) + i[11]; }
+
+ /**
+ // To set the value of RD bit of the header.
+ //
+ // @param aRD, set RD bit, if non-zero, clear otherwise.
+ */
+ inline void SetRD(TInt aRD)
+ {
+ if (aRD)
+ i[2] |= 0x01;
+ else
+ i[2] &= ~0x01;
+ }
+
+// private:
+protected:
+ //
+ // This allocation only covers the fixed minimal portion
+ //
+ TUint8 i[12];
+ //
+ // Methods to support accessing the variable sections
+ //
+public:
+ TInt NameSkip(const TInt aOffset, const TInt aOffsetLimit) const
+ /**
+ Skip over a domain name in a message.
+
+ A name consists of a sequence of labels.
+
+ @param aOffset start offset of the domain name
+ @param aOffsetLimit maximum value for the offset
+
+ @return
+ @li < 0, unsupported format, the message is invalid or corrupt
+ @li > 0, offset of the next query or section
+
+ <b>Note</b>: For a valid return, it should always be that
+ returned value > aOffset!
+ */
+ {
+ TInt tag;
+ TInt k = aOffset;
+ //
+ // Skip over the name
+ //
+ for (;;)
+ {
+ if (k >= aOffsetLimit)
+ return -1; // corrupt buffer (overflow);
+ if ((tag = i[k++]) == 0)
+ break;
+
+ switch (tag & 0xC0)
+ {
+ default:
+ return -1; // Unsupported label format!
+
+ case 0x00: // 0 0 - Normal length of label
+ k += tag;
+ break;
+
+ case 0xC0: // 1 1 - A pointer (compression)
+ k += 1;
+ goto done;
+
+ case 0x40: // 0 1 - Extended Label
+ //
+ // As this is still in Draft stage, the following
+ // code is just a reminder of possible things to
+ // implement. -- msa
+ //
+ switch (tag & 0x3F)
+ {
+ case 0x00: // 16bit Compression pointer follows
+ k += 2; //
+ break;
+ case 0x01: // Bit String label
+ if (k >= aOffsetLimit)
+ return -1; // Corrupted!
+ tag = i[k++]; // Number of significant bits
+ if (tag == 0)
+ tag = 256;
+ k += ((tag + 7) / 8);
+ break;
+ default:
+ return -1; // Unsupported
+ }
+ break;
+ }
+ }
+done:
+ return k;
+ }
+ TInt Query(const TInt aOffset, const TInt aOffsetLimit, TInt &aQType, TInt &aQClass) const
+ /**
+ Extract and skip over single query in Question section.
+
+ A query in question section is a domain-name
+ followed by query type and class fields.
+
+ @param aOffset start offset of the query (domain name)
+ @param aOffsetLimit maximum value for the offset
+
+ @return
+ @li < 0, unsupported format, the message is invalid or corrupt
+ @li > 0, offset of the next query or section
+
+ <b>Note</b>: For a valid return, it should always be that
+ returned value > aOffset!
+ */
+ {
+ //
+ // Skip over the QNAME
+ //
+ TInt k = NameSkip(aOffset, aOffsetLimit);
+ // ..ignore the fact that any return less than
+ // the original aOffset is actually an error.. -- msa
+ //
+ if (k > 0)
+ {
+ if (k + 4 > aOffsetLimit)
+ return -1;
+ aQType = (i[k] << 8) + i[k+1];
+ aQClass = (i[k+2] << 8) + i[k+3];
+ k += 4;
+ }
+ return k;
+ }
+ TInt Resource(const TInt aOffset, const TInt aOffsetLimit, TUint16 &aType, TUint16 &aClass, TUint32 &aTTL, TUint &aRDataOffset, TUint &aRDataLength)
+ /**
+ Extract basic resource record information.
+
+@verbatim
+ 1 1 1 1 1 1
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | |
+ / /
+ / NAME /
+ | |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | TYPE |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | CLASS |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | TTL |
+ | |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | RDLENGTH |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
+ / RDATA /
+ / /
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+@endverbatim
+
+ @param aOffset of the recource record (points to NAME)
+ @param aOffsetLimit maximum value for the offset
+ @retval aType RR type
+ @retval aClass RR class
+ @retval aTTL RR TTL (time to live)
+ @retval aRDataOffset offset to the beginning of the RDATA
+ @retval aRDataLength the length of the RDATA
+
+ @return offset pointing after the RR.
+ */
+ {
+ TInt k = NameSkip(aOffset, aOffsetLimit);
+ if (k < 0)
+ return k;
+ if (k + 10 > aOffsetLimit)
+ return -1; // no room for fixed part of the RR
+ aType = (TUint16)((i[k] << 8) + i[k+1]);
+ k += 2;
+ aClass = (TUint16)((i[k] << 8) + i[k+1]);
+ k += 2;
+ aTTL = (i[k] << 24) +
+ (i[k+1] << 16) +
+ (i[k+2] << 8) +
+ i[k+3];
+ k += 4;
+
+ aRDataLength = (i[k] << 8) + i[k+1];
+ k += 2;
+ aRDataOffset = k;
+ k += aRDataLength;
+ return k > aOffsetLimit ? -1 : k;
+ }
+ };
+#endif