vpnengine/ikev2lib/src/ipsecselectors.cpp
changeset 0 33413c0669b9
equal deleted inserted replaced
-1:000000000000 0:33413c0669b9
       
     1 /*
       
     2 * Copyright (c) 2003-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:   Ipsec Traffic Selector handling
       
    15 *
       
    16 */
       
    17 
       
    18 #include <in_sock.h>
       
    19 #include <ipsecpolapi.h>
       
    20 #include "ikedebug.h"
       
    21 #include "ipsecselectors.h"
       
    22 #include "ikev2payloads.h"
       
    23 #include "ikev2pluginsession.h"
       
    24 #include "ikev2proposal.h"
       
    25 #include "ikemsgrec.h"
       
    26 #include "ikev2const.h"
       
    27 #include "ipsecproposal.h"
       
    28 #include "pfkeymsg.h"
       
    29 #include "ipsecsalist.h"
       
    30 #include "ikev2trafficselector.h"
       
    31 #include "ikev2acquire.h"
       
    32 #include <networking/pfkeyv2.h>
       
    33 
       
    34 CIkev2Acquire* IpsecSelectors::GetIpsecPolicyL(CIkev2PluginSession& aPluginSession, CIkev2Payloads* aIkeMsg, TInt aDhGroup)
       
    35 {
       
    36     ASSERT(aIkeMsg);
       
    37 	//
       
    38 	// Examine is there available policy for Traffic selectors present
       
    39 	// in current CREATE_CHILD_SA request. Use Initiator traffic
       
    40 	// selector for policy check.
       
    41     
       
    42     //If there is no traffic selector, we stop the processing
       
    43 	TTSPayloadIkev2* TsIPl = aIkeMsg->iTsI;
       
    44 	if ( !TsIPl || (TsIPl->GetNumberOfTs() < 1) )
       
    45 	{	
       
    46 	   return NULL;
       
    47 	}   
       
    48 	
       
    49     TTSPayloadIkev2* TsRPl = aIkeMsg->iTsR;
       
    50     if ( !TsRPl || (TsRPl->GetNumberOfTs() < 1) )
       
    51     {   
       
    52        return NULL;
       
    53     }   
       
    54 	
       
    55     //Parse both selectors
       
    56     CArrayFix<TIkeV2TrafficSelector>* proposedTsI = new (ELeave) CArrayFixFlat<TIkeV2TrafficSelector>(2);
       
    57     CleanupStack::PushL(proposedTsI);
       
    58     
       
    59     CArrayFix<TIkeV2TrafficSelector>* proposedTsR = new (ELeave) CArrayFixFlat<TIkeV2TrafficSelector>(2);
       
    60     CleanupStack::PushL(proposedTsR);
       
    61 
       
    62     TInt i = 0;
       
    63     const TTrafficSelector* sel = TTrafficSelector::Cast(TsIPl->TrafficSelectors());
       
    64     for (i = 0; i < TsIPl->GetNumberOfTs(); ++i)
       
    65         {
       
    66         TPtrC8 selPtr(reinterpret_cast<const TUint8*>(sel), sel->Length());
       
    67         TIkeV2TrafficSelector* selector = TIkeV2TrafficSelector::NewL(selPtr);
       
    68         CleanupStack::PushL(selector);
       
    69         proposedTsI->AppendL(*selector);
       
    70         CleanupStack::PopAndDestroy(selector);
       
    71         
       
    72         sel = reinterpret_cast<const TTrafficSelector*>(reinterpret_cast<const TUint8*>(sel) + sel->Length()); 
       
    73         }
       
    74 		
       
    75     
       
    76     i = 0;
       
    77     sel = TTrafficSelector::Cast(TsRPl->TrafficSelectors());
       
    78     for (i = 0; i < TsRPl->GetNumberOfTs(); ++i)
       
    79         {
       
    80         TPtrC8 selPtr(reinterpret_cast<const TUint8*>(sel), sel->Length());
       
    81         TIkeV2TrafficSelector* selector = TIkeV2TrafficSelector::NewL(selPtr);
       
    82         CleanupStack::PushL(selector);
       
    83         proposedTsR->AppendL(*selector);
       
    84         CleanupStack::PopAndDestroy(selector);
       
    85         
       
    86         sel = reinterpret_cast<const TTrafficSelector*>(reinterpret_cast<const TUint8*>(sel) + sel->Length()); 
       
    87         }
       
    88 
       
    89     __ASSERT_DEBUG(proposedTsI->Count() > 0, User::Invariant());
       
    90     //The policy is retrieved by using the firts initiator selector.
       
    91     TInetAddr mask = (*proposedTsI)[0].Mask();
       
    92     
       
    93     //Takes only the network part of the address
       
    94     TInetAddr addr;    
       
    95     addr.SetAddress((*proposedTsI)[0].StartingAddress().Address() & mask.Address());
       
    96     addr.SetPort(0);
       
    97     
       
    98 	TInetAddr DummyIp;
       
    99 	DummyIp.SetAddress(KInetAddrNone);   // 0.0.0.0
       
   100 	DummyIp.SetPort(0);
       
   101 	
       
   102 	CIpsecSaSpecList* SaList =  NULL;
       
   103 	TRAPD(err, SaList = aPluginSession.GetIPsecSaSpecListL(DummyIp, DummyIp, // No local address/port info
       
   104                                                            addr, mask,       // for any peer address and port
       
   105                                                            (*proposedTsI)[0].ProtocolId()));  // Protocol
       
   106 	
       
   107 	if (err != KErrNone)
       
   108 	    {
       
   109 	    CleanupStack::PopAndDestroy(proposedTsR);
       
   110 	    CleanupStack::PopAndDestroy(proposedTsI);	    	    
       
   111 	    
       
   112 	    return NULL;
       
   113 	    }
       
   114 	CleanupStack::PushL(SaList);
       
   115 	const TIpsecSaSpec& Spec = SaList->At(0);
       
   116 	
       
   117 	__ASSERT_DEBUG(SaList->Count() > 0, User::Invariant());	
       
   118 	HBufC8* Sa  = IpsecProposal::BuildIpsecSaFromPolicyL(*SaList, aDhGroup);
       
   119 		
       
   120 	CleanupStack::PushL(Sa);	
       
   121 	
       
   122 	CIkev2Acquire* Acquire = CIkev2Acquire::NewL(aPluginSession.GetSAId(), Sa, proposedTsI, proposedTsR);
       
   123 	
       
   124 	CleanupStack::Pop(Sa);    
       
   125     CleanupStack::PushL(Acquire);
       
   126 	
       
   127 	TIpsecSALifetime hard(Spec.iHard.iAllocations, Spec.iHard.iBytes, Spec.iHard.iAddTime, Spec.iHard.iUseTime);
       
   128     TIpsecSALifetime soft(Spec.iSoft.iAllocations, Spec.iSoft.iBytes, Spec.iSoft.iAddTime, Spec.iSoft.iUseTime);
       
   129 	Acquire->SetHardLifetime(hard);
       
   130 	Acquire->SetSoftLifetime(soft);
       
   131 	
       
   132 	//
       
   133 	// Set SrcSpecific information to correspond MOBIKE configuration.
       
   134 	// Actually SrcSpecific should be available in TIpsecSaSpec.
       
   135 	//
       
   136 	HBufC8* remoteId = NULL;
       
   137     if ( Spec.iRemoteIdentity.Length() )
       
   138     {
       
   139        //
       
   140        // Copy remote identity from policy and queue it to CIkev2Acquire
       
   141        // object
       
   142        //
       
   143        remoteId = Spec.iRemoteIdentity.AllocL();
       
   144        
       
   145     }
       
   146     else
       
   147     {
       
   148        remoteId = HBufC8::NewL(1);
       
   149     }
       
   150     Acquire->ReplaceRemoteId(remoteId);
       
   151     
       
   152     HBufC8* localId = NULL;
       
   153     if ( Spec.iLocalIdentity.Length() )
       
   154     {
       
   155        //
       
   156        // Copy remote identity from policy and queue it to CIkev2Acquire
       
   157        // object
       
   158        //
       
   159        localId = Spec.iLocalIdentity.AllocL();
       
   160        
       
   161     }
       
   162     else
       
   163     {
       
   164         localId = HBufC8::NewL(1);
       
   165     }
       
   166     Acquire->ReplaceLocalId(localId);
       
   167     
       
   168     CleanupStack::Pop(Acquire);
       
   169     CleanupStack::PopAndDestroy(SaList);
       
   170     CleanupStack::Pop(proposedTsR);
       
   171     CleanupStack::Pop(proposedTsI);
       
   172     
       
   173  	return Acquire;
       
   174 }
       
   175 
       
   176 CIkev2Acquire* IpsecSelectors::BuildVirtualAcquireL(CIkev2PluginSession& aPluginSession)
       
   177 {
       
   178 	//
       
   179 	// Build CIkev2Acquire object and related Ipsec SA- ja Traffic selector
       
   180 	// Payloads. These payload is used in conjunction with CP payload
       
   181 	// in IKE_AUTH exchange.  
       
   182 	// To get an Virtual Ip with CP payload we must also create (for
       
   183 	// some unintelligible reason) create an pair of Ipsec SA:s.
       
   184 	// The following actions are taken:
       
   185 	// -- Try first if the "all host" selector is available in
       
   186 	// current Ipsec policy and if it build Virtual acquire for full
       
   187 	// address range (0.0.0.0 - 255.255.255.255)
       
   188 	// -- If "all host" selector is not available, we going to use
       
   189 	// "UMA"  Ipsec ESP profiles as Ipsec SA proposal.
       
   190 	// The traffic selectors are set so that we asking Ipsec SA:s
       
   191 	// between requested Virtual Ip and Remote SGW Ip
       
   192 	// (single address all ports and protocols)
       
   193 	//
       
   194 	HBufC8* Sa = 0;
       
   195 	
       
   196 	TIpsecSALifetime hard(0,0,0,0);
       
   197 	TIpsecSALifetime soft(0,0,0,0);
       
   198 	
       
   199 	TInetAddr StartIp(KInetAddrNone, 0);    // 0.0.0.0
       
   200 	TInetAddr EndIp(KInetAddrAll, 0xFFFF);	      // 255.255.255.255	
       
   201   
       
   202     CIpsecSaSpecList* SaList = aPluginSession.GetIPsecSaSpecListL(StartIp, StartIp,     // for any local address and port
       
   203                                                                   StartIp, StartIp,     // for any peer address and port
       
   204                                                         	      0);  // Any protocol
       
   205     CleanupStack::PushL(SaList);
       
   206     __ASSERT_DEBUG(SaList->Count() > 0, User::Invariant());
       
   207     
       
   208    //
       
   209    // Build Ipsec proposal for implicit SA negotiatited within IKE
       
   210    // SA AUTH exchange
       
   211    //
       
   212 	const TIpsecSaSpec& Spec = SaList->At(0);		   
       
   213     Sa = IpsecProposal::BuildIpsecSaFromPolicyL(*SaList, 0); // 0 = DH Group
       
   214     CleanupStack::PushL(Sa);
       
   215     
       
   216     CArrayFix<TIkeV2TrafficSelector>* TsI = new (ELeave) CArrayFixFlat<TIkeV2TrafficSelector>(1);
       
   217     CleanupStack::PushL(TsI);
       
   218     TIkeV2TrafficSelector selector(StartIp, EndIp, 0);
       
   219     TsI->AppendL(selector);
       
   220     
       
   221     CArrayFix<TIkeV2TrafficSelector>* TsR = new (ELeave) CArrayFixFlat<TIkeV2TrafficSelector>(1);
       
   222     CleanupStack::PushL(TsR);
       
   223     selector = TIkeV2TrafficSelector(StartIp, EndIp, 0);
       
   224     TsR->AppendL(selector);
       
   225                 
       
   226     hard.iAllocations = Spec.iHard.iAllocations;
       
   227     hard.iBytes = Spec.iHard.iBytes;
       
   228     hard.iAddtime = Spec.iHard.iAddTime;
       
   229     hard.iUsetime = Spec.iHard.iUseTime;
       
   230     soft.iAllocations = Spec.iSoft.iAllocations;
       
   231     soft.iBytes = Spec.iSoft.iBytes;
       
   232     soft.iAddtime = Spec.iSoft.iAddTime;
       
   233     soft.iUsetime = Spec.iSoft.iUseTime;
       
   234 
       
   235 	CIkev2Acquire* Acquire = CIkev2Acquire::NewL(aPluginSession.GetSAId(), Sa, TsI, TsR);
       
   236 	CleanupStack::Pop(TsR); 
       
   237 	CleanupStack::Pop(TsI); 
       
   238 	CleanupStack::Pop(Sa); 
       
   239 	
       
   240 	CleanupStack::PushL(Acquire);
       
   241 	HBufC8* identity = Spec.iRemoteIdentity.AllocL();
       
   242 	Acquire->ReplaceRemoteId(identity);    
       
   243 	identity = NULL;
       
   244 	
       
   245 	identity = Spec.iLocalIdentity.AllocL();
       
   246 	Acquire->ReplaceLocalId(identity);	
       
   247 	identity = NULL;
       
   248 		    
       
   249 	Acquire->SetVirtualIp();
       
   250 	Acquire->SetHardLifetime(hard);
       
   251 	Acquire->SetSoftLifetime(soft);
       
   252 		
       
   253 	CleanupStack::Pop(Acquire);
       
   254 	CleanupStack::PopAndDestroy(); // SaList
       
   255 	
       
   256 	return Acquire;			
       
   257 }
       
   258 
       
   259 TBool IpsecSelectors::VerifyTrafficSelectorsL(CIkev2Acquire* aAcquire, TTSPayloadIkev2* aTsI, TTSPayloadIkev2* aTsR )
       
   260 {
       
   261     ASSERT(aAcquire);
       
   262         
       
   263     if (aTsI == NULL || aTsR == NULL)
       
   264         {
       
   265         return EFalse;
       
   266         }
       
   267     //
       
   268 	// Compare Traffic selectors CIkev2Acquire object to Traffic selectors
       
   269 	// received in CREATE_CHILD_SA response.
       
   270 	//
       
   271     const CArrayFix<TIkeV2TrafficSelector>& TsI_Ref = aAcquire->TS_i();
       
   272     const CArrayFix<TIkeV2TrafficSelector>& TsR_Ref = aAcquire->TS_r();
       
   273     __ASSERT_DEBUG(TsI_Ref.Count() > 0 && TsR_Ref.Count() > 0, User::Invariant());
       
   274     
       
   275     //
       
   276 	// Check has the peer been narrowed requested Traffic selectors
       
   277 	//
       
   278     CArrayFix<TIkeV2TrafficSelector>* TsI = new (ELeave)CArrayFixFlat<TIkeV2TrafficSelector>(2);
       
   279     CleanupStack::PushL(TsI);
       
   280     CArrayFix<TIkeV2TrafficSelector>* TsR = new (ELeave)CArrayFixFlat<TIkeV2TrafficSelector>(2);
       
   281     CleanupStack::PushL(TsR);
       
   282     	
       
   283     TInt i = 0;
       
   284     const TTrafficSelector* sel = TTrafficSelector::Cast(aTsI->TrafficSelectors());
       
   285     const TUint8* payloadEnd = reinterpret_cast<TUint8*>(aTsI) + TPayloadIkev2::Cast(aTsI)->GetLength();
       
   286     for (i = 0; i < aTsI->GetNumberOfTs(); ++i)
       
   287         {
       
   288         if (reinterpret_cast<const TUint8*>(sel) > payloadEnd || 
       
   289             reinterpret_cast<const TUint8*>(sel) + sel->Length() > payloadEnd)
       
   290             {
       
   291             CleanupStack::PopAndDestroy(TsR);
       
   292             CleanupStack::PopAndDestroy(TsI);
       
   293             return EFalse;
       
   294             }
       
   295         
       
   296         TPtrC8 selPtr(reinterpret_cast<const TUint8*>(sel), sel->Length());
       
   297         TIkeV2TrafficSelector* selector = TIkeV2TrafficSelector::NewL(selPtr);
       
   298         CleanupStack::PushL(selector);
       
   299         TsI->AppendL(*selector);
       
   300         CleanupStack::PopAndDestroy(selector);
       
   301         
       
   302         sel = reinterpret_cast<const TTrafficSelector*>(reinterpret_cast<const TUint8*>(sel) + sel->Length());
       
   303         }
       
   304 
       
   305 	
       
   306     sel = TTrafficSelector::Cast(aTsR->TrafficSelectors());
       
   307     payloadEnd = reinterpret_cast<TUint8*>(aTsR) + TPayloadIkev2::Cast(aTsR)->GetLength();
       
   308     for (i = 0; i < aTsR->GetNumberOfTs(); ++i)
       
   309         {
       
   310         if (reinterpret_cast<const TUint8*>(sel) > payloadEnd || 
       
   311             reinterpret_cast<const TUint8*>(sel) + sel->Length() > payloadEnd)
       
   312             {
       
   313             CleanupStack::PopAndDestroy(TsR);
       
   314             CleanupStack::PopAndDestroy(TsI);
       
   315             return EFalse;
       
   316             }
       
   317         TPtrC8 selPtr(reinterpret_cast<const TUint8*>(sel), sel->Length());
       
   318         TIkeV2TrafficSelector* selector = TIkeV2TrafficSelector::NewL(selPtr);
       
   319         CleanupStack::PushL(selector);
       
   320         TsR->AppendL(*selector);
       
   321         CleanupStack::PopAndDestroy(selector);
       
   322         
       
   323         sel = reinterpret_cast<const TTrafficSelector*>(reinterpret_cast<const TUint8*>(sel) + sel->Length());
       
   324         }    
       
   325         
       
   326     if ( !ValidataTs(TsI_Ref, *TsI) || 
       
   327          !ValidataTs(TsR_Ref, *TsR) )
       
   328         {
       
   329         delete TsI;
       
   330         delete TsR;        
       
   331 		return EFalse;
       
   332         }
       
   333     aAcquire->ReplaceTS_i(TsI);     
       
   334     aAcquire->ReplaceTS_r(TsR);     
       
   335 
       
   336     CleanupStack::Pop(TsR);
       
   337     CleanupStack::Pop(TsI);
       
   338     
       
   339 	return ETrue;
       
   340 }
       
   341 
       
   342 
       
   343 
       
   344 void IpsecSelectors::BuildTrafficSelectorsL(CIkev2Acquire* aAcquire, const TInetAddr& aLocalAddr,
       
   345 											const TPfkeyIdentity& aSrcIdent, const TPfkeyIdentity& aDstIdent,
       
   346 										    TUint8 aProtocol)
       
   347 {
       
   348 	//
       
   349 	// Build Traffic Selectors payload from PFKEY Acquire primitive
       
   350 	// Identity data
       
   351 	//
       
   352     CArrayFix<TIkeV2TrafficSelector>* TsIBfr = NULL;
       
   353     CArrayFix<TIkeV2TrafficSelector>* TsRBfr = NULL;
       
   354 	if ( aDstIdent.iExt && (aDstIdent.iExt->sadb_ident_type == SADB_IDENTTYPE_PREFIX))
       
   355 	{	
       
   356 		TsRBfr = new (ELeave) CArrayFixFlat<TIkeV2TrafficSelector>(1);
       
   357 		CleanupStack::PushL(TsRBfr);
       
   358 		if ( ( !aLocalAddr.IsUnspecified()) ||
       
   359 			 ( aSrcIdent.iExt && (aSrcIdent.iExt->sadb_ident_type == SADB_IDENTTYPE_PREFIX)))
       
   360 		{	
       
   361 			TsIBfr = new (ELeave) CArrayFixFlat<TIkeV2TrafficSelector>(1);
       
   362 			CleanupStack::PushL(TsIBfr);
       
   363 		}	
       
   364 	}
       
   365 
       
   366 	if ( TsIBfr )
       
   367 	{
       
   368 	    ASSERT(aAcquire);
       
   369     	//
       
   370 	    // If local address pointer defined, local address is used as
       
   371 	    // initiator Traffic selector (single address "range")
       
   372 		// Else Use Source Identity data to build inititor Traffic selector
       
   373 	    //
       
   374 		if ( !aLocalAddr.IsUnspecified() )
       
   375 		{
       
   376             TInetAddr startAddress = aLocalAddr;
       
   377             startAddress.SetPort(0);
       
   378             
       
   379             TInetAddr endAddress = aLocalAddr;
       
   380             endAddress.SetPort(0xffff);
       
   381                         
       
   382             TIkeV2TrafficSelector selector(startAddress, endAddress, aProtocol);
       
   383             TsIBfr->AppendL(selector);
       
   384 		}	 
       
   385 		else
       
   386 		{
       
   387             TIkeV2TrafficSelector selector = IpsecSelectors::IdentityToSelectorL(aSrcIdent.iData, aProtocol);
       
   388             TsIBfr->AppendL(selector);
       
   389             
       
   390 		}
       
   391 		CleanupStack::Pop(TsIBfr); 							
       
   392 		aAcquire->ReplaceTS_i(TsIBfr);
       
   393 	}	
       
   394 
       
   395 	if ( TsRBfr )
       
   396 	{	
       
   397 	    ASSERT(aAcquire);
       
   398 	   //
       
   399 	   // Build responder Traffic selector from destination Identity data
       
   400 	   //	   
       
   401 	   TIkeV2TrafficSelector selector = IpsecSelectors::IdentityToSelectorL(aDstIdent.iData, aProtocol);
       
   402 	   TsRBfr->AppendL(selector);
       
   403 	   CleanupStack::Pop(TsRBfr);  // TsRBfr									
       
   404 	   aAcquire->ReplaceTS_r(TsRBfr);
       
   405 	}   
       
   406 }
       
   407 
       
   408 
       
   409 TIkeV2TrafficSelector IpsecSelectors::IdentityToSelectorL(const TDesC8& aIdentity, TUint8 aProtocol)
       
   410 {
       
   411 	//
       
   412 	// Convert text format Identity data to Range start and end address
       
   413 	// needed into Traffic selector 
       
   414 	//
       
   415 	TInetAddr StartAddr;
       
   416 	TInetAddr EndAddr;
       
   417 	TInt Lth = aIdentity.Length();
       
   418 
       
   419     if (aIdentity.Length() == 0)
       
   420         {
       
   421         User::Leave(KErrArgument);
       
   422         }
       
   423 	
       
   424     TInt offset = aIdentity.Find(_L8("/"));
       
   425     switch (offset)
       
   426     {
       
   427         case KErrNotFound:  //Simple address
       
   428         { 			
       
   429             HBufC *unibuf = HBufC::NewL(aIdentity.Length());
       
   430             unibuf->Des().Copy(aIdentity);
       
   431             if ( StartAddr.Input(unibuf->Des()) != KErrNone )
       
   432             {
       
   433                 delete unibuf;
       
   434                 User::Leave(KErrArgument);
       
   435             }  
       
   436             delete unibuf;
       
   437             EndAddr = StartAddr;  // Range start and end addresses are same
       
   438             break;
       
   439         }
       
   440 
       
   441         default:    //Subnet
       
   442         {
       
   443             //addr1 - Start address of range
       
   444             TInt prefix_len;	 
       
   445             HBufC *unibuf = HBufC::NewL(aIdentity.Length());
       
   446             unibuf->Des().Copy(aIdentity);			
       
   447             TPtrC addr_buf(unibuf->Ptr(), offset);
       
   448             if ( StartAddr.Input(addr_buf) != KErrNone )
       
   449             {
       
   450                 delete unibuf;				
       
   451                 User::Leave(KErrArgument);
       
   452             }
       
   453             TPtrC prefix_ptr(unibuf->Ptr() + offset + 1, unibuf->Length() - offset - 1);
       
   454             //addr2 - End address of range
       
   455             TLex lex(prefix_ptr);
       
   456             if ( lex.Val(prefix_len) != KErrNone )
       
   457             {
       
   458                delete unibuf;
       
   459                User::Leave(KErrArgument);
       
   460             }
       
   461             delete unibuf;
       
   462             if ( !IpsecSelectors::GetRangeEndAddresses(StartAddr, EndAddr, prefix_len) )
       
   463                 User::Leave(KErrArgument);	
       
   464         }
       
   465 
       
   466     } //end switch
       
   467     
       
   468     StartAddr.SetPort(0x0);
       
   469     EndAddr.SetPort(0xffff);
       
   470     return TIkeV2TrafficSelector(StartAddr, EndAddr, aProtocol); 
       
   471 }
       
   472 
       
   473 TBool IpsecSelectors::GetRangeEndAddresses(TInetAddr& aStartAddr, TInetAddr& aEndAddr, TInt aPrefixLen) 
       
   474 {
       
   475 	//
       
   476 	// Convert start address / prefix length to range start address /
       
   477 	// end address pair
       
   478 	//
       
   479 	if ( aStartAddr.Family() == KAfInet )
       
   480 	{
       
   481 		TUint32 Mask;		
       
   482 		if ( aPrefixLen > 32 )	
       
   483 			return EFalse;
       
   484 		if ( aPrefixLen )
       
   485 			 Mask = (~0UL << ((32 - (aPrefixLen & 31)) & 31));			
       
   486 		else Mask = 0;
       
   487         TUint32 Start = (aStartAddr.Address() & Mask);
       
   488 		TUint32 End   = Start | (~Mask);
       
   489 		aStartAddr.SetAddress(Start);
       
   490 		aEndAddr.SetAddress(End);						
       
   491 	}
       
   492 	else    //KAfInet6
       
   493 	{
       
   494 		if ( aPrefixLen > 128 )	
       
   495 			return EFalse;
       
   496 		aStartAddr.Prefix(aStartAddr, aPrefixLen); // For sure
       
   497 		TUint32 M  = (~0UL >> (aPrefixLen & 31));		
       
   498 		TIp6Addr S = aStartAddr.Ip6Address();
       
   499 		TIp6Addr E;
       
   500 		aPrefixLen >>= 5;
       
   501 		TInt i;		
       
   502 		for (i = 0; i < aPrefixLen; i++)
       
   503 			E.u.iAddr32[i] = S.u.iAddr32[i];
       
   504 
       
   505 		i <<= 2;
       
   506 		E.u.iAddr8[i] = (TUint8)(S.u.iAddr8[i] | (M >> 24)); i++;
       
   507 		E.u.iAddr8[i] = (TUint8)(S.u.iAddr8[i] | (M >> 16)); i++;
       
   508 		E.u.iAddr8[i] = (TUint8)(S.u.iAddr8[i] | (M >> 8)); i++;
       
   509 		E.u.iAddr8[i] = (TUint8)(S.u.iAddr8[i] |  M); i++;
       
   510 
       
   511 		i >>= 2;
       
   512 		while (i < 4)
       
   513 			E.u.iAddr32[i++] = ~0UL;
       
   514 		
       
   515 		aStartAddr.SetAddress(S);
       
   516 		aEndAddr.SetAddress(E);						
       
   517 	}
       
   518 
       
   519 	return ETrue;
       
   520 
       
   521 }
       
   522 
       
   523 			
       
   524 TBool IpsecSelectors::ValidataTs(const CArrayFix<TIkeV2TrafficSelector>& aTsRef, 
       
   525                                  const CArrayFix<TIkeV2TrafficSelector>& aTs)
       
   526 {
       
   527     //For every selector in aTs, there must be a same or wider selector in aTsRef.
       
   528     for (TInt i = 0; i < aTs.Count(); ++i)
       
   529         {        
       
   530         TInt j;
       
   531         const TIkeV2TrafficSelector& selector = aTs[i];
       
   532         for (j = 0; j < aTsRef.Count(); ++j)
       
   533             {
       
   534             const TIkeV2TrafficSelector& refSelector = aTsRef[j];
       
   535             if (selector <= refSelector)
       
   536                 {
       
   537                 break;
       
   538                 }
       
   539             }
       
   540         if (j == aTsRef.Count())
       
   541             {
       
   542             //No selector found
       
   543             return EFalse;
       
   544             }
       
   545         }
       
   546     return ETrue;    
       
   547 }	
       
   548 
       
   549 
       
   550 TBool IpsecSelectors::CheckPorts(TUint16 aStartRef, TUint16 aEndRef, TUint16 aStart, TUint16 aEnd )
       
   551 {
       
   552 	//
       
   553 	// Check that current port range narrowed intersection of reference
       
   554 	// port range
       
   555 	//
       
   556 	if ( (aStartRef > aStart) || (aEndRef < aEnd) || (aStart > aEnd) )
       
   557 		return EFalse;
       
   558 	
       
   559 	return ETrue;
       
   560 	
       
   561 }
       
   562 
       
   563 TBool IpsecSelectors::CheckAddresses(TUint8 aType, TUint8* aRefAddresses, TUint8* aAddresses )
       
   564 {
       
   565 	//
       
   566 	// Check that current address range narrowed intersection of reference
       
   567 	// address range
       
   568 	//
       
   569 	if ( aType == TS_IPV4_ADDR_RANGE )
       
   570 	{
       
   571         ASSERT(aRefAddresses && aAddresses);
       
   572 
       
   573 	   //
       
   574 	   // Comparison is done as 32 bit integers
       
   575 	   //
       
   576 		TUint32 StartRef = GET32(aRefAddresses);
       
   577 		TUint32 EndRef   = GET32(aRefAddresses + 4);		
       
   578 		TUint32 Start    = GET32(aAddresses);
       
   579 		TUint32 End      = GET32(aAddresses + 4);
       
   580 		if ( (StartRef > Start) || (EndRef < End) || (Start > End) )
       
   581 			return EFalse;
       
   582 	}
       
   583 	
       
   584 	return ETrue;  
       
   585 }