--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tcpiputils/dnd/inc/message.h Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,306 @@
+// 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:
+// message.h - name resolver DNS message interpreter
+//
+
+#ifndef __MESSAGE_H__
+#define __MESSAGE_H__
+
+/**
+@file message.h
+DNS message formats for queries and replies
+@internalComponent Domain Name Resolver
+*/
+#include "dns_hdr.h"
+#include <es_sock.h>
+#include <in_sock.h>
+#include "res_sock.h"
+
+#ifdef EXCLUDE_SYMBIAN_DNS_PUNYCODE
+#undef SYMBIAN_DNS_PUNYCODE
+#endif //EXCLUDE_SYMBIAN_DNS_PUNYCODE
+
+#ifdef SYMBIAN_DNS_PUNYCODE
+#include "punycodeconverter.h"
+_LIT8(KAcePrefix, "xn--");
+#endif
+
+const TInt KErrDndDiscard = KErrUnknown; // Discard the received packet without sending any response
+ // to the application
+const TUint KDndMaxLoopCount = 16; //< This constant is used to detect infinite looping in compressed domain names.
+
+
+typedef TBuf8<KDnsMaxName> THostNameEx; //< Domain Name storage
+typedef TBuf8<KDnsMaxLabel> TNodeLabel; //< Label storage (one component of domain name)
+
+#ifdef LLMNR_ENABLED
+typedef enum
+ {
+ ELlmnr_NoMsg,
+ ELlmnr_Query, //< LLMNR query from a sender
+ ELlmnr_Resp, //< LLMNR response from a responder
+ ELlmnr_Update, //< LLMNR update req from a responder
+ ELlmnr_Yxrrset, //< conflict response from a responder to an update
+ ELlmnr_ConflictResp //< conflict response from a sender, that has
+ //< received multiple LLMNR responses
+ } ELlmnrMessage; //< LLMNR message type
+#endif
+
+class TDndQuestion;
+// Extends the base class with modifying functions
+class TDndHeader : public TInet6HeaderDNS
+ {
+public:
+ // Intialize all fields of fixed header
+ void Init(const TUint16 aID = 0, const TUint8 aOpcode = 0);
+ void SetId(const TUint16 aID);
+ void SetOpcode(const TUint8 aOpcode);
+#ifdef LLMNR_ENABLED
+ void SetQR(const TUint aQR);
+ void SetAA(const TUint aAA);
+ void SetRCode(const TUint aRCode);
+#endif
+ void SetQdCount(const TUint16 aQdCount);
+ void SetAnCount(const TUint16 aAnCount);
+ void SetArCount(const TUint16 aArCount);
+#ifdef SYMBIAN_DNS_PROXY
+ void SetNsCount(const TUint16 aNsCount);
+#endif
+
+//#ifdef LLMNR_ENABLED
+// TInt CheckLlmnrHeader(ELlmnrMessage *aMsgType); //< To check the header of the message received by LLMNR respoonder
+//#endif
+ };
+
+/**
+// @brief A buffer for a DNS message packet
+//
+// TMsgBuf is a binary buffer which holds the message packet of the
+// DNS protocol. This class adds a set of utility methods to the
+// basic buffer class.
+*/
+class TMsgBuf : public TDes8
+ {
+private:
+ TMsgBuf() {}; // Just to prevent construction
+public:
+ static inline TMsgBuf &Cast(TDes8 &aDes)
+ { return *((TMsgBuf *)&aDes); }
+ static inline TMsgBuf &Cast(const TDes8 &aDes)
+ { return *((TMsgBuf *)&aDes); }
+ static inline const TMsgBuf &Cast(const TDesC8 &aDes)
+ { return *((TMsgBuf *)&aDes); }
+ // Returns raw message mapped as TDndHeader
+ inline TDndHeader &Header() const { return (TDndHeader &)Ptr()[0]; }
+
+#if 0
+ // Extract the message ID from DNS message
+ TInt GetID(TUint16 &aID) const;
+#else
+ TInt VerifyMessage(TInt &aRCode, TDndQuestion &aQuestion) const;
+#endif
+ // Decompress <domain-name> from DNS message
+ TInt GetNextName(TInt aOffset, TDes8 &aName, const TUint aDepth = 0) const;
+
+ // Extract <character-string> from DNS message
+ TInt GetNextString(TInt aOffset, TPtrC8 &aString) const;
+
+#ifndef SYMBIAN_DNS_PUNYCODE
+ // Decompress <domain-name> from DNS message
+ TInt GetName(TInt aOffset, TDes &aName) const;
+#else
+ // Decompress <domain-name> from DNS message with IDN option
+ TInt GetName(TInt aOffset, TDes &aName, TBool aIdnEnabled=EFalse) const;
+#endif //SYMBIAN_DNS_PUNYCODE
+
+
+ // Append <domain-name> into DNS message
+ TInt AppendName(const TDesC8 &aName, const TUint aCompressed = 0);
+
+ // Extract RR from the specified offset.
+ TInt GetRR(const TInt aOffset, TUint16 &aType, TUint16 &aClass, TUint32 &aTTL, TUint &aRDataOffset, TUint &aRDataLength) const;
+
+ // Skip <domain-name> in DNS message
+ TInt SkipName(TInt aOffset) const;
+ };
+
+
+// Perform the "DNS case folding" comparison between two names (or labels)
+TBool DnsCompareNames(const TDesC8 &aName1, const TDesC8 &aName2);
+
+
+// A base class to hold uncompressed DNS name
+class TDndName : public THostNameEx
+ {
+public:
+#ifdef SYMBIAN_DNS_PUNYCODE
+ // Constructor to initialse the member variables
+ TDndName():iPunyCodeConverted(EFalse),iIdnEnabled(EFalse)
+ {
+ iPunyCodeName.SetLength(0);
+ }
+#endif //SYMBIAN_DNS_PUNYCODE
+
+ // Set name from address (for PTR query)
+ TInt SetName(const TInetAddr &aAddr);
+
+ // Set name from hostname (system encoding)
+ TInt SetName(const THostName &aName);
+
+ // Set name from DNS message (domain name)
+ TInt SetName(const TMsgBuf &aBuf, const TInt aOffset);
+
+ // Get (Append) name into buffer
+ TInt GetName(TDes &aName, const TInt aStart = 0) const;
+
+ // Get IP address from PTR name
+ TBool GetAddress(TInetAddr &aAddr) const;
+#ifdef SYMBIAN_DNS_PUNYCODE
+ void EnableIdn(TBool aEnable)
+ {
+ iIdnEnabled = aEnable;
+ }
+private:
+ TPunyCodeDndName iPunyCodeName;
+ TBool iPunyCodeConverted;
+ TBool iIdnEnabled;
+#endif //SYMBIAN_DNS_PUNYCODE
+ };
+
+/**
+// @brief A Resource Record reference structure
+//
+// This is only a reference to the real data which is
+// stored in a separate DNS message buffer (provided
+// with the constructor).
+*/
+class TDndRR
+ {
+public:
+ TDndRR(const TMsgBuf &aMsg) : iBuf(aMsg) {}
+private:
+ const TMsgBuf &iBuf; //< A reference to he DNS reply message
+public:
+
+ // Initialize RR reference to point the specified RR value ("virtual ordering" of RR's)
+ TInt FindRR(TInt aOffset, TInt aNumRR, EDnsQType aType, EDnsQClass aClass, TInt aNext = 0);
+ // Initialize RR reference to point the specified RR value ("raw ordering").
+ TInt LocateRR(TInt aOffset, TInt aNumRR, EDnsQType aType, EDnsQClass aClass, TInt aStart);
+
+ // Extract information from RR, and pack it into aName and aAddr
+ TInt GetResponse(TDes &aName, TInetAddr &aAddr) const;
+ // Extract information from RR, and pack it into generic TDnsQueryResp format
+ TInt GetResponse(TDnsMessageBuf &aAnswer, TInetAddr **aAddr) const;
+
+ // Extract address from the RR for A and AAAA type records.
+ TInt GetSockAddr(TInetAddr& aAddr) const;
+
+ // Extract <domain-name> from the RDATA of RR
+ TInt GetNameFromRDATA(TDes8 &aName, const TUint aOffset = 0) const;
+
+ // Extract <character-string> from the RDATA of RR
+ TInt GetStringFromRDATA(TPtrC8 &aString, const TUint aOffset) const;
+
+ TInt iName; //< Offset of the RR (also the name)
+ /*EDnsType*/ TUint16 iType; //< Resource Type
+ /*EDnsClass*/ TUint16 iClass; //< Resource class
+ TUint32 iTTL; //< Time to live
+ TUint iRdLength; //< Length of the resource Data
+ TUint iRd; //< Offset of the RDATA content
+#ifdef SYMBIAN_DNS_PUNYCODE
+ TBool iIdnEnabled; //< whether IDN support is enabled or not.
+#endif //SYMBIAN_DNS_PUNYCODE
+ };
+
+#ifdef LLMNR_ENABLED
+/**
+// @brief Resource Record builder class
+//
+// A tool to build Resource records incrementally to a reply buffer.
+// The usage:
+//
+// Construct TDndRROut(buf) and then for each Resource Record (RR),
+// repeat the following procedure
+//
+// @li initialize RR Type, Class and TTL
+// @li call Append() to create an RR the specified type with empty RData
+// @li call AppendRData methods to build the RData content (as many times
+// as required).
+//
+// Or, alternately, append the RDATA by any other means to the message
+// buffer and call any one of the AppendRData methods as last to fix up the
+// correct RDLENGTH into the RR (calling AppendRData() will just fix the
+// RDLENGTH without adding anything).
+*/
+class TDndRROut
+ {
+public:
+ TDndRROut(TMsgBuf &aMsg) : iBuf(aMsg), iRd(0) {}
+private:
+ TMsgBuf &iBuf; //< A reference to he DNS message
+public:
+ TInt Append(const TDesC8 &aName, TInt aCompression);
+ TInt AppendRData(const TDesC8 &aName, TInt aCompression) const;
+ TInt AppendRData(const TInetAddr &aAddr) const;
+ TInt AppendRData(const TDesC8 &aRData) const;
+ void AppendRData() const;
+
+ /*EDnsType*/ TUint16 iType; //< Resource Type
+ /*EDnsClass*/ TUint16 iClass; //< Resource class
+ TUint32 iTTL; //< Time to live
+#ifdef SYMBIAN_DNS_PUNYCODE
+ TBool iIdnEnabled; //< whether IDN support is enabled or not.
+#endif //SYMBIAN_DNS_PUNYCODE
+private:
+ TUint iRd; //< Offset of the RDATA content
+ };
+#endif
+
+#ifdef LLMNR_ENABLED
+class TDndReqData;
+#endif
+
+/**
+// @brief Unpacked representation of a Question Section
+//
+// The main components of a question are: the name, query
+// type and class. This class is only for convenience and
+// used becuase the name in real message can be compressed.
+// It's sometimes easier to handle unpacked names.
+*/
+class TDndQuestion : public TDndName
+ {
+public:
+ inline TDndQuestion() : iQType(EDnsQType(0)), iQClass(EDnsQClass(0)) {} //< Initialize to invalid type and class (= 0)
+
+ // functions to set the private variables
+ inline void SetQType(EDnsQType aQType) { iQType = aQType; }
+ inline void SetQClass(EDnsQClass aQClass) { iQClass = aQClass; }
+
+ inline EDnsQType QType() const { return iQType; }
+ inline EDnsQClass QClass() const { return iQClass; }
+
+ // Create a TDndQuestion from a DNS message
+ TInt Create(const TMsgBuf &aBuf, TInt aIndex);
+
+ // Append a Question section into DNS message
+ TInt Append(TMsgBuf& aMsgBuf, TUint aCompressed = 0) const;
+
+ // Compare if two questions are same
+ TInt CheckQuestion(const TDndQuestion &aQuestion) const;
+private:
+ EDnsQType iQType;
+ EDnsQClass iQClass;
+ };
+#endif