tcpiputils/dhcp/src/DHCPIP6StateMachine.cpp
changeset 0 af10295192d8
child 53 7e41d162e158
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Implements the DHCP IP6 statemachine helper functions
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file DHCPIP6StateMachine.cpp
       
    20  @internalTechnology
       
    21 */
       
    22 
       
    23 #include "DHCPIP6States.h"
       
    24 #include "DhcpIP6MsgRcvr.h"
       
    25 #include "DHCPServer.h"
       
    26 
       
    27 #ifdef _DEBUG
       
    28 #include <e32property.h>
       
    29 #endif
       
    30 
       
    31 using namespace DHCPv6;
       
    32 
       
    33 CDHCPIP6StateMachine::~CDHCPIP6StateMachine()
       
    34 /**
       
    35   * Destructor of the If base class
       
    36   *
       
    37   * @internalTechnology
       
    38   *
       
    39   */
       
    40 	{
       
    41 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::~CDHCPIP6StateMachine")));
       
    42    delete iMessageReader;
       
    43    iServerId.Close();
       
    44 	}
       
    45 
       
    46 #ifdef SYMBIAN_NETWORKING_ADDRESS_PROVISION
       
    47 CDHCPIP6StateMachine* CDHCPIP6StateMachine::NewL(RSocketServ& aEsock, RConnection& aConnection, const TName& aInterfaceName, CDhcpHwAddrManager* aDhcpHwAddrManager)
       
    48 /**
       
    49   * Creates a new instance of this class
       
    50   *
       
    51   * @internalTechnology
       
    52   *
       
    53   */
       
    54 	{
       
    55 	CDHCPIP6StateMachine* stateMachine = new (ELeave) CDHCPIP6StateMachine(aEsock, aConnection, aInterfaceName, aDhcpHwAddrManager);
       
    56 	CleanupStack::PushL(stateMachine);
       
    57 	stateMachine->ConstructL();
       
    58 	CleanupStack::Pop(stateMachine);
       
    59 	return stateMachine;
       
    60 	}
       
    61 #else
       
    62 CDHCPIP6StateMachine* CDHCPIP6StateMachine::NewL(RSocketServ& aEsock, RConnection& aConnection, const TName& aInterfaceName)
       
    63 /**
       
    64   * Creates a new instance of this class
       
    65   *
       
    66   * @internalTechnology
       
    67   *
       
    68   */
       
    69 	{
       
    70 	CDHCPIP6StateMachine* stateMachine = new (ELeave) CDHCPIP6StateMachine(aEsock, aConnection, aInterfaceName);
       
    71 	CleanupStack::PushL(stateMachine);
       
    72 	stateMachine->ConstructL();
       
    73 	CleanupStack::Pop(stateMachine);
       
    74 	return stateMachine;
       
    75 	}
       
    76 #endif //SYMBIAN_NETWORKING_ADDRESS_PROVISION
       
    77 void CDHCPIP6StateMachine::ConstructL()
       
    78 /**
       
    79   * Creates socket and connections for the object
       
    80   *
       
    81   *
       
    82   *	@internalTechnology
       
    83   *
       
    84   */
       
    85 	{
       
    86    CDHCPStateMachine::ConstructL();
       
    87 
       
    88 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::ConstructL")));
       
    89 	
       
    90   	ReAllocL(KDhcpInitMsgSizeIP6);
       
    91   	iDhcpMessage = new(ELeave)CDHCPMessageHeaderIP6(iFragment);
       
    92 	iMessageReader = new(ELeave)CDhcpIP6MessageReader( *this );
       
    93 	iMessageSender = new(ELeave)CDHCPIP6MessageSender(this,iSocket,&iTaskStartedAt,KAfInet6);
       
    94 	}
       
    95 
       
    96 void CDHCPIP6StateMachine::GetServerAddress( TInetAddr& aAddress )
       
    97 {
       
    98 	iInterfaceConfigInfo.GetServerAddress( aAddress );
       
    99 }
       
   100 
       
   101 void CDHCPIP6StateMachine::SetCurrentAddress(const TInetAddr& aCurrentAddress, const TInetAddr& /*aSubnetMask*/)
       
   102    {
       
   103    CDHCPStateMachine::SetCurrentAddress( aCurrentAddress );
       
   104    }
       
   105 
       
   106 void CDHCPIP6StateMachine::StartInitL(MStateMachineNotify* aStateMachineNotify, EInitialisationContext aInitialisationContext, TInt aUserTimeOut )
       
   107 /**
       
   108   * StartInitL
       
   109   *
       
   110   * This function is called to start the IP address solicitation state machine
       
   111   * we don't support rapid commit option for now
       
   112   *
       
   113   * @internalTechnology
       
   114   */
       
   115 	{
       
   116 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::StartSolicitationL")));
       
   117 	ASSERT(!iFirstState);//the states should be deleted by now or we are starting off
       
   118 	
       
   119 	SetIdle( EFalse );
       
   120 	iInterfaceConfigInfo.Reset();
       
   121 
       
   122 #ifdef SYMBIAN_ESOCK_V3
       
   123 	if ( aInitialisationContext == CDHCPStateMachine::EFirstCall )
       
   124 		{
       
   125 		iFirstState = new(ELeave) CDHCPIP6ListenToNeighbor(*this);
       
   126 		}
       
   127 	else
       
   128 #else
       
   129 	(void)aInitialisationContext;
       
   130 #endif
       
   131 		{
       
   132 		iFirstState = new(ELeave) CDHCPIP6Solicit(*this, aUserTimeOut);
       
   133 		CDHCPState* state1 = new(ELeave)CDHCPIP6Select(*this);
       
   134 		iFirstState->SetNext( state1 );
       
   135 		CDHCPState* state2 = new(ELeave) CDHCPIP6Request(*this);
       
   136 		state1->SetNext( state2 );
       
   137 		state2->SetNext( new(ELeave) CDHCPIP6WaitForDAD(*this) );
       
   138 
       
   139 		if (iStartInitCalls == CDHCPStateMachine::EFirstCall)
       
   140 			{
       
   141 			//This is the first time we're going to wait for a DCHP server. 
       
   142 			//If there is no server it we will complete the client after one attempt 
       
   143 			iStartInitCalls = aInitialisationContext;
       
   144 			static_cast<CDHCPIP6Select*>(state1)->SetMaxRetryCount(1);
       
   145 			}
       
   146 		else
       
   147 			{
       
   148 			//We never found a DCHP server the first time, but this time try harder.
       
   149 			static_cast<CDHCPIP6Select*>(state1)->SetMaxRetryCount(INT_MAX);
       
   150 			}
       
   151 		}
       
   152 
       
   153 	CDHCPStateMachine::Start(aStateMachineNotify);
       
   154 	}
       
   155 #ifdef SYMBIAN_TCPIPDHCP_UPDATE
       
   156 void CDHCPIP6StateMachine::StartInformL(MStateMachineNotify* aStateMachineNotify)
       
   157 /**
       
   158   * This function is called to send inform message if options are not 
       
   159   * found in iValidMsg buffer
       
   160   *
       
   161   * @internalTechnology
       
   162   */
       
   163 	{
       
   164 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::StartInformL Dynamic Inform Request")));
       
   165 	ASSERT(!iFirstState);
       
   166 	iFirstState = new(ELeave) CDHCPIP6InformRequest(*this);
       
   167 	CDHCPState* request = new(ELeave) CDHCPIP6Request(*this);
       
   168 	iFirstState->SetNext( request );
       
   169 	CDHCPStateMachine::Start(aStateMachineNotify);
       
   170 	}
       
   171 #endif //SYMBIAN_TCPIPDHCP_UPDATE
       
   172 void CDHCPIP6StateMachine::StartInformL(MStateMachineNotify* aStateMachineNotify, TBool /*aStaticAddress*/)
       
   173 /**
       
   174   * StartInformL
       
   175   *
       
   176   * This function is called to start the inform for state-less configuration
       
   177   *
       
   178   * @internalTechnology
       
   179   */
       
   180 	{
       
   181 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::EInformRequest")));
       
   182 	ASSERT(!iFirstState); //the states should be deleted by now or we are starting off
       
   183 
       
   184     if (!iServerId.Length())
       
   185         {
       
   186 	    iInterfaceConfigInfo.Reset();
       
   187         }
       
   188 
       
   189 	iFirstState = new(ELeave) CDHCPIP6InformRequest(*this);
       
   190    CDHCPState* state1 = new(ELeave) CDHCPIP6Request(*this);
       
   191    iFirstState->SetNext( state1 );
       
   192 	//static address is set but no wait for DAD here
       
   193 	
       
   194 	CDHCPStateMachine::Start(aStateMachineNotify);
       
   195 	iCfgInfoOnly = ETrue;
       
   196 	}
       
   197 
       
   198 #ifdef SYMBIAN_NETWORKING_DHCPSERVER
       
   199 
       
   200 void CDHCPIP6StateMachine::CreateOfferMsgL()
       
   201 	{
       
   202 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::CreateOfferMsgL")));	
       
   203 	}
       
   204 	
       
   205 void CDHCPIP6StateMachine::HandleRequestMsgL()//CreateRequestResponseMsgL()
       
   206 	{
       
   207 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::CreateRequestResponseMsgL")));	
       
   208 	}
       
   209 	
       
   210 void CDHCPIP6StateMachine::HandleInformMsgL()
       
   211 	{
       
   212 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::HandleInformMsgL")));		
       
   213 	}	
       
   214 
       
   215 void CDHCPIP6StateMachine::PrepareToSendServerMsgL( CDHCPStateMachine::EAddressType /*aEAddressType*/)
       
   216 /**
       
   217   * PrepareToSendL
       
   218   *
       
   219   * This function is called to set the correct destination address
       
   220   * for messages before they are sent.
       
   221   *
       
   222   * @internalTechnology
       
   223   */	
       
   224 	{
       
   225 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::PrepareToSendL")));
       
   226 	DhcpMessage()->Dump();
       
   227 	iMessageSender->Cancel();
       
   228 	}
       
   229 
       
   230 void CDHCPIP6StateMachine::CloseNSendServerMsgL(TRequestStatus& /*aStatus*/, CDHCPStateMachine::EAddressType /*aEAddressType*/)
       
   231 	{
       
   232 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::CloseNSendServerMsgL")));			
       
   233 	}
       
   234 
       
   235 CDHCPState* CDHCPIP6StateMachine::ReceiveOnPort67L( TRequestStatus* aStatus )
       
   236 	{
       
   237 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::ReceiveOn67")));
       
   238 	
       
   239 	iDhcpMessage->InitialiseL();
       
   240    	iMessageReader->SetNext( iActiveEvent );
       
   241    	ASSERT( iReceiving == EFalse );
       
   242    	iReceiving = ETrue;
       
   243    	return static_cast<CDHCPState*>(iMessageReader->ProcessL( *aStatus ));
       
   244 	}
       
   245 
       
   246 void CDHCPIP6StateMachine::InitialiseServerSocketL()
       
   247 	{
       
   248 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::InitialiseServerSocketL")));	
       
   249 	}	
       
   250 
       
   251 #endif // SYMBIAN_NETWORKING_DHCPSERVER
       
   252 
       
   253 void CDHCPIP6StateMachine::StartRebootL(MStateMachineNotify* aStateMachineNotify)
       
   254 /**
       
   255   * StartRebootL
       
   256   *
       
   257   * This function is called to start the confirm request state machine
       
   258   * used when trying to start using a previously assigned address still
       
   259   * with valid lease.
       
   260   *
       
   261   * @internalTechnology
       
   262   */
       
   263 	{
       
   264 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::StartConfirmL")));
       
   265 	ASSERT(!iFirstState);//the states should be deleted by now or we are starting off
       
   266 
       
   267    iFirstState = new(ELeave) CDHCPIP6Confirm(*this);
       
   268    CDHCPState* state1 = new(ELeave) CDHCPIP6Request(*this);
       
   269    iFirstState->SetNext( state1 );
       
   270    state1->SetNext( new(ELeave) CDHCPIP6WaitForDAD(*this) );
       
   271 
       
   272 	CDHCPStateMachine::Start(aStateMachineNotify);
       
   273 	}
       
   274 
       
   275 void CDHCPIP6StateMachine::StartRenewL(MStateMachineNotify* aStateMachineNotify,TInt aUserTimeOut)
       
   276    {
       
   277 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::StartRenewL")));
       
   278 	ASSERT(!iFirstState);
       
   279 
       
   280    iUserRebindTimeout = aUserTimeOut;
       
   281    iFirstState = new(ELeave) CDHCPIP6Renew(*this,aUserTimeOut);
       
   282    iFirstState->SetNext( new(ELeave) CDHCPIP6WaitForDAD(*this) );
       
   283 
       
   284 	CDHCPStateMachine::Start(aStateMachineNotify);	
       
   285    }
       
   286 
       
   287 void CDHCPIP6StateMachine::StartRebindL(MStateMachineNotify* aStateMachineNotify)
       
   288 /**
       
   289   * StartRebindL
       
   290   *
       
   291   * This function is called to start the rebind state machine
       
   292   *
       
   293   * @internalTechnology
       
   294   */	
       
   295 	{
       
   296 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::StartRebindL")));
       
   297 	ASSERT(!iFirstState);//the states should be deleted by now or we are starting off
       
   298 	
       
   299 	iFirstState = new(ELeave) CDHCPIP6Rebind(*this,iUserRebindTimeout);
       
   300    iFirstState->SetNext( new(ELeave) CDHCPIP6WaitForDAD(*this) );
       
   301 
       
   302 	CDHCPStateMachine::Start(aStateMachineNotify);
       
   303 	}
       
   304 
       
   305 void CDHCPIP6StateMachine::StartReconfigureL(MStateMachineNotify* aStateMachineNotify)
       
   306 /**
       
   307   * StartReconfigureL
       
   308   *
       
   309   * This function is called to initialise waiting for the server reconfigure message.
       
   310   * The task ends once a valid reconfigure messageg's been received
       
   311   *
       
   312   * @internalTechnology
       
   313   */
       
   314 {
       
   315 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::StartReconfigureL")));
       
   316 
       
   317 	ASSERT(!iFirstState);//the states should be deleted by now or we are starting off
       
   318 	
       
   319 	iXid.SetXid( 0 );
       
   320 	iFirstState = new(ELeave) CDHCPIP6Reconfigure(*this);
       
   321 
       
   322 	CDHCPStateMachine::Start(aStateMachineNotify);
       
   323 }
       
   324 
       
   325 void CDHCPIP6StateMachine::StartDeclineL(MStateMachineNotify* aStateMachineNotify)
       
   326 /**
       
   327   * StartDeclineL
       
   328   *
       
   329   * This function is called to start the decline task
       
   330   *
       
   331   * @internalTechnology
       
   332   */
       
   333 	{
       
   334 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::StartDeclineL")));
       
   335 	ASSERT(!iFirstState);//the states should be deleted by now or we are starting off
       
   336 	
       
   337 	if ( iInterfaceConfigInfo.AnyAddressToDecline() )
       
   338 		{
       
   339 		iFirstState = new(ELeave) CDHCPIP6Decline(*this);
       
   340    	iFirstState->SetNext( new CDHCPIP6ReplyNoBinding(*this) );	
       
   341 		}
       
   342   	CDHCPStateMachine::Start(aStateMachineNotify);
       
   343 	}
       
   344 
       
   345 void CDHCPIP6StateMachine::StartReleaseL(MStateMachineNotify* aStateMachineNotify)
       
   346 /**
       
   347   * StartReleaseL
       
   348   *
       
   349   * This function is called to start the release state machine
       
   350   *
       
   351   * @internalTechnology
       
   352   */
       
   353 	{
       
   354 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::StartReleaseL")));
       
   355 	ASSERT(!iFirstState);//the states should be deleted by now or we are starting off
       
   356 	
       
   357 	iFirstState = new(ELeave) CDHCPIP6Release(*this);
       
   358    iFirstState->SetNext( new(ELeave)CDHCPIP6ReplyNoBinding(*this) );	
       
   359 	
       
   360 	CDHCPStateMachine::Start(aStateMachineNotify);
       
   361 	}
       
   362 
       
   363 void CDHCPIP6StateMachine::PrepareToSendL( CDHCPStateMachine::EAddressType /*aEAddressType*/ )
       
   364 /**
       
   365   * PrepareToSendL
       
   366   *
       
   367   * This function is called to set the correct destination address
       
   368   * for messages before they are sent.
       
   369   *
       
   370   * @internalTechnology
       
   371   */	
       
   372 	{
       
   373 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::PrepareToSendL")));
       
   374 	DhcpMessage()->Dump();
       
   375 	iMessageSender->Cancel();
       
   376 	}
       
   377 
       
   378 void CDHCPIP6StateMachine::CloseNSendMsgL(TRequestStatus& /*aStatus*/, CDHCPStateMachine::EAddressType aEAddressType)
       
   379 /**
       
   380   * Handles sending of packets for this object
       
   381   *
       
   382   * @internalTechnology
       
   383   *
       
   384   */
       
   385 	{
       
   386 	CDHCPStateMachine::CloseNSendMsgL(0,KInfinity,aEAddressType); //IPv6 calculates its own delay and retry values..so KInfinity is ignored
       
   387 	}
       
   388 
       
   389 void CDHCPIP6StateMachine::CancelMessageReceiver()
       
   390    {//doesn't cancel statemachine only the reader state
       
   391    if ( IsActive() && iReceiving )
       
   392       {
       
   393       ASSERT( !iErrorEvent );
       
   394    	CStateMachine::Cancel(KErrNone);//waits for the cancel to complete
       
   395       iActiveEvent = iMessageReader->Next();
       
   396       iReceiving = EFalse;
       
   397       //restart the state machine
       
   398       CStateMachine::Start(NULL, NULL, iStateMachineNotify);
       
   399       }
       
   400    }
       
   401 
       
   402 CDHCPState* CDHCPIP6StateMachine::ReceiveL(TRequestStatus* aStatus)
       
   403 /**
       
   404   * Starts iMessageReader state
       
   405   *
       
   406   * @internalTechnology
       
   407   *
       
   408   */
       
   409 	{
       
   410 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::Receive")));
       
   411 	
       
   412 	iDhcpMessage->InitialiseL();
       
   413    iMessageReader->SetNext( iActiveEvent );
       
   414    ASSERT( iReceiving == EFalse );
       
   415    iReceiving = ETrue;
       
   416    return static_cast<CDHCPState*>(iMessageReader->ProcessL( *aStatus ));
       
   417 	}
       
   418 
       
   419 void CDHCPIP6StateMachine::OnCompletion()
       
   420 {
       
   421    if (LastError() == KErrEof && iReceiving)
       
   422       {//end of datagram while reading a message => not an error => restart state machine
       
   423       iActiveEvent = iMessageReader->Next();
       
   424       
       
   425       CStateMachine::Start(NULL, NULL, iStateMachineNotify); //sets last error to KErrNone
       
   426       }
       
   427    else
       
   428       {
       
   429       CDHCPStateMachine::OnCompletion();
       
   430       }
       
   431 }
       
   432 
       
   433 void CDHCPIP6StateMachine::AssembleClientIDsL()
       
   434 /**
       
   435   * Sets the client id - hardware address and type pair
       
   436   * 
       
   437   *
       
   438   */
       
   439 	{
       
   440    /*client id and the way we generate it
       
   441      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       
   442     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   443     |               3               |    hardware type (16 bits)    |
       
   444     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   445     .                                                               .
       
   446     .             link-layer address (variable length)              .
       
   447     .                                                               .
       
   448     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   449    */
       
   450 	FetchHWAddress();
       
   451 
       
   452 	TUint htype = 0;
       
   453 	if(iHardwareAddr.Family() != KAFUnspec)
       
   454 		{
       
   455 		iClientId.CreateL(KDuidTypeLen + KDuidHardwareTypeLen + iHardwareAddr.Length() - KHwAddrOffset);
       
   456 		htype = iHardwareAddr.Family();		// should this be Port() ?
       
   457 		}
       
   458 	else 
       
   459 		{
       
   460     	// This means we're on a point-to-point link (i.e. one with no hardware addressing).
       
   461     	//  We'll make client id look like an ethernet/mac address combo to reduce the chance of stupid servers getting upset
       
   462 		__CFLOG_VAR((KLogSubSysDHCP, KLogCode,
       
   463 						_L8("CDHCPIP6StateMachine::AssembleClientIDsL - no hardware address (suggesting point-to-point)"
       
   464 						     " so generating a random 6 byte client id")));
       
   465 		iClientId.CreateL(KDuidTypeLen + KDuidHardwareTypeLen + KDuidEthMacAddrSize);
       
   466 		htype = 1;		// fake up as Ethernet
       
   467 		}
       
   468 		
       
   469 	TBigEndian::SetValue(const_cast<TUint8*>(iClientId.Ptr()), KDuidTypeLen, KDuidLLTypeCode);	
       
   470 	TBigEndian::SetValue(const_cast<TUint8*>(iClientId.Ptr()) + KDuidTypeLen, KDuidHardwareTypeLen, htype);
       
   471 	iClientId.SetLength(KDuidTypeLen + KDuidHardwareTypeLen);
       
   472 	
       
   473 	if(iHardwareAddr.Family()!=KAFUnspec)
       
   474 		{
       
   475 	    iClientId.Append(iHardwareAddr.Mid(KHwAddrOffset, iHardwareAddr.Length() - KHwAddrOffset));
       
   476 		}
       
   477 	else 
       
   478 		{
       
   479 		// Note: if you increase the number of bytes appended here, then be sure to
       
   480 		// increase the size passed to iClientId.CreateL() above.
       
   481     	TUint32 data = Math::Random();
       
   482 		iClientId.Append(TPckgC<TUint32>(data));
       
   483 		iClientId.Append(TPckgC<TUint16>(data));
       
   484 		}
       
   485 	}
       
   486 
       
   487 TUint CDHCPIP6StateMachine::GetMessageType() const
       
   488 /**
       
   489   * Parses the message and returns the message type from the DHCP message
       
   490   * i.e. whether the message is an advertise. reply, reconfigure
       
   491   *
       
   492   * @internalTechnology 
       
   493   */
       
   494 	{
       
   495 	CDHCPMessageHeaderIP6* v6Msg = DhcpMessage();
       
   496 	if ( v6Msg->Parse(iXid,iClientId,iServerId) == KErrNone )
       
   497       {
       
   498 	   v6Msg->Dump();	
       
   499    	return v6Msg->GetMessageType();
       
   500       }
       
   501    return EUnknown;
       
   502 	}
       
   503 
       
   504 void CDHCPIP6StateMachine::SetMessageHeaderL( TMessageType aMsgType )
       
   505 /**
       
   506   * Sets the message header
       
   507   *
       
   508   * @internalTechnology
       
   509   */
       
   510 	{
       
   511 	iXid.Init6(); //generate random transaction Id
       
   512 	iTaskStartedAt.HomeTime();	// set time stamp to now
       
   513 	CDHCPMessageHeaderIP6* v6Msg = DhcpMessage();
       
   514 	v6Msg->InitialiseL();
       
   515 	v6Msg->SetXid(iXid.Xid());
       
   516 	v6Msg->SetMessageType(static_cast<TUint8>(aMsgType));
       
   517 	
       
   518 	// +++++++++++++++++++++++ Elapsed Time +++++++++++++++++++++++++++++++++++++++++/	
       
   519 	//EElapsedTime option MUST be the first option in the option part of the message
       
   520 	//see CDHCPIP6MessageSender::SendingContinues fn
       
   521    v6Msg->AddOptionL(EElapsedTime, KElapsedTimeOptionLen)->SetBigEndian( 0 );
       
   522 	// +++++++++++++++++++++++ Client Id +++++++++++++++++++++++++++++++++++++++++/	
       
   523 	v6Msg->AddOptionL(EClientId, iClientId.Length())->GetBodyDes().Copy(iClientId);
       
   524 	// +++++++++++++++++++++++ Server ID +++++++++++++++++++++++++++++++++++++++++/
       
   525    //included only when it exists
       
   526    if ( iServerId.Length() )
       
   527       {
       
   528       v6Msg->AddOptionL(EServerId, iServerId.Length())->GetBodyDes().Copy(iServerId);
       
   529       }
       
   530 	}
       
   531 
       
   532 void CDHCPIP6StateMachine::CreateDiscoverMsgL()
       
   533 /**
       
   534   * Puts the specifics of the solicit message into
       
   535   * the message buffer
       
   536   *
       
   537   * @internalTechnology
       
   538   */
       
   539 	{
       
   540 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::CreateDiscoverMsgL")));
       
   541 	
       
   542 	iServerId.Close();
       
   543 	//initiate message header
       
   544 	SetMessageHeaderL(ESolicit);
       
   545 	
       
   546 	CDHCPMessageHeaderIP6* v6Msg = DhcpMessage();
       
   547 
       
   548 	// +++++++++++++++++++++++ IA_NA/TA options+++++++++++++++++++++++++++++++++++/
       
   549 	iInterfaceConfigInfo.AppendIAOptionsL(*v6Msg, ESolicit);
       
   550 	
       
   551 	// +++++++++++++++++++++++ reconfiguration accept ++++++++++++++++++++++++++++/
       
   552 #if defined(DHCP_RECONFIGURE_NO_AUTHENTICATION)
       
   553 	v6Msg->AddOptionL(EReconfAccept, 0);
       
   554 #endif
       
   555 
       
   556 	// +++++++++++++++++++++++ append requested options list +++++++++++++++++++++/
       
   557 	static_cast<CDHCPOptionRequestOption*>(v6Msg->AddOptionL( EOro, KDHCPOptionRequestLen ))->AppendRequestedOptions();
       
   558 	}
       
   559 
       
   560 void CDHCPIP6StateMachine::CreateOfferAcceptanceRequestMsgL()
       
   561 /**
       
   562   * Puts the specifics of the request
       
   563   * message into the message buffer
       
   564   *
       
   565   * @internalTechnology
       
   566   */
       
   567 	{
       
   568 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::CreateOfferAcceptanceRequestMsgL")));
       
   569 	
       
   570 	SetMessageHeaderL( ERequest );
       
   571 	CDHCPMessageHeaderIP6* v6Msg = DhcpMessage();
       
   572 	
       
   573 	// +++++++++++++++++++++++ IA_NA/TA options+++++++++++++++++++++++++++++++++++/
       
   574    iInterfaceConfigInfo.AppendIAOptionsL( *v6Msg, ERequest );
       
   575 	// +++++++++++++++++++++++ reconfiguration accept ++++++++++++++++++++++++++++/
       
   576 #if defined(DHCP_RECONFIGURE_NO_AUTHENTICATION)
       
   577    v6Msg->AddOptionL(EReconfAccept, 0);
       
   578 #endif
       
   579 	// +++++++++++++++++++++++ append requested options list +++++++++++++++++++++/
       
   580    static_cast<CDHCPOptionRequestOption*>(v6Msg->AddOptionL( EOro, KDHCPOptionRequestLen ))->AppendRequestedOptions();
       
   581    
       
   582 	}
       
   583 
       
   584 void CDHCPIP6StateMachine::CreateRebootRequestMsgL()
       
   585 /**
       
   586   * Puts the specifics of a confirm specific after reboot or other means of 
       
   587   * changing the interface into the message buffer 
       
   588   *
       
   589   * @internalTechnology
       
   590   */
       
   591 	{
       
   592 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::CreateRebootRequestMsgL")));
       
   593 	
       
   594 	iServerId.Close();
       
   595 	SetMessageHeaderL( EConfirm );
       
   596 	CDHCPMessageHeaderIP6* v6Msg = DhcpMessage();
       
   597 	
       
   598 	// +++++++++++++++++++++++ IA_NA/TA options+++++++++++++++++++++++++++++++++++/
       
   599    iInterfaceConfigInfo.AppendIAOptionsL( *v6Msg, EConfirm );
       
   600 	// +++++++++++++++++++++++ IA_TA +++++++++++++++++++++++++++++++++++++++++++++/
       
   601    //iInterfaceConfigInfo.Init6ialiseNA_Option( *v6Msg->AddOptionL( EIaTa, KDHCPOptionIA_TATInitLength ) );
       
   602 	// +++++++++++++++++++++++ append requested options list +++++++++++++++++++++/
       
   603    static_cast<CDHCPOptionRequestOption*>(v6Msg->AddOptionL( EOro, KDHCPOptionRequestLen ))->AppendRequestedOptions();
       
   604    
       
   605 	}
       
   606 
       
   607 void CDHCPIP6StateMachine::CreateInformMsgL()
       
   608 /**
       
   609   * Puts the specifics of an inform-request message
       
   610   * into the message buffer
       
   611   *
       
   612   * @internalTechnology
       
   613   */
       
   614 	{
       
   615 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::CreateInformMsgL")));
       
   616 	 
       
   617 	SetMessageHeaderL( EInformationRequest );
       
   618 	CDHCPMessageHeaderIP6* v6Msg = DhcpMessage();
       
   619 #ifdef SYMBIAN_TCPIPDHCP_UPDATE	
       
   620 	//This is used for multiple parameter option request 
       
   621 	if (iSavedExtraParameters.Ptr())
       
   622 		{
       
   623 		TUint8 requestedOptions[KDHCPOptionRequestLen] = {0,EServerId, 0,EIaNa, 0,ESipServerD, 0,ESipServerA,
       
   624 																0,EDNSServers, 0,EDomainList};
       
   625 
       
   626 		TPtr8 ptr(requestedOptions, KDHCPOptionRequestLen, KDHCPOptionRequestLen );
       
   627 		
       
   628 		RBuf8 appendOpCodeList;
       
   629 		appendOpCodeList.CreateL(ptr);
       
   630 		TInt oplength = appendOpCodeList.Length();
       
   631 		//get the no of opcode to be fetched
       
   632 		TInt optLen= iSavedExtraParameters.Length();
       
   633 		//Reallocate the opcodelist with the new opcodes(example if the client requests 
       
   634 		//for 2options in the multiple opcode then the new memory will be allocated for 2 opcodes(2*2= 4 as it is 16bit))
       
   635 		appendOpCodeList.ReAllocL(KDHCPOptionRequestLen+(optLen*2));
       
   636 		for (TUint8 i=1;i<=optLen;i++)
       
   637 			{
       
   638 			//append null at the begining of the opcode always
       
   639 			appendOpCodeList.Append(TChar::EAlphaGroup);
       
   640 			//get the opcode number and append at the end
       
   641 			TPtr8 ptrs= iSavedExtraParameters.RightTPtr(i);
       
   642 			appendOpCodeList.Append(ptrs.Ptr(),1);
       
   643 			}
       
   644 		//add the required opcodes in the addoption 
       
   645 		static_cast<CDHCPOptionRequestOption*>(v6Msg->AddOptionL(EOro, appendOpCodeList.Length()))->GetBodyDes().Copy(appendOpCodeList);
       
   646 		appendOpCodeList.Close();
       
   647 		}
       
   648 #endif //SYMBIAN_TCPIPDHCP_UPDATE		
       
   649 	// +++++++++++++++++++++++ append requested options list +++++++++++++++++++++/
       
   650    static_cast<CDHCPOptionRequestOption*>(v6Msg->AddOptionL( EOro, KDHCPOptionRequestLen ))->AppendRequestedOptions();
       
   651 	}
       
   652 
       
   653 void CDHCPIP6StateMachine::CreateRenewRequestMsgL()
       
   654 /**
       
   655   * Puts the specifics of the renew message
       
   656   * into the mesage buffer
       
   657   *
       
   658   * @internalTechnology
       
   659   */
       
   660 	{
       
   661 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::CreateRenewRequestMsgL")));
       
   662 	
       
   663 	SetMessageHeaderL( ERenew );
       
   664 	CDHCPMessageHeaderIP6* v6Msg = DhcpMessage();
       
   665 	
       
   666 	// +++++++++++++++++++++++ IA_NA/TA options+++++++++++++++++++++++++++++++++++/
       
   667    iInterfaceConfigInfo.AppendIAOptionsL( *v6Msg, ERenew );
       
   668 	// +++++++++++++++++++++++ IA_TA +++++++++++++++++++++++++++++++++++++++++++++/
       
   669    //iInterfaceConfigInfo.Init6ialiseNA_Option( *v6Msg->AddOptionL( EIaTa, KDHCPOptionIA_TATInitLength ) );
       
   670 	// +++++++++++++++++++++++ append requested options list +++++++++++++++++++++/
       
   671 	
       
   672    static_cast<CDHCPOptionRequestOption*>(v6Msg->AddOptionL( EOro, KDHCPOptionRequestLen ))->AppendRequestedOptions();
       
   673 	}	
       
   674 
       
   675 void CDHCPIP6StateMachine::CreateRebindRequestMsgL()
       
   676 /**
       
   677   * Puts the specifics of the rebind message
       
   678   * into the message buffer
       
   679   * 
       
   680   * @internalTechnology
       
   681   */
       
   682    {
       
   683 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::CreateRebindRequestMsgL")));
       
   684 	
       
   685 	SetMessageHeaderL( ERebind );
       
   686 	CDHCPMessageHeaderIP6* v6Msg = DhcpMessage();
       
   687 	
       
   688 	iInterfaceConfigInfo.ResetUseUnicast();
       
   689 	
       
   690 	// +++++++++++++++++++++++ IA_NA/TA options+++++++++++++++++++++++++++++++++++/
       
   691    iInterfaceConfigInfo.AppendIAOptionsL( *v6Msg, ERebind );
       
   692 	// +++++++++++++++++++++++ IA_TA +++++++++++++++++++++++++++++++++++++++++++++/
       
   693    //iInterfaceConfigInfo.Init6ialiseNA_Option( *v6Msg->AddOptionL( EIaTa, KDHCPOptionIA_TATInitLength ) );
       
   694 	// +++++++++++++++++++++++ append requested options list +++++++++++++++++++++/
       
   695    static_cast<CDHCPOptionRequestOption*>(v6Msg->AddOptionL( EOro, KDHCPOptionRequestLen ))->AppendRequestedOptions();
       
   696    }
       
   697 
       
   698 void CDHCPIP6StateMachine::CreateReleaseMsgL()
       
   699 /**
       
   700   * Puts the specifics of the release message
       
   701   * into the message buffer
       
   702   * 
       
   703   * @internalTechnology
       
   704   */
       
   705 	{
       
   706 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::CreateReleaseMsgL")));
       
   707 	
       
   708 	SetMessageHeaderL( DHCPv6::ERelease );
       
   709 	CDHCPMessageHeaderIP6* v6Msg = DhcpMessage();
       
   710 
       
   711 	iInterfaceConfigInfo.SetAddressStatus( DHCPv6::KAddrIndexAll, DHCPv6::EMarkForRelease );
       
   712     
       
   713 	// +++++++++++++++++++++++ IA_NA/TA options+++++++++++++++++++++++++++++++++++/
       
   714    iInterfaceConfigInfo.AppendIAOptionsL( *v6Msg, DHCPv6::ERelease );
       
   715 
       
   716     RemoveConfiguredAddress();
       
   717 	}
       
   718 
       
   719 void CDHCPIP6StateMachine::CreateDeclineMsgL()
       
   720 /**
       
   721   * Puts the specifics of the decline message
       
   722   * into the message buffer
       
   723   *
       
   724   * @internalTechnology
       
   725   */
       
   726 	{
       
   727 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::CreateDeclineMsgL")));
       
   728 	
       
   729 	SetMessageHeaderL( EDecline );
       
   730 	CDHCPMessageHeaderIP6* v6Msg = DhcpMessage();
       
   731 
       
   732 	// +++++++++++++++++++++++ IA_NA/TA options+++++++++++++++++++++++++++++++++++/
       
   733    iInterfaceConfigInfo.AppendIAOptionsL( *v6Msg, EDecline );
       
   734 	
       
   735 	}
       
   736 
       
   737 void CDHCPIP6StateMachine::HandleOfferL()
       
   738 /**
       
   739   * Handles the selected advertisement from a dhcp server, providing
       
   740   * an offer of configuration parameters
       
   741   *
       
   742   * @see CDHCPIP6Select
       
   743   * @internalTechnology
       
   744   *
       
   745   */
       
   746 	{
       
   747 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::HandleOffer")));
       
   748 	
       
   749 	CDHCPMessageHeaderIP6* v6Msg = DhcpMessage();
       
   750 	//remember the address of the server and check for unicast option
       
   751 	iInterfaceConfigInfo.CheckForUnicast( *v6Msg );
       
   752 	}
       
   753 
       
   754 CDHCPState* CDHCPIP6StateMachine::HandleReplyL( TRequestStatus* aStatus )
       
   755 /**
       
   756   * Called after Request, Confirm, Renew, Rebind or
       
   757   * Information-request message
       
   758   *
       
   759   * @internalTechnology
       
   760   *
       
   761   */
       
   762 {
       
   763    iReceiving = EFalse;
       
   764    
       
   765    CDHCPState* state = NULL;
       
   766 
       
   767    if ( GetMessageType() != EReply )
       
   768     {
       
   769 		return ReceiveL(aStatus);
       
   770     }
       
   771 
       
   772     switch ( DhcpMessage()->GetStatusCode() )
       
   773         {
       
   774          case ESuccess:
       
   775 				HandleAckL();
       
   776                 User::RequestComplete(aStatus, KErrNone);
       
   777 	            state = static_cast<CDHCPState*>(iActiveEvent->Next());
       
   778                 
       
   779                 // No need to notify server status - the TCP/IP6 stack will
       
   780                 // move straight to the address assigned state when we call
       
   781                 // ConfigureL...
       
   782 
       
   783 		 break;
       
   784  
       
   785          case EUnspecFail:
       
   786          case ENoAddrsAvail:
       
   787          case ENoBinding:
       
   788          case ENotOnLink:
       
   789 				User::RequestComplete(aStatus, KErrAccessDenied);
       
   790  
       
   791                 state = NULL;
       
   792          break;
       
   793 
       
   794          case EUseMulticast:
       
   795             {
       
   796                 iInterfaceConfigInfo.ResetUseUnicast();
       
   797                 //return to the previous state and use multicast
       
   798                 CAsynchEvent* p = iFirstState;
       
   799                 while ( p->Next() != iActiveEvent )
       
   800                    {
       
   801                    p = p->Next();
       
   802                    }
       
   803                 state =static_cast<CDHCPState*>(p);
       
   804             }
       
   805          break;
       
   806            
       
   807             		 
       
   808          default:
       
   809 			state = ReceiveL(aStatus);
       
   810          break;
       
   811          
       
   812          };// switch
       
   813 	
       
   814 
       
   815     return state;
       
   816 }
       
   817 
       
   818 void CDHCPIP6StateMachine::HandleAckL()
       
   819 /**
       
   820   * Handles a succesfull reply from a dhcp server, storing
       
   821   * configuration parameters and a committed ip address.
       
   822   * Checks status code for IA(s) and IP address options and leaves
       
   823   * with KErrAccessDenied if no address is avaiable.
       
   824   *
       
   825   * @internalTechnology
       
   826   *
       
   827   */
       
   828 	{
       
   829 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::HandleAck")));
       
   830 	
       
   831 	CDHCPMessageHeaderIP6* v6Msg = DhcpMessage();
       
   832 	//get addresses out of IA options
       
   833 	iInterfaceConfigInfo.ParseIAOptionsL(*v6Msg);
       
   834 	//check unicast option & server address
       
   835 	iInterfaceConfigInfo.CheckForUnicast(*v6Msg);
       
   836 
       
   837 	//check name servers from msg options
       
   838 	if( iNameServerAddressesFromServer )
       
   839 		{
       
   840 		CDHCPOptionDNSServers* pServers = static_cast<CDHCPOptionDNSServers*>(v6Msg->GetOptions().FindOption( EDNSServers ));
       
   841 		if ( pServers )
       
   842 			{
       
   843 			pServers->GetDomainNameServer( 0, iNameServer1 );
       
   844 			pServers->GetDomainNameServer( 1, iNameServer2 );
       
   845 			}
       
   846 		}
       
   847 	//get a host name somehow?
       
   848 	//still draft only draft-ietf-dhc-dhcpv6-fqdn-00.txt with option-code      OPTION_CLIENT_FQDN (TBD)
       
   849 
       
   850 	#ifdef _LOG
       
   851 		TBuf<39> addrStr;
       
   852 		
       
   853 		interfaceInfo.iAddress.Output( addrStr );
       
   854 		
       
   855 		__CFLOG_1( KLogSubSysDHCP, KLogCode, _L( "DHCP client address is %S" ), &addrStr );
       
   856 	#endif
       
   857 
       
   858 	ConfigureInterfaceL( 0 );
       
   859 	}
       
   860 
       
   861 void CDHCPIP6StateMachine::ConfigureInterfaceL( TInt aPos )
       
   862 /**
       
   863   * Set the interface IP address and other params
       
   864   * into the TCP/IP6 stack.
       
   865   * Picks next valid address starting from given possition
       
   866   *
       
   867   * What we set depends on the setup
       
   868   * in commDB for the service.  If ipAddressFromServer
       
   869   * is true then we set the ip address that has
       
   870   * been assigned by DHCP, along with the netmask and gateway.
       
   871   * If ipAddressFromServer is false, then we set the static ip
       
   872   * address as long as it has been okayed by the DHCP server after
       
   873   * we have sent an inform.  We will then set the netmask and gateway
       
   874   * choosing from those in commDB if they have been given values, or 
       
   875   * those returned in the DHCP Server ACK if a zero address is in commDB
       
   876   * The same principle applies to DNS Server addresses.
       
   877   *
       
   878   * @param aPos possition to start in the address list
       
   879   * @see SIdentityAssociationConfigInfo
       
   880   * @internalTechnology
       
   881   */
       
   882 	{
       
   883 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::ConfigureInterfaceL - Cancel Message Sender - aPos %d"), aPos));
       
   884 	iMessageSender->Cancel();
       
   885 	
       
   886 	if (!IsGettingCfgInfoOnly())
       
   887 		{
       
   888 		const SIPAddressInfo* info = iInterfaceConfigInfo.GetValidAddressInfo( aPos );
       
   889 		if ( !info )
       
   890 			{//no more addresses to configure
       
   891 			User::Leave( KErrNotFound );
       
   892 			}
       
   893 		//the values already checked on TInterfaceConfigInfo::ParseIAOptionsL
       
   894 		iRenewalTimeT1 = iInterfaceConfigInfo.RenewTime();
       
   895 		iRebindTimeT2 = iInterfaceConfigInfo.RebindTime();
       
   896 		iLeaseTime = info->iValidLifeTime;
       
   897 		
       
   898 		// This block caters for the following 2 cases:
       
   899         //  1. Server sent 0 lease time, meaning "forever". This behaviour wasn't defined in the 
       
   900         //     original RFC but many servers work this way so we need to support it.
       
   901         //  2. Server sent extremely large lease time (e.g. 0xffffffff as specified in RFC).
       
   902         //     As TTimeIntervalSeconds has a maximum of 0x7fffffff, we must enforce this maximum.
       
   903         //
       
   904         if ( iLeaseTime == 0 || iLeaseTime > KReallyLongLease )
       
   905             {
       
   906             iLeaseTime = KReallyLongLease;  // 68 years should be long enough
       
   907             }
       
   908         
       
   909 		if ( (iRenewalTimeT1 == iRebindTimeT2) || (iRenewalTimeT1==0 && iRebindTimeT2==0) )
       
   910             {
       
   911             // may have only been provided with a lease time...
       
   912             // we need time to renew the lease before it runs out
       
   913             // so we'd better set some times from the overall lease time
       
   914             TUint32 temp = iLeaseTime/4;
       
   915             iRenewalTimeT1=iLeaseTime/2;
       
   916             iRebindTimeT2=iRenewalTimeT1+temp;      
       
   917             }
       
   918 		else if (iRenewalTimeT1<iRebindTimeT2 && iRebindTimeT2<iLeaseTime && iRenewalTimeT1<iLeaseTime)
       
   919             {
       
   920             // do nothing as we have got the valid values we were expecting
       
   921             }
       
   922         else
       
   923             {
       
   924             User::Leave(KErrArgument);
       
   925             }   
       
   926 		
       
   927 		iCurrentAddress.SetAddress( info->iAddress.Ip6Address() );
       
   928 		}
       
   929 	else if ( aPos != 0 )
       
   930 		{//no more addresses to configure only one statically configured address
       
   931 		User::Leave( KErrNotFound );
       
   932 		}
       
   933 
       
   934 	TSoInet6InterfaceInfo interfaceInfo;
       
   935    //fill interfaceInfo current address is iCurrentAddress
       
   936 	interfaceInfo.iHwAddr = iHardwareAddr;
       
   937 	interfaceInfo.iAddress = iCurrentAddress;
       
   938 //	interfaceInfo.iNetMask = iSubnetMask;
       
   939 	interfaceInfo.iDefGate = iDefGateway;
       
   940 	if (iNameServerAddressesFromServer)
       
   941 		{
       
   942 		interfaceInfo.iNameSer1 = iNameServer1;
       
   943 		interfaceInfo.iNameSer2 = iNameServer2;
       
   944 		}
       
   945 	else
       
   946 		{
       
   947 		//We need to set the family to KAFUnspec to ensure that the Stack does not overwrite the existing address
       
   948 		interfaceInfo.iNameSer1.SetFamily(KAFUnspec);
       
   949 		interfaceInfo.iNameSer2.SetFamily(KAFUnspec);
       
   950 		}
       
   951 	interfaceInfo.iName = iInterfaceName;
       
   952 	interfaceInfo.iMtu = 0;
       
   953 	interfaceInfo.iSpeedMetric = 0;
       
   954 	interfaceInfo.iFeatures = 0; // zero value better than junk value
       
   955 	
       
   956 	interfaceInfo.iState = EIfUp;
       
   957 
       
   958 	interfaceInfo.iDelete = EFalse;
       
   959 	interfaceInfo.iAlias = EFalse;
       
   960 	interfaceInfo.iDoId = ETrue;
       
   961 	interfaceInfo.iDoState = ETrue;
       
   962 	interfaceInfo.iDoAnycast = EFalse;
       
   963 	interfaceInfo.iDoProxy = EFalse;
       
   964 	interfaceInfo.iDoPrefix = EFalse;
       
   965 	
       
   966 	CDHCPStateMachine::ConfigureInterfaceL( interfaceInfo );
       
   967 	}
       
   968 
       
   969 void CDHCPIP6StateMachine::InitialiseSocketL()
       
   970 /**
       
   971   * Sets up socket, by opening one associated with the connection
       
   972   * and sets the interface to use for traffic
       
   973   *
       
   974   * @internalTechnology
       
   975   *
       
   976   */
       
   977 	{
       
   978 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::InitialiseSocketL")));
       
   979 	
       
   980 	iSocket.Close();
       
   981 	
       
   982 	User::LeaveIfError(iSocket.Open(iEsock, KAfInet, KSockDatagram, KProtocolInetUdp, iConnection));
       
   983 	User::LeaveIfError(iSocket.SetOpt(KSoReuseAddr, KSolInetIp, 1));
       
   984 #ifdef _DEBUG
       
   985 	TInt destPort;
       
   986 	RProperty::Get(KMyPropertyCat, KMyPropertyDestPortv6, destPort);
       
   987 	User::LeaveIfError(iSocket.SetLocalPort(destPort - 1));
       
   988 #else
       
   989 	User::LeaveIfError(iSocket.SetLocalPort(KDhcpv6SrcPort));
       
   990 #endif	
       
   991 	TPckgBuf<TSoInetIfQuery> query;
       
   992 	query().iName = iInterfaceName;
       
   993 	User::LeaveIfError(iSocket.GetOpt(KSoInetIfQueryByName, KSolInetIfQuery, query));
       
   994 	User::LeaveIfError(iSocket.SetOpt(KSoInterfaceIndex, KSolInetIp, query().iIndex));
       
   995 	User::LeaveIfError(iSocket.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl));
       
   996 	// make socket invisable for interface counting
       
   997 	User::LeaveIfError(iSocket.SetOpt(KSoKeepInterfaceUp, KSolInetIp, 0));
       
   998 	}
       
   999 
       
  1000 void CDHCPIP6StateMachine::RemoveConfiguredAddress(const TInetAddr* /* aInetAddr*/)
       
  1001 /**
       
  1002   * This function can be called as a result of DAD failing
       
  1003   * or the lease expiring! It removes the address from the interface
       
  1004   * inside the TCP/IP6 stack as the address cannot continue to be used.
       
  1005   *
       
  1006   * @see "Implementation of IPv4/IPv6 Basic Socket API for Symbian OS"
       
  1007   * document for explanation of TSoInet6InterfaceInfo and its use
       
  1008   * @internalTechnology
       
  1009   */
       
  1010 	{
       
  1011 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::RemoveConfiguredAddress")));
       
  1012 	
       
  1013 	TSoInet6InterfaceInfo interfaceInfo;
       
  1014 	interfaceInfo.iHwAddr = iHardwareAddr;
       
  1015 	interfaceInfo.iAddress = iCurrentAddress;
       
  1016 	interfaceInfo.iName = iInterfaceName;
       
  1017 	interfaceInfo.iDelete = ETrue;
       
  1018 	interfaceInfo.iAlias = EFalse;
       
  1019 	interfaceInfo.iDoId = ETrue;
       
  1020 	interfaceInfo.iState = EIfUp;
       
  1021 	interfaceInfo.iDoState = ETrue;
       
  1022 	interfaceInfo.iDoAnycast = EFalse;
       
  1023 	// zero value better than junk value
       
  1024 	interfaceInfo.iMtu = 0;
       
  1025 	interfaceInfo.iSpeedMetric = 0;
       
  1026 	interfaceInfo.iFeatures = 0; 
       
  1027 	CDHCPStateMachine::RemoveConfiguredAddress( interfaceInfo );
       
  1028     iInterfaceConfigInfo.Reset();
       
  1029 	}
       
  1030 
       
  1031 void CDHCPIP6StateMachine::AssignAddresses( TInetAddr& aDest, const TInetAddr& aSrc ) const
       
  1032 	{
       
  1033 	aDest = aSrc;
       
  1034 
       
  1035 #ifdef _DEBUG
       
  1036 	// Simulate initialisation, renewal or rebind failure by using the wrong port.
       
  1037 	if( ( CDHCPServer::DebugFlags() & KDHCP_FailDiscover ) || ( CDHCPServer::DebugFlags() & KDHCP_FailRenew ) || ( CDHCPServer::DebugFlags() & KDHCP_FailRebind ) )
       
  1038 		{
       
  1039 		aDest.SetPort(KDhcpv6WrongSrcPort);
       
  1040 		}
       
  1041 	else
       
  1042 		{
       
  1043 		TInt destPort;
       
  1044 		RProperty::Get(KMyPropertyCat, KMyPropertyDestPortv6, destPort);
       
  1045 		aDest.SetPort(destPort - 1);
       
  1046 		}
       
  1047 #else
       
  1048 	aDest.SetPort(KDhcpv6SrcPort);
       
  1049 #endif
       
  1050 	}
       
  1051 
       
  1052 void CDHCPIP6StateMachine::BindSocketForUnicastL()
       
  1053 /**
       
  1054   * Initialises socket in case it hasn't already been initialised
       
  1055   *
       
  1056   * @internalTechnology
       
  1057   */
       
  1058 	{
       
  1059     __CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP6StateMachine::BindSocketForRenewL")));
       
  1060     UpdateHistory(CDHCPState::EBindToSource);
       
  1061     if (!iSocket.SubSessionHandle())
       
  1062         {
       
  1063         InitialiseSocketL();
       
  1064         }
       
  1065 	}