vpnengine/ikev2lib/src/ipsecselectors.cpp
changeset 0 33413c0669b9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vpnengine/ikev2lib/src/ipsecselectors.cpp	Thu Dec 17 09:14:51 2009 +0200
@@ -0,0 +1,585 @@
+/*
+* Copyright (c) 2003-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:   Ipsec Traffic Selector handling
+*
+*/
+
+#include <in_sock.h>
+#include <ipsecpolapi.h>
+#include "ikedebug.h"
+#include "ipsecselectors.h"
+#include "ikev2payloads.h"
+#include "ikev2pluginsession.h"
+#include "ikev2proposal.h"
+#include "ikemsgrec.h"
+#include "ikev2const.h"
+#include "ipsecproposal.h"
+#include "pfkeymsg.h"
+#include "ipsecsalist.h"
+#include "ikev2trafficselector.h"
+#include "ikev2acquire.h"
+#include <networking/pfkeyv2.h>
+
+CIkev2Acquire* IpsecSelectors::GetIpsecPolicyL(CIkev2PluginSession& aPluginSession, CIkev2Payloads* aIkeMsg, TInt aDhGroup)
+{
+    ASSERT(aIkeMsg);
+	//
+	// Examine is there available policy for Traffic selectors present
+	// in current CREATE_CHILD_SA request. Use Initiator traffic
+	// selector for policy check.
+    
+    //If there is no traffic selector, we stop the processing
+	TTSPayloadIkev2* TsIPl = aIkeMsg->iTsI;
+	if ( !TsIPl || (TsIPl->GetNumberOfTs() < 1) )
+	{	
+	   return NULL;
+	}   
+	
+    TTSPayloadIkev2* TsRPl = aIkeMsg->iTsR;
+    if ( !TsRPl || (TsRPl->GetNumberOfTs() < 1) )
+    {   
+       return NULL;
+    }   
+	
+    //Parse both selectors
+    CArrayFix<TIkeV2TrafficSelector>* proposedTsI = new (ELeave) CArrayFixFlat<TIkeV2TrafficSelector>(2);
+    CleanupStack::PushL(proposedTsI);
+    
+    CArrayFix<TIkeV2TrafficSelector>* proposedTsR = new (ELeave) CArrayFixFlat<TIkeV2TrafficSelector>(2);
+    CleanupStack::PushL(proposedTsR);
+
+    TInt i = 0;
+    const TTrafficSelector* sel = TTrafficSelector::Cast(TsIPl->TrafficSelectors());
+    for (i = 0; i < TsIPl->GetNumberOfTs(); ++i)
+        {
+        TPtrC8 selPtr(reinterpret_cast<const TUint8*>(sel), sel->Length());
+        TIkeV2TrafficSelector* selector = TIkeV2TrafficSelector::NewL(selPtr);
+        CleanupStack::PushL(selector);
+        proposedTsI->AppendL(*selector);
+        CleanupStack::PopAndDestroy(selector);
+        
+        sel = reinterpret_cast<const TTrafficSelector*>(reinterpret_cast<const TUint8*>(sel) + sel->Length()); 
+        }
+		
+    
+    i = 0;
+    sel = TTrafficSelector::Cast(TsRPl->TrafficSelectors());
+    for (i = 0; i < TsRPl->GetNumberOfTs(); ++i)
+        {
+        TPtrC8 selPtr(reinterpret_cast<const TUint8*>(sel), sel->Length());
+        TIkeV2TrafficSelector* selector = TIkeV2TrafficSelector::NewL(selPtr);
+        CleanupStack::PushL(selector);
+        proposedTsR->AppendL(*selector);
+        CleanupStack::PopAndDestroy(selector);
+        
+        sel = reinterpret_cast<const TTrafficSelector*>(reinterpret_cast<const TUint8*>(sel) + sel->Length()); 
+        }
+
+    __ASSERT_DEBUG(proposedTsI->Count() > 0, User::Invariant());
+    //The policy is retrieved by using the firts initiator selector.
+    TInetAddr mask = (*proposedTsI)[0].Mask();
+    
+    //Takes only the network part of the address
+    TInetAddr addr;    
+    addr.SetAddress((*proposedTsI)[0].StartingAddress().Address() & mask.Address());
+    addr.SetPort(0);
+    
+	TInetAddr DummyIp;
+	DummyIp.SetAddress(KInetAddrNone);   // 0.0.0.0
+	DummyIp.SetPort(0);
+	
+	CIpsecSaSpecList* SaList =  NULL;
+	TRAPD(err, SaList = aPluginSession.GetIPsecSaSpecListL(DummyIp, DummyIp, // No local address/port info
+                                                           addr, mask,       // for any peer address and port
+                                                           (*proposedTsI)[0].ProtocolId()));  // Protocol
+	
+	if (err != KErrNone)
+	    {
+	    CleanupStack::PopAndDestroy(proposedTsR);
+	    CleanupStack::PopAndDestroy(proposedTsI);	    	    
+	    
+	    return NULL;
+	    }
+	CleanupStack::PushL(SaList);
+	const TIpsecSaSpec& Spec = SaList->At(0);
+	
+	__ASSERT_DEBUG(SaList->Count() > 0, User::Invariant());	
+	HBufC8* Sa  = IpsecProposal::BuildIpsecSaFromPolicyL(*SaList, aDhGroup);
+		
+	CleanupStack::PushL(Sa);	
+	
+	CIkev2Acquire* Acquire = CIkev2Acquire::NewL(aPluginSession.GetSAId(), Sa, proposedTsI, proposedTsR);
+	
+	CleanupStack::Pop(Sa);    
+    CleanupStack::PushL(Acquire);
+	
+	TIpsecSALifetime hard(Spec.iHard.iAllocations, Spec.iHard.iBytes, Spec.iHard.iAddTime, Spec.iHard.iUseTime);
+    TIpsecSALifetime soft(Spec.iSoft.iAllocations, Spec.iSoft.iBytes, Spec.iSoft.iAddTime, Spec.iSoft.iUseTime);
+	Acquire->SetHardLifetime(hard);
+	Acquire->SetSoftLifetime(soft);
+	
+	//
+	// Set SrcSpecific information to correspond MOBIKE configuration.
+	// Actually SrcSpecific should be available in TIpsecSaSpec.
+	//
+	HBufC8* remoteId = NULL;
+    if ( Spec.iRemoteIdentity.Length() )
+    {
+       //
+       // Copy remote identity from policy and queue it to CIkev2Acquire
+       // object
+       //
+       remoteId = Spec.iRemoteIdentity.AllocL();
+       
+    }
+    else
+    {
+       remoteId = HBufC8::NewL(1);
+    }
+    Acquire->ReplaceRemoteId(remoteId);
+    
+    HBufC8* localId = NULL;
+    if ( Spec.iLocalIdentity.Length() )
+    {
+       //
+       // Copy remote identity from policy and queue it to CIkev2Acquire
+       // object
+       //
+       localId = Spec.iLocalIdentity.AllocL();
+       
+    }
+    else
+    {
+        localId = HBufC8::NewL(1);
+    }
+    Acquire->ReplaceLocalId(localId);
+    
+    CleanupStack::Pop(Acquire);
+    CleanupStack::PopAndDestroy(SaList);
+    CleanupStack::Pop(proposedTsR);
+    CleanupStack::Pop(proposedTsI);
+    
+ 	return Acquire;
+}
+
+CIkev2Acquire* IpsecSelectors::BuildVirtualAcquireL(CIkev2PluginSession& aPluginSession)
+{
+	//
+	// Build CIkev2Acquire object and related Ipsec SA- ja Traffic selector
+	// Payloads. These payload is used in conjunction with CP payload
+	// in IKE_AUTH exchange.  
+	// To get an Virtual Ip with CP payload we must also create (for
+	// some unintelligible reason) create an pair of Ipsec SA:s.
+	// The following actions are taken:
+	// -- Try first if the "all host" selector is available in
+	// current Ipsec policy and if it build Virtual acquire for full
+	// address range (0.0.0.0 - 255.255.255.255)
+	// -- If "all host" selector is not available, we going to use
+	// "UMA"  Ipsec ESP profiles as Ipsec SA proposal.
+	// The traffic selectors are set so that we asking Ipsec SA:s
+	// between requested Virtual Ip and Remote SGW Ip
+	// (single address all ports and protocols)
+	//
+	HBufC8* Sa = 0;
+	
+	TIpsecSALifetime hard(0,0,0,0);
+	TIpsecSALifetime soft(0,0,0,0);
+	
+	TInetAddr StartIp(KInetAddrNone, 0);    // 0.0.0.0
+	TInetAddr EndIp(KInetAddrAll, 0xFFFF);	      // 255.255.255.255	
+  
+    CIpsecSaSpecList* SaList = aPluginSession.GetIPsecSaSpecListL(StartIp, StartIp,     // for any local address and port
+                                                                  StartIp, StartIp,     // for any peer address and port
+                                                        	      0);  // Any protocol
+    CleanupStack::PushL(SaList);
+    __ASSERT_DEBUG(SaList->Count() > 0, User::Invariant());
+    
+   //
+   // Build Ipsec proposal for implicit SA negotiatited within IKE
+   // SA AUTH exchange
+   //
+	const TIpsecSaSpec& Spec = SaList->At(0);		   
+    Sa = IpsecProposal::BuildIpsecSaFromPolicyL(*SaList, 0); // 0 = DH Group
+    CleanupStack::PushL(Sa);
+    
+    CArrayFix<TIkeV2TrafficSelector>* TsI = new (ELeave) CArrayFixFlat<TIkeV2TrafficSelector>(1);
+    CleanupStack::PushL(TsI);
+    TIkeV2TrafficSelector selector(StartIp, EndIp, 0);
+    TsI->AppendL(selector);
+    
+    CArrayFix<TIkeV2TrafficSelector>* TsR = new (ELeave) CArrayFixFlat<TIkeV2TrafficSelector>(1);
+    CleanupStack::PushL(TsR);
+    selector = TIkeV2TrafficSelector(StartIp, EndIp, 0);
+    TsR->AppendL(selector);
+                
+    hard.iAllocations = Spec.iHard.iAllocations;
+    hard.iBytes = Spec.iHard.iBytes;
+    hard.iAddtime = Spec.iHard.iAddTime;
+    hard.iUsetime = Spec.iHard.iUseTime;
+    soft.iAllocations = Spec.iSoft.iAllocations;
+    soft.iBytes = Spec.iSoft.iBytes;
+    soft.iAddtime = Spec.iSoft.iAddTime;
+    soft.iUsetime = Spec.iSoft.iUseTime;
+
+	CIkev2Acquire* Acquire = CIkev2Acquire::NewL(aPluginSession.GetSAId(), Sa, TsI, TsR);
+	CleanupStack::Pop(TsR); 
+	CleanupStack::Pop(TsI); 
+	CleanupStack::Pop(Sa); 
+	
+	CleanupStack::PushL(Acquire);
+	HBufC8* identity = Spec.iRemoteIdentity.AllocL();
+	Acquire->ReplaceRemoteId(identity);    
+	identity = NULL;
+	
+	identity = Spec.iLocalIdentity.AllocL();
+	Acquire->ReplaceLocalId(identity);	
+	identity = NULL;
+		    
+	Acquire->SetVirtualIp();
+	Acquire->SetHardLifetime(hard);
+	Acquire->SetSoftLifetime(soft);
+		
+	CleanupStack::Pop(Acquire);
+	CleanupStack::PopAndDestroy(); // SaList
+	
+	return Acquire;			
+}
+
+TBool IpsecSelectors::VerifyTrafficSelectorsL(CIkev2Acquire* aAcquire, TTSPayloadIkev2* aTsI, TTSPayloadIkev2* aTsR )
+{
+    ASSERT(aAcquire);
+        
+    if (aTsI == NULL || aTsR == NULL)
+        {
+        return EFalse;
+        }
+    //
+	// Compare Traffic selectors CIkev2Acquire object to Traffic selectors
+	// received in CREATE_CHILD_SA response.
+	//
+    const CArrayFix<TIkeV2TrafficSelector>& TsI_Ref = aAcquire->TS_i();
+    const CArrayFix<TIkeV2TrafficSelector>& TsR_Ref = aAcquire->TS_r();
+    __ASSERT_DEBUG(TsI_Ref.Count() > 0 && TsR_Ref.Count() > 0, User::Invariant());
+    
+    //
+	// Check has the peer been narrowed requested Traffic selectors
+	//
+    CArrayFix<TIkeV2TrafficSelector>* TsI = new (ELeave)CArrayFixFlat<TIkeV2TrafficSelector>(2);
+    CleanupStack::PushL(TsI);
+    CArrayFix<TIkeV2TrafficSelector>* TsR = new (ELeave)CArrayFixFlat<TIkeV2TrafficSelector>(2);
+    CleanupStack::PushL(TsR);
+    	
+    TInt i = 0;
+    const TTrafficSelector* sel = TTrafficSelector::Cast(aTsI->TrafficSelectors());
+    const TUint8* payloadEnd = reinterpret_cast<TUint8*>(aTsI) + TPayloadIkev2::Cast(aTsI)->GetLength();
+    for (i = 0; i < aTsI->GetNumberOfTs(); ++i)
+        {
+        if (reinterpret_cast<const TUint8*>(sel) > payloadEnd || 
+            reinterpret_cast<const TUint8*>(sel) + sel->Length() > payloadEnd)
+            {
+            CleanupStack::PopAndDestroy(TsR);
+            CleanupStack::PopAndDestroy(TsI);
+            return EFalse;
+            }
+        
+        TPtrC8 selPtr(reinterpret_cast<const TUint8*>(sel), sel->Length());
+        TIkeV2TrafficSelector* selector = TIkeV2TrafficSelector::NewL(selPtr);
+        CleanupStack::PushL(selector);
+        TsI->AppendL(*selector);
+        CleanupStack::PopAndDestroy(selector);
+        
+        sel = reinterpret_cast<const TTrafficSelector*>(reinterpret_cast<const TUint8*>(sel) + sel->Length());
+        }
+
+	
+    sel = TTrafficSelector::Cast(aTsR->TrafficSelectors());
+    payloadEnd = reinterpret_cast<TUint8*>(aTsR) + TPayloadIkev2::Cast(aTsR)->GetLength();
+    for (i = 0; i < aTsR->GetNumberOfTs(); ++i)
+        {
+        if (reinterpret_cast<const TUint8*>(sel) > payloadEnd || 
+            reinterpret_cast<const TUint8*>(sel) + sel->Length() > payloadEnd)
+            {
+            CleanupStack::PopAndDestroy(TsR);
+            CleanupStack::PopAndDestroy(TsI);
+            return EFalse;
+            }
+        TPtrC8 selPtr(reinterpret_cast<const TUint8*>(sel), sel->Length());
+        TIkeV2TrafficSelector* selector = TIkeV2TrafficSelector::NewL(selPtr);
+        CleanupStack::PushL(selector);
+        TsR->AppendL(*selector);
+        CleanupStack::PopAndDestroy(selector);
+        
+        sel = reinterpret_cast<const TTrafficSelector*>(reinterpret_cast<const TUint8*>(sel) + sel->Length());
+        }    
+        
+    if ( !ValidataTs(TsI_Ref, *TsI) || 
+         !ValidataTs(TsR_Ref, *TsR) )
+        {
+        delete TsI;
+        delete TsR;        
+		return EFalse;
+        }
+    aAcquire->ReplaceTS_i(TsI);     
+    aAcquire->ReplaceTS_r(TsR);     
+
+    CleanupStack::Pop(TsR);
+    CleanupStack::Pop(TsI);
+    
+	return ETrue;
+}
+
+
+
+void IpsecSelectors::BuildTrafficSelectorsL(CIkev2Acquire* aAcquire, const TInetAddr& aLocalAddr,
+											const TPfkeyIdentity& aSrcIdent, const TPfkeyIdentity& aDstIdent,
+										    TUint8 aProtocol)
+{
+	//
+	// Build Traffic Selectors payload from PFKEY Acquire primitive
+	// Identity data
+	//
+    CArrayFix<TIkeV2TrafficSelector>* TsIBfr = NULL;
+    CArrayFix<TIkeV2TrafficSelector>* TsRBfr = NULL;
+	if ( aDstIdent.iExt && (aDstIdent.iExt->sadb_ident_type == SADB_IDENTTYPE_PREFIX))
+	{	
+		TsRBfr = new (ELeave) CArrayFixFlat<TIkeV2TrafficSelector>(1);
+		CleanupStack::PushL(TsRBfr);
+		if ( ( !aLocalAddr.IsUnspecified()) ||
+			 ( aSrcIdent.iExt && (aSrcIdent.iExt->sadb_ident_type == SADB_IDENTTYPE_PREFIX)))
+		{	
+			TsIBfr = new (ELeave) CArrayFixFlat<TIkeV2TrafficSelector>(1);
+			CleanupStack::PushL(TsIBfr);
+		}	
+	}
+
+	if ( TsIBfr )
+	{
+	    ASSERT(aAcquire);
+    	//
+	    // If local address pointer defined, local address is used as
+	    // initiator Traffic selector (single address "range")
+		// Else Use Source Identity data to build inititor Traffic selector
+	    //
+		if ( !aLocalAddr.IsUnspecified() )
+		{
+            TInetAddr startAddress = aLocalAddr;
+            startAddress.SetPort(0);
+            
+            TInetAddr endAddress = aLocalAddr;
+            endAddress.SetPort(0xffff);
+                        
+            TIkeV2TrafficSelector selector(startAddress, endAddress, aProtocol);
+            TsIBfr->AppendL(selector);
+		}	 
+		else
+		{
+            TIkeV2TrafficSelector selector = IpsecSelectors::IdentityToSelectorL(aSrcIdent.iData, aProtocol);
+            TsIBfr->AppendL(selector);
+            
+		}
+		CleanupStack::Pop(TsIBfr); 							
+		aAcquire->ReplaceTS_i(TsIBfr);
+	}	
+
+	if ( TsRBfr )
+	{	
+	    ASSERT(aAcquire);
+	   //
+	   // Build responder Traffic selector from destination Identity data
+	   //	   
+	   TIkeV2TrafficSelector selector = IpsecSelectors::IdentityToSelectorL(aDstIdent.iData, aProtocol);
+	   TsRBfr->AppendL(selector);
+	   CleanupStack::Pop(TsRBfr);  // TsRBfr									
+	   aAcquire->ReplaceTS_r(TsRBfr);
+	}   
+}
+
+
+TIkeV2TrafficSelector IpsecSelectors::IdentityToSelectorL(const TDesC8& aIdentity, TUint8 aProtocol)
+{
+	//
+	// Convert text format Identity data to Range start and end address
+	// needed into Traffic selector 
+	//
+	TInetAddr StartAddr;
+	TInetAddr EndAddr;
+	TInt Lth = aIdentity.Length();
+
+    if (aIdentity.Length() == 0)
+        {
+        User::Leave(KErrArgument);
+        }
+	
+    TInt offset = aIdentity.Find(_L8("/"));
+    switch (offset)
+    {
+        case KErrNotFound:  //Simple address
+        { 			
+            HBufC *unibuf = HBufC::NewL(aIdentity.Length());
+            unibuf->Des().Copy(aIdentity);
+            if ( StartAddr.Input(unibuf->Des()) != KErrNone )
+            {
+                delete unibuf;
+                User::Leave(KErrArgument);
+            }  
+            delete unibuf;
+            EndAddr = StartAddr;  // Range start and end addresses are same
+            break;
+        }
+
+        default:    //Subnet
+        {
+            //addr1 - Start address of range
+            TInt prefix_len;	 
+            HBufC *unibuf = HBufC::NewL(aIdentity.Length());
+            unibuf->Des().Copy(aIdentity);			
+            TPtrC addr_buf(unibuf->Ptr(), offset);
+            if ( StartAddr.Input(addr_buf) != KErrNone )
+            {
+                delete unibuf;				
+                User::Leave(KErrArgument);
+            }
+            TPtrC prefix_ptr(unibuf->Ptr() + offset + 1, unibuf->Length() - offset - 1);
+            //addr2 - End address of range
+            TLex lex(prefix_ptr);
+            if ( lex.Val(prefix_len) != KErrNone )
+            {
+               delete unibuf;
+               User::Leave(KErrArgument);
+            }
+            delete unibuf;
+            if ( !IpsecSelectors::GetRangeEndAddresses(StartAddr, EndAddr, prefix_len) )
+                User::Leave(KErrArgument);	
+        }
+
+    } //end switch
+    
+    StartAddr.SetPort(0x0);
+    EndAddr.SetPort(0xffff);
+    return TIkeV2TrafficSelector(StartAddr, EndAddr, aProtocol); 
+}
+
+TBool IpsecSelectors::GetRangeEndAddresses(TInetAddr& aStartAddr, TInetAddr& aEndAddr, TInt aPrefixLen) 
+{
+	//
+	// Convert start address / prefix length to range start address /
+	// end address pair
+	//
+	if ( aStartAddr.Family() == KAfInet )
+	{
+		TUint32 Mask;		
+		if ( aPrefixLen > 32 )	
+			return EFalse;
+		if ( aPrefixLen )
+			 Mask = (~0UL << ((32 - (aPrefixLen & 31)) & 31));			
+		else Mask = 0;
+        TUint32 Start = (aStartAddr.Address() & Mask);
+		TUint32 End   = Start | (~Mask);
+		aStartAddr.SetAddress(Start);
+		aEndAddr.SetAddress(End);						
+	}
+	else    //KAfInet6
+	{
+		if ( aPrefixLen > 128 )	
+			return EFalse;
+		aStartAddr.Prefix(aStartAddr, aPrefixLen); // For sure
+		TUint32 M  = (~0UL >> (aPrefixLen & 31));		
+		TIp6Addr S = aStartAddr.Ip6Address();
+		TIp6Addr E;
+		aPrefixLen >>= 5;
+		TInt i;		
+		for (i = 0; i < aPrefixLen; i++)
+			E.u.iAddr32[i] = S.u.iAddr32[i];
+
+		i <<= 2;
+		E.u.iAddr8[i] = (TUint8)(S.u.iAddr8[i] | (M >> 24)); i++;
+		E.u.iAddr8[i] = (TUint8)(S.u.iAddr8[i] | (M >> 16)); i++;
+		E.u.iAddr8[i] = (TUint8)(S.u.iAddr8[i] | (M >> 8)); i++;
+		E.u.iAddr8[i] = (TUint8)(S.u.iAddr8[i] |  M); i++;
+
+		i >>= 2;
+		while (i < 4)
+			E.u.iAddr32[i++] = ~0UL;
+		
+		aStartAddr.SetAddress(S);
+		aEndAddr.SetAddress(E);						
+	}
+
+	return ETrue;
+
+}
+
+			
+TBool IpsecSelectors::ValidataTs(const CArrayFix<TIkeV2TrafficSelector>& aTsRef, 
+                                 const CArrayFix<TIkeV2TrafficSelector>& aTs)
+{
+    //For every selector in aTs, there must be a same or wider selector in aTsRef.
+    for (TInt i = 0; i < aTs.Count(); ++i)
+        {        
+        TInt j;
+        const TIkeV2TrafficSelector& selector = aTs[i];
+        for (j = 0; j < aTsRef.Count(); ++j)
+            {
+            const TIkeV2TrafficSelector& refSelector = aTsRef[j];
+            if (selector <= refSelector)
+                {
+                break;
+                }
+            }
+        if (j == aTsRef.Count())
+            {
+            //No selector found
+            return EFalse;
+            }
+        }
+    return ETrue;    
+}	
+
+
+TBool IpsecSelectors::CheckPorts(TUint16 aStartRef, TUint16 aEndRef, TUint16 aStart, TUint16 aEnd )
+{
+	//
+	// Check that current port range narrowed intersection of reference
+	// port range
+	//
+	if ( (aStartRef > aStart) || (aEndRef < aEnd) || (aStart > aEnd) )
+		return EFalse;
+	
+	return ETrue;
+	
+}
+
+TBool IpsecSelectors::CheckAddresses(TUint8 aType, TUint8* aRefAddresses, TUint8* aAddresses )
+{
+	//
+	// Check that current address range narrowed intersection of reference
+	// address range
+	//
+	if ( aType == TS_IPV4_ADDR_RANGE )
+	{
+        ASSERT(aRefAddresses && aAddresses);
+
+	   //
+	   // Comparison is done as 32 bit integers
+	   //
+		TUint32 StartRef = GET32(aRefAddresses);
+		TUint32 EndRef   = GET32(aRefAddresses + 4);		
+		TUint32 Start    = GET32(aAddresses);
+		TUint32 End      = GET32(aAddresses + 4);
+		if ( (StartRef > Start) || (EndRef < End) || (Start > End) )
+			return EFalse;
+	}
+	
+	return ETrue;  
+}