zeroconf/dnsparser/src/cdnsmessagecomposerparser.cpp
changeset 14 da856f45b798
--- /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());
+    }
+