diff -r 78fbd574edf4 -r da856f45b798 zeroconf/dnsparser/src/cdnsmessagecomposerparser.cpp --- /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& quesList = aMessage.Queries(); + const RPointerArray& ansList = aMessage.Answers(); + const RPointerArray& authList= aMessage.Authorities(); + const RPointerArray& additionalList = aMessage.Additional(); + + iMsgBuf->SetInt16(quesList.Count()); + iMsgBuf->SetInt16(ansList.Count()); + iMsgBuf->SetInt16(authList.Count()); + iMsgBuf->SetInt16(additionalList.Count()); + + TInt i; + for(i=0; iSetDomainNameL(ques->Name()); + iMsgBuf->SetInt16(ques->Type()); + iMsgBuf->SetInt16(ques->Class()); + } + + // add answer section + for(i=0; i 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 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 Retrieving Answer Section")); + CDnsResourceData* resourceRecord = GetResourceRecordsL(); + CleanupStack::PushL(resourceRecord); + dnsMessage->AppendAnswerL(resourceRecord); + CleanupStack::Pop(resourceRecord); + } + + // extract the authority section + for(i=0; i Retrieving Authority NS Section")); + CDnsResourceData* resourceRecord = GetResourceRecordsL(); + CleanupStack::PushL(resourceRecord); + dnsMessage->AppendAuthorityL(resourceRecord); + CleanupStack::Pop(resourceRecord); + } + + // extract the additional section + for(i=0; i 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(aResourceRecord); + const TInetAddr& addr = addrRecord->Address(); + iMsgBuf->SetInt16(4); + iMsgBuf->SetInt32(addr.Address()); + } + break; + case EDnsType_PTR: // PTR record + { + CRdTypePtr* ptrRecord = static_cast(aResourceRecord); + iMsgBuf->SetPtrRdLengthL(ptrRecord->DomainName()); + iMsgBuf->SetDomainNameL(ptrRecord->DomainName()); + } + break; + case EDnsType_SRV: // SRV record + { + CRdTypeSrv* srvRecord = static_cast(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(aResourceRecord); + const RArray& txtList = txtRecord->Text(); + iMsgBuf->SetTxtRdLength(txtList); + for(TInt j=0; jSetText(txt); + txt.Close(); + } + } + break; + } + } + + +//Returns the size of the dns message +TUint16 CDnsMessageComposerParser::GetLength(const CDnsMessage& aMessage)const + { + return (aMessage.Size()); + } +