--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/zeroconf/dnsparser/src/cdnsmessagecomposerparser.cpp Thu Jun 24 19:09:47 2010 +0530
@@ -0,0 +1,372 @@
+/*
+* Copyright (c) 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:
+*
+*/
+
+
+#include "cdnsmessagecomposerparser.h"
+#include "cdnsmsgbuf.h"
+#include "cdnspacket.h"
+
+
+__FLOG_STMT(_LIT8(KSubsys,"Dns Message Composer Parser");)
+__FLOG_STMT(_LIT8(KComponent,"DnsMessage");)
+
+
+
+CDnsMessageComposerParser::CDnsMessageComposerParser()
+ {
+ }
+
+
+EXPORT_C CDnsMessageComposerParser* CDnsMessageComposerParser::NewL()
+ {
+ CDnsMessageComposerParser* self= new(ELeave)CDnsMessageComposerParser;
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+
+CDnsMessageComposerParser::~CDnsMessageComposerParser()
+ {
+ iBuf.Close();
+ delete iPacket;
+ delete iMsgBuf;
+ __FLOG(_L8("-> Composer Parser destroyed"));
+ __FLOG_CLOSE;
+ }
+
+
+void CDnsMessageComposerParser::ConstructL()
+ {
+ __FLOG_OPEN(KSubsys, KComponent);
+ __FLOG(_L8("-> Composer parser created"));
+ }
+
+
+/**
+ Composes mdns message
+ @param aMessage
+ @param aType RR type
+ @param aUnicast
+ @return iBuf composed dns buffer
+ */
+EXPORT_C void CDnsMessageComposerParser::CreateMessageL(RBuf8& aMessageBuffer, const CDnsMessage& aMessage )
+ {
+ __FLOG(_L8("-> Composing Dns Message"));
+
+ aMessageBuffer.CreateL(GetLength(aMessage));
+
+ iMsgBuf = CDnsMsgBuf::NewL(aMessageBuffer);
+
+ const TDnsHeader& header = aMessage.Header();
+ iMsgBuf->SetInt16(header.Id());
+ iMsgBuf->SetInt16(header.Flags());
+
+ const RPointerArray<CDnsQuestion>& quesList = aMessage.Queries();
+ const RPointerArray<CDnsResourceData>& ansList = aMessage.Answers();
+ const RPointerArray<CDnsResourceData>& authList= aMessage.Authorities();
+ const RPointerArray<CDnsResourceData>& additionalList = aMessage.Additional();
+
+ iMsgBuf->SetInt16(quesList.Count());
+ iMsgBuf->SetInt16(ansList.Count());
+ iMsgBuf->SetInt16(authList.Count());
+ iMsgBuf->SetInt16(additionalList.Count());
+
+ TInt i;
+ for(i=0; i<quesList.Count(); i++ )
+ {
+ CDnsQuestion* ques = quesList[i];
+
+ iMsgBuf->SetDomainNameL(ques->Name());
+ iMsgBuf->SetInt16(ques->Type());
+ iMsgBuf->SetInt16(ques->Class());
+ }
+
+ // add answer section
+ for(i=0; i<ansList.Count(); i++ )
+ {
+ AppendResourceRecordsL(ansList[i]);
+ }
+
+ // add authority section
+ for(i=0; i<authList.Count(); i++ )
+ {
+ AppendResourceRecordsL(authList[i]);
+ }
+
+ // add additional section
+ for(i=0; i<additionalList.Count(); i++ )
+ {
+ AppendResourceRecordsL(additionalList[i]);
+ }
+ aMessageBuffer.SetLength(GetLength(aMessage));
+ }
+
+
+/**
+ Parses the raw dns packet
+ @param aBuf
+ @return dnsMessage Dns Message Structure
+ */
+EXPORT_C CDnsMessage* CDnsMessageComposerParser::ParseMessageL(const TDesC8& aBuf)
+ {
+ __FLOG(_L8("-> Parsing Dns Raw Buffer"));
+ iBuf.CreateL(aBuf);
+ iPacket = CDnsPacket::NewL(iBuf.LeftTPtr(iBuf.Length()));
+
+ const TDnsHeader& header = iPacket->GetHeaderL();
+
+ CDnsMessage* dnsMessage = CDnsMessage::NewL(header.Id(),header.IsQuery());
+ CleanupStack::PushL(dnsMessage);
+
+ dnsMessage->SetHeader(header);
+
+ TInt i;
+ // extract the query section;
+ for(i=0; i<header.QueryCount(); i++)
+ {
+ __FLOG(_L8("-> Retrieving Query Section"));
+ RBuf8 domainName;
+ domainName.CreateL(KMaxDNSNameLength);
+ iPacket->GetDomainNameL(domainName);
+ CDnsQuestion* question = CDnsQuestion::NewL();
+ CleanupStack::PushL(question);
+ question->SetNameL(domainName);
+ question->SetType(iPacket->GetInt16L());
+ question->SetClass(iPacket->GetInt16L());
+ domainName.Close();
+ dnsMessage->AppendQueryL(question);
+ CleanupStack::Pop(question);
+ }
+
+ // extract the answer section
+ for(i=0; i<header.AnswerCount(); i++)
+ {
+ __FLOG(_L8("-> Retrieving Answer Section"));
+ CDnsResourceData* resourceRecord = GetResourceRecordsL();
+ CleanupStack::PushL(resourceRecord);
+ dnsMessage->AppendAnswerL(resourceRecord);
+ CleanupStack::Pop(resourceRecord);
+ }
+
+ // extract the authority section
+ for(i=0; i<header.AuthorityNSCount(); i++)
+ {
+ __FLOG(_L8("-> Retrieving Authority NS Section"));
+ CDnsResourceData* resourceRecord = GetResourceRecordsL();
+ CleanupStack::PushL(resourceRecord);
+ dnsMessage->AppendAuthorityL(resourceRecord);
+ CleanupStack::Pop(resourceRecord);
+ }
+
+ // extract the additional section
+ for(i=0; i<header.AdditionalRCount(); i++)
+ {
+ __FLOG(_L8("-> Retrieving Additional Record Section"));
+ CDnsResourceData* resourceRecord = GetResourceRecordsL();
+ CleanupStack::PushL(resourceRecord);
+ dnsMessage->AppendAdditionalL(resourceRecord);
+ CleanupStack::Pop(resourceRecord);
+ }
+
+ CleanupStack::Pop(dnsMessage);
+ return dnsMessage;
+ }
+
+
+CDnsResourceData* CDnsMessageComposerParser::GetResourceRecordsL()
+ {
+ __FLOG(_L8("-> Retrieving Resource Records"));
+ RBuf8 name;
+ name.CreateL(KMaxDNSNameLength);
+ iPacket->GetDomainNameL(name);
+ TUint16 type = iPacket->GetInt16L();
+ TUint16 classType = iPacket->GetInt16L();
+ TUint32 ttl = iPacket->GetInt32L();
+ TUint16 rdLength = iPacket->GetInt16L();
+
+ CDnsResourceData* resourceData = NULL;
+
+ switch(type)
+ {
+ case EDnsType_A : // A record
+ {
+ TInetAddr addr;
+ addr.SetAddress(iPacket->GetInt32L());
+
+ CRdTypeA* addrRecord = CRdTypeA::NewL();
+ CleanupStack::PushL(addrRecord);
+
+ addrRecord->SetNameL(name);
+ addrRecord->SetType(type);
+ addrRecord->SetClass(classType);
+ addrRecord->SetTtl(ttl);
+ addrRecord->SetRdLength(rdLength);
+ addrRecord->SetAddr(addr);
+
+ CleanupStack::Pop(addrRecord);
+ resourceData = addrRecord;
+ }
+ break;
+ case EDnsType_PTR: // PTR record
+ {
+ RBuf8 ptrDomainName;
+ ptrDomainName.CreateL(KMaxDNSNameLength);
+ iPacket->GetRdDomainNameL(ptrDomainName,rdLength);
+
+ CRdTypePtr* ptrRecord = CRdTypePtr::NewL();
+ CleanupStack::PushL(ptrRecord);
+
+ ptrRecord->SetNameL(name);
+ ptrRecord->SetType(type);
+ ptrRecord->SetClass(classType);
+ ptrRecord->SetTtl(ttl);
+ ptrRecord->SetRdLength(rdLength);
+ ptrRecord->SetDomainNameL(ptrDomainName);
+
+ ptrDomainName.Close();
+ CleanupStack::Pop(ptrRecord);
+ resourceData = ptrRecord;
+ }
+ break;
+ case EDnsType_SRV: // SRC record
+ {
+ TUint16 priority = iPacket->GetInt16L();
+ TUint16 weight = iPacket->GetInt16L();
+ TUint16 port = iPacket->GetInt16L();
+ RBuf8 srvDomainName;
+ srvDomainName.CreateL(KMaxDNSNameLength);
+ TInt length1 = sizeof(priority);
+ TInt length2 = sizeof(weight);
+ TInt length3 = sizeof(port);
+ TInt length = length1+length2+length3; // 6 = sizeof( prio + weight + port )
+ iPacket->GetRdDomainNameL(srvDomainName,rdLength - length);
+
+ CRdTypeSrv* srvRecord = CRdTypeSrv::NewL();
+ CleanupStack::PushL(srvRecord);
+
+ srvRecord->SetNameL(name);
+ srvRecord->SetType(type);
+ srvRecord->SetClass(classType);
+ srvRecord->SetTtl(ttl);
+ srvRecord->SetRdLength(rdLength);
+ srvRecord->SetPriority(priority);
+ srvRecord->SetWeight(weight);
+ srvRecord->SetPort(port);
+ srvRecord->SetTargetL(srvDomainName);
+
+ srvDomainName.Close();
+ CleanupStack::Pop(srvRecord);
+ resourceData = srvRecord;
+ }
+ break;
+ case EDnsType_TXT: // TXT record
+ {
+ TInt strLength = 0;
+ CRdTypeTxt* txtRecord = CRdTypeTxt::NewL();
+ CleanupStack::PushL(txtRecord);
+
+ txtRecord->SetNameL(name);
+ txtRecord->SetType(type);
+ txtRecord->SetClass(classType);
+ txtRecord->SetTtl(ttl);
+ txtRecord->SetRdLength(rdLength);
+
+ while(rdLength)
+ {
+ RBuf8 txtString;
+ strLength = iPacket->GetCharL();
+ rdLength--;
+ txtString.CreateL(strLength);
+ iPacket->GetStringL(txtString,strLength);
+ rdLength -= strLength;
+ txtRecord->AppendTextDataL(txtString);
+ }
+ CleanupStack::Pop(txtRecord);
+ resourceData = txtRecord;
+ }
+ break;
+ default:
+ //User::Leave(KErrCorrupt);
+ break;
+ }
+ name.Close();
+ return resourceData;
+ }
+
+
+void CDnsMessageComposerParser::AppendResourceRecordsL( CDnsResourceData* aResourceRecord )
+ {
+ __FLOG(_L8("-> Adding Resource Records to buffer"));
+
+ iMsgBuf->SetDomainNameL(aResourceRecord->Name());
+ iMsgBuf->SetInt16(aResourceRecord->Type());
+ iMsgBuf->SetInt16(aResourceRecord->Class());
+ iMsgBuf->SetInt32(aResourceRecord->Ttl());
+
+ switch( aResourceRecord->Type())
+ {
+ case EDnsType_A: // A record
+ {
+ CRdTypeA* addrRecord = static_cast<CRdTypeA*>(aResourceRecord);
+ const TInetAddr& addr = addrRecord->Address();
+ iMsgBuf->SetInt16(4);
+ iMsgBuf->SetInt32(addr.Address());
+ }
+ break;
+ case EDnsType_PTR: // PTR record
+ {
+ CRdTypePtr* ptrRecord = static_cast<CRdTypePtr*>(aResourceRecord);
+ iMsgBuf->SetPtrRdLengthL(ptrRecord->DomainName());
+ iMsgBuf->SetDomainNameL(ptrRecord->DomainName());
+ }
+ break;
+ case EDnsType_SRV: // SRV record
+ {
+ CRdTypeSrv* srvRecord = static_cast<CRdTypeSrv*>(aResourceRecord);
+ iMsgBuf->SetSrvRdLengthL(srvRecord->Target());
+ iMsgBuf->SetInt16(srvRecord->Priority());
+ iMsgBuf->SetInt16( srvRecord->Weight());
+ iMsgBuf->SetInt16( srvRecord->Port());
+ iMsgBuf->SetDomainNameL(srvRecord->Target());
+ }
+ break;
+ case EDnsType_TXT: // TXT record
+ {
+ CRdTypeTxt* txtRecord = static_cast<CRdTypeTxt*>(aResourceRecord);
+ const RArray<RBuf8>& txtList = txtRecord->Text();
+ iMsgBuf->SetTxtRdLength(txtList);
+ for(TInt j=0; j<txtList.Count(); j++)
+ {
+ RBuf8 txt;
+ txt.CreateL(txtList[j]);
+ iMsgBuf->SetText(txt);
+ txt.Close();
+ }
+ }
+ break;
+ }
+ }
+
+
+//Returns the size of the dns message
+TUint16 CDnsMessageComposerParser::GetLength(const CDnsMessage& aMessage)const
+ {
+ return (aMessage.Size());
+ }
+