vpnengine/ikev2lib/src/Ikev2Config.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: This class is used to handle IKEv2 configuration payload attributes.
       
    15 *
       
    16 */
       
    17 
       
    18 #include "ikedebug.h"
       
    19 #include "ikev2config.h"
       
    20 #include "ikev2payloads.h"
       
    21 #include "ikev2const.h"
       
    22 #include "internaladdress.h"
       
    23 #include "ipsecselectors.h"
       
    24 #include "ikev2acquire.h"
       
    25 #include "ikev2trafficselector.h"
       
    26 
       
    27 CIkev2Config* CIkev2Config::NewL(CIkev2Acquire* aAcquire, TInetAddr* aRemoteIp)
       
    28 {
       
    29 	CIkev2Config* Config = new (ELeave)CIkev2Config();
       
    30 	CleanupStack::PushL(Config);
       
    31 	Config->ConstructL(aAcquire, aRemoteIp);
       
    32 	CleanupStack::Pop(Config);		
       
    33 	return Config;
       
    34 }
       
    35 
       
    36 CIkev2Config::~CIkev2Config() 
       
    37     {
       
    38     delete iCp; 
       
    39     }
       
    40 
       
    41 
       
    42 TBool CIkev2Config::ProcessCpL(TCPPayloadIkev2* Cp)
       
    43 {
       
    44     ASSERT(Cp);
       
    45    //
       
    46    // Process received CP payload according to message type     
       
    47    // If CP request is going and reply received parse attributes to get
       
    48    // Virtual IP and possible DNS addresses. If INTERNAL_ADDRESS_EXPIRY
       
    49    // present save it into object too. (used as IKE SA lifetime).
       
    50    // If CP request received sanity check attributes (CFG_REPLY has
       
    51    // already been built on constructor ConstructL().
       
    52    // All other messages (CFG_SET and CFG_ACK) are silently discarded
       
    53    //
       
    54     TBool Status = EFalse;
       
    55 	
       
    56     if ( (Cp->GetCFGType() == CFG_REQUEST) || (Cp->GetCFGType() == CFG_REPLY) )
       
    57 	{
       
    58 		Status = ETrue;
       
    59 
       
    60 		TInt AttrLth;
       
    61 		TUint32   Ipv4Addr;
       
    62 		TIp6Addr  Ipv6Addr;    //IPV6 raw address
       
    63 		TDataAttributes* Attribute = Cp->Attributes();		
       
    64 		TInt Lth = (TInt)(TPayloadIkev2::Cast(Cp)->GetLength()) - TCPPayloadIkev2::Size();
       
    65 		
       
    66 		while ( Status && Lth )
       
    67 		{
       
    68 			AttrLth = (TInt)Attribute->GetValue();
       
    69 			switch ( Attribute->GetType() )
       
    70 			{
       
    71 				
       
    72 				case INTERNAL_IP4_ADDRESS:
       
    73 					if ( (AttrLth == 0) || (AttrLth == 4) )
       
    74 					{
       
    75 					   if (AttrLth == 4)
       
    76 					   {
       
    77 						  Ipv4Addr = GET32(Attribute->Data()); 
       
    78 						  iVIP.iVPNIfAddr.SetAddress(Ipv4Addr);
       
    79 					   }	   
       
    80 					}	
       
    81 					else Status = EFalse;	
       
    82 					break;
       
    83 
       
    84 				case INTERNAL_IP4_DNS:
       
    85 					if ( (AttrLth == 0) || (AttrLth == 4) )
       
    86 					{
       
    87 						if (AttrLth == 4)
       
    88 						{	
       
    89 						   Ipv4Addr = GET32(Attribute->Data());
       
    90 						   
       
    91 						   //Only two DNS server addresses supported
       
    92 						   if (iVIP.iVPNIfDNS1.IsUnspecified())
       
    93 						       {
       
    94 						       iVIP.iVPNIfDNS1.SetAddress(Ipv4Addr);
       
    95 						       }
       
    96 						   else if (iVIP.iVPNIfDNS2.IsUnspecified())
       
    97 						       {
       
    98 						       iVIP.iVPNIfDNS2.SetAddress(Ipv4Addr);
       
    99 						       }
       
   100 						}
       
   101 					}	
       
   102 					else Status = EFalse;	
       
   103 					break;
       
   104 
       
   105 				case INTERNAL_ADDRESS_EXPIRY:
       
   106 					if ( (AttrLth == 0) || (AttrLth == 4) )
       
   107 					{
       
   108 						if ( AttrLth == 4 )
       
   109 						{
       
   110 						   iAddressExpiry = GET32(Attribute->Data());
       
   111 						}	
       
   112 					}	
       
   113 					else Status = EFalse;	
       
   114 					break;
       
   115 					
       
   116 				case INTERNAL_IP6_ADDRESS:
       
   117 					if ( (AttrLth == 0) || (AttrLth == 16) )
       
   118 					{
       
   119 						if ( (AttrLth == 16))
       
   120 						{
       
   121 						   Mem::Copy(&Ipv6Addr.u.iAddr8, Attribute->Data(), sizeof(Ipv6Addr.u.iAddr8));
       
   122 						   iVIP.iVPNIfAddr.SetAddress(Ipv6Addr);
       
   123 						}	   
       
   124 					}	
       
   125 					else Status = EFalse;
       
   126 					break;
       
   127 					
       
   128 				default:
       
   129 					//
       
   130 					// All other parameters are just ignored
       
   131 					//
       
   132                     break;
       
   133 					
       
   134 			}
       
   135 
       
   136 			AttrLth += Attribute->Size();
       
   137 			if ( Lth < AttrLth )
       
   138 			{
       
   139 			   Status = EFalse;	
       
   140 			   break;  // Error
       
   141 			}	 
       
   142 			else Lth -= AttrLth;
       
   143 			
       
   144 			Attribute = Attribute->Next();			
       
   145 		
       
   146 		}
       
   147 		
       
   148 		if ( !Status &&  Cp->GetCFGType() != CFG_REPLY)
       
   149 		{
       
   150            delete iCp;
       
   151            iCp = NULL;
       
   152 		}	
       
   153 	}
       
   154 	
       
   155 	return Status;
       
   156 }
       
   157 
       
   158 void CIkev2Config::ConstructL(CIkev2Acquire* aAcquire, TInetAddr* aRemoteIp)
       
   159 {
       
   160     ASSERT(aAcquire);
       
   161    //
       
   162    // Build either Config Payload Request or Reply depending on 
       
   163    // CIkev2Acquire object "role".
       
   164    // If CIkev2Acquire is a request (=not response) build CFG_REQUEST 
       
   165    // If CIkev2Acquire is a response) build CFG_REPLY and replace initiator
       
   166    // Traffic selector in CIkev2Acquire with Traffic selector containing
       
   167    // "dummy"  Virtual IP address built from CIkev2Acquire ID.
       
   168    //
       
   169 	iCp = HBufC8::NewL(80);
       
   170 	TDataAttributes* Attributes = reinterpret_cast<TDataAttributes*>(const_cast<TUint8*>(iCp->Ptr()));
       
   171 	TInt AttrLth = 0;
       
   172 
       
   173     if ( !aAcquire->Response() )
       
   174 	{
       
   175         iCpType = CFG_REQUEST;
       
   176 		AttrLth += AddAttribute(Attributes, INTERNAL_IP4_ADDRESS, 0, NULL);
       
   177 		Attributes = Attributes->Next();
       
   178 		AttrLth += AddAttribute(Attributes, INTERNAL_IP4_DNS, 0, NULL);
       
   179 	}
       
   180 	else
       
   181 	{
       
   182 		//
       
   183 		// Build "dummy" virtual IPv4 
       
   184 		//
       
   185         iCpType = CFG_REPLY;
       
   186 		TUint32 virtualIp = aAcquire->Id();
       
   187 		if ( !aRemoteIp ||
       
   188 		     ((aRemoteIp->Family() == KAfInet6) && !aRemoteIp->IsV4Mapped() && !aRemoteIp->IsV4Compat()))
       
   189 		{
       
   190 		   //
       
   191 		   // "Dummy" virtual IPv4 is created from CIkev2Acquire object Id
       
   192 		   // data. The address format is the following: 10.x.y.z where bit 1 is always 0
       
   193 		   //
       
   194 		   virtualIp  = aAcquire->Id();
       
   195 		   virtualIp &= 0xfdfdfd;
       
   196 		   virtualIp |= 0x0a000000;
       
   197 		}
       
   198 		else
       
   199 		{
       
   200 		   //
       
   201 		   // "Dummy" virtual IPv4 is created from original peer
       
   202 		   // address as follows:
       
   203 		   // Original address: x.y.z.w ==> Virtual IP: 10.y.z.w
       
   204 		   // If original address: 10.y.z.w ==> Virtual IP: 172.y.z.w
       
   205 		   //
       
   206 			virtualIp = aRemoteIp->Address();
       
   207 			if ( (virtualIp & 0xff000000 ) != 0x0a000000)
       
   208 				 virtualIp = (virtualIp & 0xffffff) | 0x0a000000;
       
   209 			else virtualIp = (virtualIp & 0xffffff) | 0xac000000;			
       
   210 		}	
       
   211 		TInetAddr Ipv4Addr;
       
   212 		Ipv4Addr.SetAddress(virtualIp);
       
   213 		virtualIp = ByteOrder::Swap32(virtualIp);
       
   214 		AttrLth += AddAttribute(Attributes, INTERNAL_IP4_ADDRESS, 4, (TUint8*)&virtualIp);
       
   215 
       
   216 		//
       
   217 		// Replace original Initiator Traffic selector with new based
       
   218 		// on "virtualIp"
       
   219 		//
       
   220 		__ASSERT_DEBUG(aAcquire->TS_i().Count() > 0, User::Invariant());
       
   221 		TUint8 Protocol = aAcquire->TS_i()[0].ProtocolId();
       
   222 		
       
   223 		CArrayFix<TIkeV2TrafficSelector>* newSelectors = 
       
   224                             new (ELeave) CArrayFixFlat<TIkeV2TrafficSelector>(1);
       
   225 		CleanupStack::PushL(newSelectors);
       
   226 		TIkeV2TrafficSelector selector(Ipv4Addr, Ipv4Addr, Protocol);
       
   227 		newSelectors->AppendL(selector);
       
   228 		aAcquire->ReplaceTS_i(newSelectors);
       
   229 		CleanupStack::Pop(newSelectors);		
       
   230 	}	
       
   231     iCp->Des().SetLength(AttrLth);	
       
   232 }
       
   233 
       
   234 TInt CIkev2Config::AddAttribute(TDataAttributes* aAttr, TUint8 aType, TInt aLth, TUint8* aData)
       
   235 {
       
   236     ASSERT(aAttr);
       
   237     //
       
   238 	// Set R-Bit zero by adding attribute as variable length attribute 
       
   239 	//
       
   240 	aAttr->SetVariable();
       
   241 	aAttr->SetType(aType);	
       
   242 	aAttr->SetValue((TUint16)aLth);	
       
   243 	if ( aLth && aData )
       
   244 		Mem::Copy(aAttr->Data(), aData, aLth);
       
   245 
       
   246 	return (aLth + aAttr->Size());
       
   247 }
       
   248 
       
   249 TPtrC8 CIkev2Config::Cp() const 
       
   250     { 
       
   251     __ASSERT_DEBUG(iCp != NULL, User::Invariant());    
       
   252     return *iCp;
       
   253     }
       
   254 
       
   255 
       
   256 TUint8 CIkev2Config::CpType()const
       
   257     {
       
   258     return iCpType;
       
   259     }
       
   260 
       
   261 TUint32 CIkev2Config::ExpireTime() const 
       
   262     { 
       
   263     return iAddressExpiry;
       
   264     }
       
   265 
       
   266 
       
   267 TVPNAddress CIkev2Config::VirtualIp()
       
   268     {
       
   269     TVPNAddress Vip = iVIP;
       
   270     iVIP = TVPNAddress(); 
       
   271     return Vip;
       
   272     }
       
   273