zeroconf/dnsparser/src/cdnsmessagecomposerparser.cpp
changeset 14 da856f45b798
equal deleted inserted replaced
12:78fbd574edf4 14:da856f45b798
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "cdnsmessagecomposerparser.h"
       
    20 #include "cdnsmsgbuf.h"
       
    21 #include "cdnspacket.h"
       
    22 
       
    23 
       
    24 __FLOG_STMT(_LIT8(KSubsys,"Dns Message Composer Parser");)
       
    25 __FLOG_STMT(_LIT8(KComponent,"DnsMessage");)
       
    26 
       
    27 
       
    28 
       
    29 CDnsMessageComposerParser::CDnsMessageComposerParser()
       
    30     {
       
    31     }
       
    32 
       
    33 
       
    34 EXPORT_C CDnsMessageComposerParser* CDnsMessageComposerParser::NewL()
       
    35     {
       
    36     CDnsMessageComposerParser* self= new(ELeave)CDnsMessageComposerParser;
       
    37     CleanupStack::PushL(self);
       
    38     self->ConstructL();
       
    39     CleanupStack::Pop(self);
       
    40     return self;
       
    41     }
       
    42  
       
    43 
       
    44 CDnsMessageComposerParser::~CDnsMessageComposerParser()
       
    45     {
       
    46     iBuf.Close();
       
    47     delete iPacket;
       
    48     delete iMsgBuf;
       
    49     __FLOG(_L8("-> Composer Parser destroyed"));
       
    50     __FLOG_CLOSE;
       
    51     }
       
    52 
       
    53 
       
    54 void CDnsMessageComposerParser::ConstructL()
       
    55     {   
       
    56 	__FLOG_OPEN(KSubsys, KComponent);
       
    57 	__FLOG(_L8("-> Composer parser created"));
       
    58     }
       
    59         
       
    60 
       
    61 /**
       
    62  Composes mdns message
       
    63  @param aMessage
       
    64  @param aType RR type
       
    65  @param aUnicast 
       
    66  @return iBuf composed dns buffer
       
    67  */
       
    68 EXPORT_C void CDnsMessageComposerParser::CreateMessageL(RBuf8& aMessageBuffer, const CDnsMessage& aMessage )
       
    69     {
       
    70      __FLOG(_L8("-> Composing Dns Message"));
       
    71        
       
    72     aMessageBuffer.CreateL(GetLength(aMessage));   
       
    73     
       
    74     iMsgBuf = CDnsMsgBuf::NewL(aMessageBuffer);
       
    75 
       
    76     const TDnsHeader& header = aMessage.Header();  
       
    77     iMsgBuf->SetInt16(header.Id());
       
    78     iMsgBuf->SetInt16(header.Flags());
       
    79       	   
       
    80     const RPointerArray<CDnsQuestion>& quesList = aMessage.Queries();
       
    81     const RPointerArray<CDnsResourceData>& ansList = aMessage.Answers();
       
    82     const RPointerArray<CDnsResourceData>& authList= aMessage.Authorities();
       
    83     const RPointerArray<CDnsResourceData>& additionalList = aMessage.Additional();
       
    84     
       
    85     iMsgBuf->SetInt16(quesList.Count());
       
    86     iMsgBuf->SetInt16(ansList.Count());
       
    87     iMsgBuf->SetInt16(authList.Count());
       
    88     iMsgBuf->SetInt16(additionalList.Count());
       
    89     
       
    90     TInt i;    
       
    91     for(i=0; i<quesList.Count(); i++ )
       
    92     	{
       
    93     	CDnsQuestion* ques = quesList[i];
       
    94         
       
    95     	iMsgBuf->SetDomainNameL(ques->Name());    	 
       
    96     	iMsgBuf->SetInt16(ques->Type());
       
    97     	iMsgBuf->SetInt16(ques->Class());
       
    98     	}  
       
    99     
       
   100     // add answer section
       
   101     for(i=0;  i<ansList.Count(); i++ )
       
   102     	{
       
   103     	AppendResourceRecordsL(ansList[i]);
       
   104     	}
       
   105     
       
   106     // add authority section
       
   107     for(i=0;  i<authList.Count(); i++ )
       
   108     	{
       
   109     	AppendResourceRecordsL(authList[i]);
       
   110     	}
       
   111     
       
   112     // add additional section
       
   113     for(i=0;  i<additionalList.Count(); i++ )
       
   114     	{
       
   115     	AppendResourceRecordsL(additionalList[i]);
       
   116     	}   
       
   117     aMessageBuffer.SetLength(GetLength(aMessage));
       
   118     }
       
   119 
       
   120 
       
   121 /**
       
   122  Parses the raw dns packet
       
   123  @param aBuf
       
   124  @return dnsMessage Dns Message Structure
       
   125  */
       
   126 EXPORT_C CDnsMessage* CDnsMessageComposerParser::ParseMessageL(const TDesC8& aBuf)
       
   127    { 
       
   128    __FLOG(_L8("-> Parsing Dns Raw Buffer"));
       
   129    iBuf.CreateL(aBuf);  
       
   130    iPacket = CDnsPacket::NewL(iBuf.LeftTPtr(iBuf.Length()));
       
   131    
       
   132    const TDnsHeader& header = iPacket->GetHeaderL();
       
   133   
       
   134    CDnsMessage* dnsMessage = CDnsMessage::NewL(header.Id(),header.IsQuery());
       
   135    CleanupStack::PushL(dnsMessage);
       
   136    
       
   137    dnsMessage->SetHeader(header);
       
   138    
       
   139    TInt i;
       
   140    // extract the query section;
       
   141    for(i=0; i<header.QueryCount(); i++)
       
   142 	   {
       
   143 	   __FLOG(_L8("-> Retrieving Query Section"));
       
   144 	   RBuf8 domainName;
       
   145 	   domainName.CreateL(KMaxDNSNameLength);
       
   146 	   iPacket->GetDomainNameL(domainName);
       
   147 	   CDnsQuestion* question = CDnsQuestion::NewL();
       
   148 	   CleanupStack::PushL(question);
       
   149 	   question->SetNameL(domainName);
       
   150 	   question->SetType(iPacket->GetInt16L());
       
   151 	   question->SetClass(iPacket->GetInt16L());	   
       
   152 	   domainName.Close();
       
   153 	   dnsMessage->AppendQueryL(question);
       
   154 	   CleanupStack::Pop(question);
       
   155 	   }
       
   156    
       
   157    	// extract the answer section
       
   158    for(i=0; i<header.AnswerCount(); i++)
       
   159 	   {  
       
   160 	   __FLOG(_L8("-> Retrieving  Answer Section"));
       
   161        CDnsResourceData* resourceRecord = GetResourceRecordsL();
       
   162        CleanupStack::PushL(resourceRecord);
       
   163 	   dnsMessage->AppendAnswerL(resourceRecord);
       
   164 	   CleanupStack::Pop(resourceRecord);
       
   165 	   }
       
   166    
       
   167   	// extract the authority section
       
   168    for(i=0; i<header.AuthorityNSCount(); i++)
       
   169 	   {
       
   170 	   __FLOG(_L8("-> Retrieving  Authority NS Section"));
       
   171 	   CDnsResourceData* resourceRecord = GetResourceRecordsL();
       
   172 	   CleanupStack::PushL(resourceRecord);
       
   173 	   dnsMessage->AppendAuthorityL(resourceRecord);
       
   174 	   CleanupStack::Pop(resourceRecord);
       
   175 	   }
       
   176 
       
   177 	// extract the additional section
       
   178 	for(i=0; i<header.AdditionalRCount(); i++)
       
   179 		{
       
   180 		 __FLOG(_L8("-> Retrieving Additional Record Section"));
       
   181 	    CDnsResourceData* resourceRecord = GetResourceRecordsL();
       
   182 	    CleanupStack::PushL(resourceRecord);
       
   183 		dnsMessage->AppendAdditionalL(resourceRecord);
       
   184 		CleanupStack::Pop(resourceRecord);
       
   185 		} 		
       
   186 	
       
   187    CleanupStack::Pop(dnsMessage);
       
   188    return dnsMessage;
       
   189    }
       
   190 
       
   191 
       
   192 CDnsResourceData* CDnsMessageComposerParser::GetResourceRecordsL()
       
   193 	{
       
   194 	__FLOG(_L8("-> Retrieving Resource Records"));
       
   195 	RBuf8 name;
       
   196 	name.CreateL(KMaxDNSNameLength);
       
   197 	iPacket->GetDomainNameL(name);
       
   198 	TUint16 type = iPacket->GetInt16L();
       
   199 	TUint16 classType = iPacket->GetInt16L();
       
   200 	TUint32 ttl = iPacket->GetInt32L();
       
   201 	TUint16 rdLength = iPacket->GetInt16L();
       
   202 	
       
   203 	CDnsResourceData* resourceData = NULL;
       
   204 	
       
   205 	switch(type)
       
   206 		{
       
   207 		case EDnsType_A	: // A record
       
   208 			{
       
   209 			TInetAddr addr;
       
   210 			addr.SetAddress(iPacket->GetInt32L());
       
   211 			
       
   212 			CRdTypeA* addrRecord = CRdTypeA::NewL();
       
   213 			CleanupStack::PushL(addrRecord);			
       
   214 			
       
   215 			addrRecord->SetNameL(name);
       
   216 			addrRecord->SetType(type);
       
   217 			addrRecord->SetClass(classType);
       
   218 			addrRecord->SetTtl(ttl);
       
   219 			addrRecord->SetRdLength(rdLength);
       
   220 			addrRecord->SetAddr(addr);
       
   221 					
       
   222 			CleanupStack::Pop(addrRecord);
       
   223 			resourceData = addrRecord;
       
   224 			}
       
   225 		    break;			
       
   226 	    case EDnsType_PTR: // PTR record
       
   227 	    	{
       
   228 			RBuf8 ptrDomainName;
       
   229 			ptrDomainName.CreateL(KMaxDNSNameLength);
       
   230 			iPacket->GetRdDomainNameL(ptrDomainName,rdLength);
       
   231 			
       
   232 			CRdTypePtr* ptrRecord = CRdTypePtr::NewL();
       
   233 			CleanupStack::PushL(ptrRecord);
       
   234 			
       
   235 			ptrRecord->SetNameL(name);
       
   236 			ptrRecord->SetType(type);
       
   237 			ptrRecord->SetClass(classType);
       
   238 			ptrRecord->SetTtl(ttl);
       
   239 			ptrRecord->SetRdLength(rdLength);						
       
   240 			ptrRecord->SetDomainNameL(ptrDomainName);
       
   241 			
       
   242 			ptrDomainName.Close();			
       
   243 			CleanupStack::Pop(ptrRecord);
       
   244 			resourceData = ptrRecord;
       
   245 	    	}
       
   246 		    break;	
       
   247 		case EDnsType_SRV: // SRC record
       
   248 			{
       
   249 			TUint16 priority = iPacket->GetInt16L();
       
   250 			TUint16 weight = iPacket->GetInt16L();
       
   251 			TUint16 port = iPacket->GetInt16L();
       
   252 			RBuf8 srvDomainName;
       
   253 			srvDomainName.CreateL(KMaxDNSNameLength); 
       
   254 			TInt length1 = sizeof(priority);
       
   255 			TInt length2 = sizeof(weight);
       
   256 			TInt length3 = sizeof(port);
       
   257 			TInt length =  length1+length2+length3; // 6 = sizeof( prio + weight + port )
       
   258 			iPacket->GetRdDomainNameL(srvDomainName,rdLength - length); 
       
   259 			
       
   260 			CRdTypeSrv* srvRecord = CRdTypeSrv::NewL();
       
   261 			CleanupStack::PushL(srvRecord);
       
   262 			
       
   263 			srvRecord->SetNameL(name);
       
   264 			srvRecord->SetType(type);
       
   265 			srvRecord->SetClass(classType);
       
   266 			srvRecord->SetTtl(ttl);
       
   267 			srvRecord->SetRdLength(rdLength);
       
   268 			srvRecord->SetPriority(priority);
       
   269 			srvRecord->SetWeight(weight);
       
   270 			srvRecord->SetPort(port);						
       
   271 			srvRecord->SetTargetL(srvDomainName);
       
   272 			
       
   273 			srvDomainName.Close();			
       
   274 			CleanupStack::Pop(srvRecord);
       
   275 			resourceData = srvRecord;
       
   276 			}
       
   277 		    break;		
       
   278 		case EDnsType_TXT: // TXT record
       
   279 			{
       
   280 			TInt strLength = 0;
       
   281 			CRdTypeTxt* txtRecord = CRdTypeTxt::NewL();
       
   282 			CleanupStack::PushL(txtRecord);
       
   283 			
       
   284 			txtRecord->SetNameL(name);
       
   285 			txtRecord->SetType(type);
       
   286 			txtRecord->SetClass(classType);
       
   287 			txtRecord->SetTtl(ttl);
       
   288 			txtRecord->SetRdLength(rdLength);					
       
   289 			
       
   290 	    	while(rdLength)
       
   291 				{
       
   292 				RBuf8 txtString;
       
   293 				strLength = iPacket->GetCharL();
       
   294 				rdLength--;
       
   295 				txtString.CreateL(strLength);
       
   296 				iPacket->GetStringL(txtString,strLength);
       
   297 				rdLength -= strLength;
       
   298 				txtRecord->AppendTextDataL(txtString);	
       
   299 				}	    	
       
   300 	    	CleanupStack::Pop(txtRecord);
       
   301 	    	resourceData = txtRecord;
       
   302 			}
       
   303 		    break;			
       
   304 		default:
       
   305 			//User::Leave(KErrCorrupt);
       
   306 		    break;
       
   307 	    }
       
   308 	name.Close();
       
   309 	return resourceData;
       
   310 	}
       
   311 
       
   312 
       
   313 void CDnsMessageComposerParser::AppendResourceRecordsL( CDnsResourceData* aResourceRecord )
       
   314 	{
       
   315 	__FLOG(_L8("-> Adding Resource Records to buffer"));
       
   316 	
       
   317 	iMsgBuf->SetDomainNameL(aResourceRecord->Name()); 
       
   318 	iMsgBuf->SetInt16(aResourceRecord->Type());
       
   319 	iMsgBuf->SetInt16(aResourceRecord->Class());
       
   320 	iMsgBuf->SetInt32(aResourceRecord->Ttl());
       
   321 		
       
   322 	switch( aResourceRecord->Type())
       
   323 		{
       
   324 		case EDnsType_A: // A record 
       
   325 			{
       
   326 			CRdTypeA* addrRecord = static_cast<CRdTypeA*>(aResourceRecord);	
       
   327 			const TInetAddr& addr = addrRecord->Address();
       
   328 			iMsgBuf->SetInt16(4);
       
   329 			iMsgBuf->SetInt32(addr.Address());
       
   330 			}
       
   331 		    break;	
       
   332 		case EDnsType_PTR: // PTR record	
       
   333 			{
       
   334 			CRdTypePtr* ptrRecord = static_cast<CRdTypePtr*>(aResourceRecord);
       
   335 			iMsgBuf->SetPtrRdLengthL(ptrRecord->DomainName());		
       
   336 			iMsgBuf->SetDomainNameL(ptrRecord->DomainName());
       
   337 			}
       
   338 		    break;	
       
   339 		case EDnsType_SRV: // SRV record
       
   340 			{
       
   341 			CRdTypeSrv* srvRecord = static_cast<CRdTypeSrv*>(aResourceRecord);
       
   342 			iMsgBuf->SetSrvRdLengthL(srvRecord->Target());
       
   343 			iMsgBuf->SetInt16(srvRecord->Priority());
       
   344 			iMsgBuf->SetInt16( srvRecord->Weight());
       
   345 			iMsgBuf->SetInt16( srvRecord->Port());
       
   346 			iMsgBuf->SetDomainNameL(srvRecord->Target());
       
   347 			}
       
   348 		    break;
       
   349 		case EDnsType_TXT: // TXT record
       
   350 			{
       
   351 			CRdTypeTxt* txtRecord = static_cast<CRdTypeTxt*>(aResourceRecord);
       
   352 			const RArray<RBuf8>& txtList = txtRecord->Text();
       
   353 			iMsgBuf->SetTxtRdLength(txtList);
       
   354 			for(TInt j=0; j<txtList.Count(); j++)
       
   355 				{
       
   356 				RBuf8 txt;
       
   357 				txt.CreateL(txtList[j]); 	
       
   358 				iMsgBuf->SetText(txt);
       
   359 				txt.Close();
       
   360 				}
       
   361 			}
       
   362 			break;  	     
       
   363 	    }	
       
   364 	}
       
   365 
       
   366 
       
   367 //Returns the size of the dns message 
       
   368 TUint16 CDnsMessageComposerParser::GetLength(const CDnsMessage& aMessage)const
       
   369     {
       
   370     return (aMessage.Size());
       
   371     }
       
   372