tcpiputils/dhcp/src/DHCPIP4StateMachine.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 IP4 statemachine helper functions
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file DHCPIP4StateMachine.cpp
       
    20  @internalTechnology
       
    21 */
       
    22 #include <babitflags.h>
       
    23 #include <e32math.h>
       
    24 #include "DHCPIP4States.h"
       
    25 #include "DHCPServer.h"
       
    26 #ifndef SYMBIAN_COMMS_REPOSITORY
       
    27 #include <commdb.h>
       
    28 #else
       
    29 #include <metadatabase.h>
       
    30 #include <commsdattypesv1_1.h>
       
    31 #endif
       
    32 
       
    33 #ifdef SYMBIAN_NETWORKING_ADDRESS_PROVISION
       
    34 #include "dhcphwaddrmanager.h"
       
    35 #endif //SYMBIAN_NETWORKING_ADDRESS_PROVISION
       
    36 using namespace DHCPv4;
       
    37 #ifdef SYMBIAN_COMMS_REPOSITORY
       
    38 using namespace CommsDat;
       
    39 #endif
       
    40 
       
    41 #ifdef SYMBIAN_NETWORKING_DHCPSERVER
       
    42 const TUint16 KBroadCastFlagMask = 0x8000;
       
    43 #endif
       
    44 
       
    45 CDHCPIP4StateMachine::~CDHCPIP4StateMachine()
       
    46 /**
       
    47   * Destructor of the If base class
       
    48   *
       
    49   * @internalTechnology
       
    50   *
       
    51   */
       
    52 	{
       
    53 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::~CDHCPIP4StateMachine")));
       
    54 	}
       
    55 	
       
    56 #ifndef SYMBIAN_NETWORKING_DHCPSERVER
       
    57 CDHCPIP4StateMachine* CDHCPIP4StateMachine::NewL(RSocketServ& aEsock, RConnection& aConnection, const TName& aInterfaceName)
       
    58 /**
       
    59   * Creates a new instance of this class
       
    60   *
       
    61   * @internalTechnology
       
    62   *
       
    63   */
       
    64 	{
       
    65 	CDHCPIP4StateMachine* stateMachine = new (ELeave) CDHCPIP4StateMachine(aEsock, aConnection, aInterfaceName);
       
    66 	CleanupStack::PushL(stateMachine);
       
    67 	stateMachine->ConstructL();
       
    68 	CleanupStack::Pop(stateMachine);
       
    69 	return stateMachine;
       
    70 	}
       
    71 #endif // SYMBIAN_NETWORKING_DHCPSERVER
       
    72 
       
    73 void CDHCPIP4StateMachine::ConstructL()
       
    74 /**
       
    75   * Creates socket and connections for the object
       
    76   *
       
    77   *
       
    78   *	@internalTechnology
       
    79   *
       
    80   */
       
    81 	{
       
    82    CDHCPStateMachine::ConstructL();
       
    83 
       
    84 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::ConstructL")));
       
    85 	
       
    86   	ReAllocL(KDhcpMaxMsgSizeIP4);
       
    87   	iDhcpMessage = new(ELeave)CDHCPMessageHeaderIP4(iFragment);
       
    88 	iMessageSender = new(ELeave)CMessageSender(this,iSocket,&iTaskStartedAt,KAfInet);
       
    89 
       
    90 	}
       
    91 
       
    92 void CDHCPIP4StateMachine::StartInitL(MStateMachineNotify* aStateMachineNotify, EInitialisationContext /*aInitialisationContext*/, TInt /*aUserTimeOut*/)
       
    93 /**
       
    94   * StartInitL
       
    95   *
       
    96   * This function is called to start the init state machine
       
    97   *
       
    98   * @internalTechnology
       
    99   */
       
   100 	{
       
   101 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::StartInitL")));
       
   102 	ASSERT(!iFirstState);
       
   103 	
       
   104 	iFirstState = new(ELeave) CDHCPIP4Init(*this);
       
   105 	CDHCPState* select = new(ELeave) CDHCPIP4Select(*this);
       
   106 	iFirstState->SetNext( select );
       
   107 	CDHCPState* request = new(ELeave) CDHCPIP4Request(*this);
       
   108 	select->SetNext( request );
       
   109 	request->SetNext( new(ELeave) CDHCPIP4WaitForDAD(*this) );
       
   110 
       
   111 	CDHCPStateMachine::Start(aStateMachineNotify);
       
   112 	}
       
   113 
       
   114 void CDHCPIP4StateMachine::StartInformL(MStateMachineNotify* aStateMachineNotify, TBool /*aStaticAddress*/)
       
   115 /**
       
   116   * StartIniformL
       
   117   *
       
   118   * This function is called to start the inform static address state machine
       
   119   *
       
   120   * @internalTechnology
       
   121   */
       
   122 	{
       
   123 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::StartInformL")));
       
   124 	ASSERT(!iFirstState);
       
   125 
       
   126 	iFirstState = new(ELeave) CDHCPIP4Inform(*this);
       
   127 	CDHCPState* request = new(ELeave) CDHCPIP4Request(*this);
       
   128    iFirstState->SetNext( request );
       
   129    request->SetNext( new(ELeave) CDHCPIP4WaitForDAD(*this) );
       
   130 	
       
   131 	CDHCPStateMachine::Start(aStateMachineNotify);
       
   132 	iCfgInfoOnly = ETrue;
       
   133 	}
       
   134 
       
   135 #ifdef SYMBIAN_NETWORKING_DHCP_MSG_HEADERS
       
   136 void CDHCPIP4StateMachine::StartInformL(MStateMachineNotify* aStateMachineNotify)
       
   137 /**
       
   138   * This function is called to send inform message if options are not 
       
   139   * found in iValidMsg buffer
       
   140   *
       
   141   * @internalTechnology
       
   142   */
       
   143 	{
       
   144 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::StartInformL Dynamic Inform Request")));
       
   145 	ASSERT(!iFirstState);
       
   146 
       
   147 	iFirstState = new(ELeave) CDHCPIP4Inform(*this);
       
   148 	CDHCPState* request = new(ELeave) CDHCPIP4Request(*this);
       
   149 	iFirstState->SetNext( request );
       
   150 	CDHCPStateMachine::Start(aStateMachineNotify);
       
   151 
       
   152 	}
       
   153 #endif // SYMBIAN_NETWORKING_DHCP_MSG_HEADERS
       
   154 void CDHCPIP4StateMachine::StartRebootL(MStateMachineNotify* aStateMachineNotify)
       
   155 /**
       
   156   * StartRebootL
       
   157   *
       
   158   * This function is called to start the reboot request state machine
       
   159   * used when trying to start using a previously assigned address still
       
   160   * with valid lease.
       
   161   *
       
   162   * @internalTechnology
       
   163   */
       
   164 	{
       
   165 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::StartRebootL")));
       
   166 	ASSERT(!iFirstState);
       
   167 
       
   168    iFirstState = new(ELeave) CDHCPIP4Reboot(*this);
       
   169 	CDHCPState* request = new(ELeave) CDHCPIP4Request(*this);
       
   170    iFirstState->SetNext( request );
       
   171    request->SetNext( new(ELeave) CDHCPIP4WaitForDAD(*this) );
       
   172 
       
   173 	CDHCPStateMachine::Start(aStateMachineNotify);
       
   174 	}
       
   175 
       
   176 void CDHCPIP4StateMachine::StartRenewL(MStateMachineNotify* aStateMachineNotify,TInt /*aUserTimeOut*/)
       
   177 /**
       
   178   * StartRenewL
       
   179   *
       
   180   * This function is called to start the renew of lease state machine
       
   181   *
       
   182   * @internalTechnology
       
   183   */
       
   184 	{
       
   185 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::StartRenew")));
       
   186 	ASSERT(!iFirstState);
       
   187 
       
   188   	iFirstState = new(ELeave) CDHCPIP4Renew(*this);
       
   189    iFirstState->SetNext( new(ELeave) CDHCPIP4WaitForDAD(*this) );
       
   190 
       
   191    CDHCPStateMachine::Start(aStateMachineNotify);
       
   192 	}
       
   193 
       
   194 void CDHCPIP4StateMachine::StartRebindL(MStateMachineNotify* aStateMachineNotify)
       
   195 /**
       
   196   * StartRebindL
       
   197   *
       
   198   * This function is called to start the rebind state machine
       
   199   *
       
   200   * @internalTechnology
       
   201   */	
       
   202 	{
       
   203 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::StartRebindL")));
       
   204 	ASSERT(!iFirstState);
       
   205 	
       
   206 	iFirstState = new(ELeave) CDHCPIP4Rebind(*this);
       
   207    iFirstState->SetNext( new(ELeave) CDHCPIP4WaitForDAD(*this) );
       
   208 
       
   209 	CDHCPStateMachine::Start(aStateMachineNotify);
       
   210 	}
       
   211 
       
   212 void CDHCPIP4StateMachine::StartDeclineL(MStateMachineNotify* aStateMachineNotify)
       
   213 /**
       
   214   * StartDeclineL
       
   215   *
       
   216   * This function is called to start the decline state machine
       
   217   *
       
   218   * @internalTechnology
       
   219   */
       
   220 	{
       
   221 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::StartDeclineL")));
       
   222 	ASSERT(!iFirstState);
       
   223 	
       
   224 	iFirstState = new(ELeave) CDHCPIP4Decline(*this);
       
   225 	
       
   226 	CDHCPStateMachine::Start(aStateMachineNotify);
       
   227 	}
       
   228 
       
   229 void CDHCPIP4StateMachine::StartReleaseL(MStateMachineNotify* aStateMachineNotify)
       
   230 /**
       
   231   * StartReleaseL
       
   232   *
       
   233   * This function is called to start the release state machine
       
   234   *
       
   235   * @internalTechnology
       
   236   */
       
   237 	{
       
   238 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::StartReleaseL")));
       
   239 	ASSERT(!iFirstState);
       
   240 	
       
   241 	iFirstState = new(ELeave) CDHCPIP4Release(*this);
       
   242 	//iFirstState->SetNext( new(ELeave) CDHCPRemoveConfiguredAddress(*this));
       
   243 	
       
   244 	CDHCPStateMachine::Start(aStateMachineNotify);
       
   245 	}
       
   246 
       
   247 CDHCPState* CDHCPIP4StateMachine::ReceiveL(TRequestStatus* aStatus)
       
   248 /**
       
   249   * Posts receive from on socket
       
   250   *
       
   251   * @note The iDHCPServerAddr in param 2 of the socket receivefrom
       
   252   * is written into by the socket to say where the received message
       
   253   * came from.
       
   254   * @internalTechnology
       
   255   *
       
   256   */
       
   257 	{
       
   258 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::Receive")));
       
   259 	
       
   260 	DhcpMessage()->InitialiseL();
       
   261   	iIncomingMsgDataPtr.Set(iDhcpMessage->Message().Des());
       
   262    ASSERT( iReceiving == EFalse );
       
   263  	iReceiving = ETrue;
       
   264 	iSocket.RecvFrom(iIncomingMsgDataPtr, iDHCPServerAddr, 0, *aStatus);
       
   265    return static_cast<CDHCPState*>(iActiveEvent);
       
   266 	}
       
   267 
       
   268 #ifdef SYMBIAN_NETWORKING_DHCPSERVER
       
   269 #ifdef SYMBIAN_NETWORKING_ADDRESS_PROVISION
       
   270 CDHCPIP4StateMachine* CDHCPIP4StateMachine::NewL(RSocketServ& aEsock, RConnection& aConnection, const TName& aInterfaceName,  CDhcpHwAddrManager* aDhcpHwAddrManager, TBool aDHCPServerImpl)
       
   271 #else
       
   272 CDHCPIP4StateMachine* CDHCPIP4StateMachine::NewL(RSocketServ& aEsock, RConnection& aConnection, const TName& aInterfaceName,TBool aDHCPServerImpl)
       
   273 #endif //SYMBIAN_NETWORKING_ADDRESS_PROVISION
       
   274 /**
       
   275   * Creates a new instance of this class
       
   276   *
       
   277   * @internalTechnology
       
   278   *
       
   279   */
       
   280 	{
       
   281 #ifdef SYMBIAN_NETWORKING_ADDRESS_PROVISION
       
   282 	CDHCPIP4StateMachine* stateMachine = new (ELeave) CDHCPIP4StateMachine(aEsock, aConnection, aInterfaceName, aDhcpHwAddrManager, aDHCPServerImpl);
       
   283 #else
       
   284 	CDHCPIP4StateMachine* stateMachine = new (ELeave) CDHCPIP4StateMachine(aEsock, aConnection, aInterfaceName,aDHCPServerImpl);
       
   285 #endif //SYMBIAN_NETWORKING_ADDRESS_PROVISION	
       
   286 	CleanupStack::PushL(stateMachine);
       
   287 	stateMachine->ConstructL();
       
   288 	CleanupStack::Pop(stateMachine);
       
   289 	return stateMachine;
       
   290 	}
       
   291 
       
   292 TUint8 CDHCPIP4StateMachine::GetClientMessageTypeL() const
       
   293 /**
       
   294   * Returns the message type from the DHCP message
       
   295   * i.e. whether the message is an offer, ack, nak...
       
   296   *
       
   297   * @internalTechnology 
       
   298   */
       
   299 	{
       
   300 	CDHCPMessageHeaderIP4* v4Msg = DhcpMessage();
       
   301 	v4Msg->ParseClientMsgL();
       
   302 	v4Msg->Dump();	
       
   303 
       
   304 	return v4Msg->iOptions.GetMessageType();
       
   305 	}
       
   306 
       
   307 	
       
   308 CDHCPState* CDHCPIP4StateMachine::ReceiveOnPort67L(TRequestStatus* aStatus)
       
   309 /**
       
   310   * Posts receive from on socket
       
   311   *
       
   312   * @note The iDHCPClientAddr in param 2 of the socket receivefrom
       
   313   * is written into by the socket to say where the received message
       
   314   * came from.
       
   315   * @internalTechnology
       
   316   *
       
   317   */
       
   318 	{
       
   319 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::ReceiveOnPort67L")));
       
   320 	
       
   321 	DhcpMessage()->InitialiseL();
       
   322   	iIncomingMsgDataPtr.Set(iDhcpMessage->Message().Des());
       
   323 	ASSERT( iReceiving == EFalse );
       
   324  	iReceiving = ETrue;
       
   325 	iSvrSocket.RecvFrom(iIncomingMsgDataPtr, iDHCPClientAddr, 0, *aStatus);
       
   326 	return static_cast<CDHCPState*>(iActiveEvent);
       
   327 	}
       
   328 	
       
   329 void CDHCPIP4StateMachine::PrepareToSendServerMsgL( CDHCPStateMachine::EAddressType aEAddressType)
       
   330 /**
       
   331   * PrepareToSendServerMsgL
       
   332   *
       
   333   * This function is called to set the correct destination address
       
   334   * for messages before they are sent.
       
   335   *
       
   336   * @internalTechnology
       
   337   */	
       
   338 	{
       
   339 	// nothing is done with iClientId in server implementation
       
   340 	// but it is passed to reuse the existing function.
       
   341 	DhcpMessage()->FinishL(iClientId); 
       
   342 	DhcpMessage()->Dump();
       
   343 	if (aEAddressType==EUnicast)
       
   344 		{
       
   345 		if(iBroadCastFlag)
       
   346 			{
       
   347 			__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::SetDestination - broadcast")));
       
   348 			iDHCPClientAddr.SetV4MappedAddress(KInetAddrBroadcast);		
       
   349 			}
       
   350 		else
       
   351 			{
       
   352 			__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::SetDestination - unicast")));
       
   353 			iDHCPClientAddr.SetV4MappedAddress(iYiaddr);// client ip address
       
   354 			}
       
   355 		}
       
   356 	else
       
   357 		{
       
   358 		__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::SetDestination - broadcast")));
       
   359 		iDHCPClientAddr.SetV4MappedAddress(KInetAddrBroadcast);	
       
   360 		}
       
   361 
       
   362 // While DHCP server listens on a custom port, the server message for client
       
   363 // needs to be the custom server port + 1 and not the default client port (i.e., 68)
       
   364 #ifdef _DEBUG
       
   365 	iDHCPClientAddr.SetPort(GetDestPort()+1);
       
   366 #else
       
   367 	iDHCPClientAddr.SetPort(KDhcpClientPort);
       
   368 #endif
       
   369 	}
       
   370 	
       
   371 void CDHCPIP4StateMachine::GetClientAddress( TInetAddr& aAddress )
       
   372 /**
       
   373   * GetClientAddress
       
   374   *
       
   375   * Gets the assigned client address
       
   376   *
       
   377   * @internalTechnology	
       
   378 */
       
   379 	{
       
   380 	aAddress = iDHCPClientAddr;
       
   381 	}
       
   382 
       
   383 TUint32 CDHCPIP4StateMachine::GenerateClientIPAddress()
       
   384 /**
       
   385   * GenerateClientIPAddress
       
   386   *
       
   387   * Generate valid IP address to be offered to the client
       
   388   *
       
   389   *@internalTechnology	
       
   390 */
       
   391 	{
       
   392 	// get the server IP address	
       
   393 	TUint32 serverAddr = iCurrentAddress.Address();
       
   394 	TUint32 hostId = (serverAddr & ~KInetAddrNetMaskC) + 1;
       
   395 	if (hostId >= 255)
       
   396 	 {
       
   397 	 hostId = 1;
       
   398 	 }
       
   399 	return (serverAddr & KInetAddrNetMaskC) | hostId;
       
   400 	}
       
   401 	
       
   402 void CDHCPIP4StateMachine::SetMessageHeaderAsServerL( TDHCPv4MessageType aMsgType )
       
   403 /**
       
   404   * SetMessageHeaderAsServerL
       
   405   *
       
   406   * Fills in the DHCP header information to be sent to the client
       
   407   *
       
   408   * @internalTechnology
       
   409   */
       
   410 	{
       
   411 	TTime now;
       
   412 	TTimeIntervalSeconds secs;
       
   413 	now.HomeTime();	
       
   414 	(void)now.SecondsFrom(iTaskStartedAt, secs);
       
   415 
       
   416 	CDHCPMessageHeaderIP4* v4Msg = DhcpMessage();
       
   417 	v4Msg->InitialiseL();
       
   418 	v4Msg->SetSecs(static_cast<TUint16>(secs.Int()));	// time field is 16 bits, time elapsed will be less than 16 bits, hence no data loss
       
   419 	v4Msg->SetXid(iXid.Xid());
       
   420 	// set to indicate we are using DHCP server implementation
       
   421 	v4Msg->iDHCPServerImpl = ETrue; 
       
   422 	v4Msg->SetCIAddr(iCiaddr);
       
   423 	// +++++++++++++++++++++ Message Type (1 byte) ++++++++++++++++++++++++++++++++/
       
   424 	v4Msg->AddOptionL(EDHCPMessageType, 1)->SetBigEndian(aMsgType);
       
   425 	
       
   426 	switch(aMsgType)
       
   427 		{
       
   428 		case EDHCPOffer:
       
   429 		case EDHCPAck:
       
   430 			// ++++++++Subnet mask, Router and Server IP set with server address ++++++++++/			
       
   431 			v4Msg->AddOptionL(EDHCPSubnetMask,KIp4AddrByteLength)->SetBigEndian(KInetAddrNetMaskC); // 255.255.255.0
       
   432 			v4Msg->AddOptionL(EDHCPRouter,KIp4AddrByteLength)->SetBigEndian(iCurrentAddress.Address());
       
   433 			v4Msg->AddOptionL(EDHCPServerID,KIp4AddrByteLength)->SetBigEndian(iCurrentAddress.Address());	
       
   434 			break;
       
   435 
       
   436 		case EDHCPNak:
       
   437 			// ++++++++Server IP set with server address ++++++++++/
       
   438 			v4Msg->AddOptionL(EDHCPServerID,KIp4AddrByteLength)->SetBigEndian(iCurrentAddress.Address());	
       
   439 			break;
       
   440 		}
       
   441 	
       
   442 	TUint8 htype,hlen;
       
   443 	//  fill in something "traditional" so as not to upset a stupid server.
       
   444 	//  This is a best guess based on lack of specs in this area
       
   445 	htype = 1; // ethernet
       
   446 	hlen = 6; // mac address length
       
   447 	v4Msg->SetCHAddr(iClientHWAddr);
       
   448 
       
   449 	v4Msg->SetHeader(EDHCPBootReply,  htype /*hardware addr type*/,  hlen /*hardware addr length*/,  0 /*hops*/);
       
   450 	v4Msg->SetFlags(iFlag);
       
   451 #ifdef _DEBUG
       
   452 	if (CDHCPServer::DebugFlags() & KDHCP_RequestIP4BroadcastOffer)
       
   453 		{
       
   454 		v4Msg->SetFlags(0x8000); // force broadcast
       
   455 		}
       
   456 #endif
       
   457 	}
       
   458 			
       
   459 #endif // SYMBIAN_NETWORKING_DHCPSERVER
       
   460 
       
   461 void CDHCPIP4StateMachine::PrepareToSendL( CDHCPStateMachine::EAddressType aEAddressType )
       
   462 /**
       
   463   * PrepareToSendL
       
   464   *
       
   465   * This function is called to set the correct destination address
       
   466   * for messages before they are sent.
       
   467   *
       
   468   * @internalTechnology
       
   469   */	
       
   470 	{
       
   471 #ifdef SYMBIAN_NETWORKING_DHCP_MSG_HEADERS
       
   472 	if (iDhcpInformAckPending)
       
   473 		{
       
   474 		DhcpMessage()->FinishL(iClientId,&iSavedExtraParameters);
       
   475 		}
       
   476 	else
       
   477 		{
       
   478 #endif // SYMBIAN_NETWORKING_DHCP_MSG_HEADERS
       
   479 	DhcpMessage()->FinishL(iClientId);
       
   480 #ifdef SYMBIAN_NETWORKING_DHCP_MSG_HEADERS
       
   481 		}	
       
   482 #endif // SYMBIAN_NETWORKING_DHCP_MSG_HEADERS
       
   483 	DhcpMessage()->Dump();
       
   484 	if (aEAddressType==EUnicast)
       
   485 		{
       
   486 		__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::SetDestination - unicast")));
       
   487 		iDHCPServerAddr.SetV4MappedAddress(iServerAddress);
       
   488 		}
       
   489 	else
       
   490 		{
       
   491 		__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::SetDestination - broadcast")));
       
   492 		iDHCPServerAddr.SetV4MappedAddress(KInetAddrBroadcast);	
       
   493 		}
       
   494 #ifndef _DEBUG
       
   495 	iDHCPServerAddr.SetPort(KDhcpDestPort);
       
   496 #else
       
   497 	// Simulate initialisation, renewal or rebind failure by using the wrong port.
       
   498 	if( ( CDHCPServer::DebugFlags() & KDHCP_FailDiscover ) || ( CDHCPServer::DebugFlags() & KDHCP_FailRenew ) || ( CDHCPServer::DebugFlags() & KDHCP_FailRebind ) )
       
   499 		{
       
   500 		iDHCPServerAddr.SetPort(KDhcpWrongDestPort);
       
   501 		}
       
   502 	else
       
   503 		{
       
   504 		iDHCPServerAddr.SetPort(GetDestPort());
       
   505 		}
       
   506 #endif
       
   507 	}
       
   508 
       
   509 
       
   510 void CDHCPIP4StateMachine::AssembleClientIDsL()
       
   511 /**
       
   512   * Sets the client id - this just has to be a cookie for the server to use for indexing.
       
   513   * 
       
   514   *   On an addressed link (e.g. ethernet), hardware address type/value pair is a good combo to use
       
   515   *      as it mirrors a few other popular implementations..
       
   516   */
       
   517 	{
       
   518     FetchHWAddress();
       
   519 
       
   520     iClientId.CreateL(KMaxSockAddrSize);
       
   521     iClientId.SetLength(1);		// set length to 1 byte
       
   522 
       
   523 	if(iHardwareAddr.Family()!=KAFUnspec)
       
   524 		{
       
   525 		// we're on a link with hardware addressing e.g. ethernet
       
   526 		__CFLOG_VAR((KLogSubSysDHCP, KLogCode,
       
   527 						_L8("CDHCPIP4StateMachine::AssembleClientIDsL - hardware address type=%d, length=%d"),
       
   528 						iHardwareAddr.Port(), iHardwareAddr.Length() - KHwAddrOffset));
       
   529 
       
   530 		iClientId[0] = static_cast<TUint8>(iHardwareAddr.Port());	// fill in the hwAddrType
       
   531 	    iClientId.Append(iHardwareAddr.Mid(KHwAddrOffset, iHardwareAddr.Length() - KHwAddrOffset));
       
   532 		}
       
   533 	else // family was unspecified meaning no hardware address
       
   534     	{
       
   535     	// This means we're on a point-to-point link (i.e. one with no hardware addressing).
       
   536     	//  We'll make client id look like an ethernet/mac address combo to reduce the chance of stupid servers getting upset
       
   537 		__CFLOG_VAR((KLogSubSysDHCP, KLogCode,
       
   538 						_L8("CDHCPIP4StateMachine::AssembleClientIDsL - no hardware address (suggesting point-to-point)"
       
   539 						     " so generating a random 4 byte client id")));
       
   540 		iClientId[0] = static_cast<TUint8>(1);	// force hwAddrType to look like ethernet
       
   541     	TUint32 data = Math::Random();
       
   542 		iClientId.Append(TPckgC<TUint32>(data));
       
   543 		iClientId.Append(TPckgC<TUint16>(data));
       
   544     	}
       
   545 	}
       
   546 
       
   547 
       
   548 void CDHCPIP4StateMachine::GetServerAddress( TInetAddr& aAddress )
       
   549 {
       
   550 	aAddress = iDHCPServerAddr;
       
   551 }
       
   552 
       
   553 
       
   554 void CDHCPIP4StateMachine::SetCurrentAddress(const TInetAddr& aCurrentAddress, const TInetAddr& aSubnetMask)
       
   555 /**
       
   556   * The SetCurrentAddress function
       
   557   *
       
   558   * Stores ip address and subnet mask and assembles the broadcast address
       
   559   *
       
   560   * @internalTechnology
       
   561   */
       
   562 	{
       
   563 	iCurrentAddress = aCurrentAddress;
       
   564 	iSubnetMask = aSubnetMask;
       
   565 	TInetAddr broadcast;
       
   566 	broadcast.SubNetBroadcast(iCurrentAddress, iSubnetMask);
       
   567 	iBroadcastAddress = broadcast.Address();
       
   568 	}
       
   569 
       
   570 void CDHCPIP4StateMachine::SetMessageHeaderL( TDHCPv4MessageType aMsgType )
       
   571 /**
       
   572   * Puts a standard header into the message
       
   573   *
       
   574   * @internalTechnology
       
   575   */
       
   576 	{
       
   577 	TTime now;
       
   578 	TTimeIntervalSeconds secs;
       
   579 	now.HomeTime();	
       
   580 	(void)now.SecondsFrom(iTaskStartedAt, secs);
       
   581 
       
   582 	CDHCPMessageHeaderIP4* v4Msg = DhcpMessage();
       
   583 	v4Msg->InitialiseL();
       
   584 	v4Msg->SetSecs(static_cast<TUint16>(secs.Int()));	// time field is 16 bits, time elapsed will be less than 16 bits, hence no data loss
       
   585 	v4Msg->SetXid(iXid.Xid());
       
   586 
       
   587 	TUint8 htype,hlen;
       
   588 	if(iHardwareAddr.Family()!=KAFUnspec)
       
   589 		{
       
   590 		// we have link layer addressing so fill in the blanks..
       
   591 		htype = static_cast<TUint8>(iHardwareAddr.Port()); // hwAddr type (hidden in port field)...there won't be any loss of data
       
   592 		hlen = static_cast<TUint8>(iHardwareAddr.Length()-KHwAddrOffset); // length won't be too long that we lose data. Data starts 8 bytes in, thats why length is minus an offset(8)
       
   593 		v4Msg->SetCHAddr(iHardwareAddr);
       
   594 		}
       
   595 	else
       
   596 		{
       
   597 		// We have no link layer addressing so fill in something "traditional" so as not to upset a stupid server.
       
   598 		//  This is a best guess based on lack of specs in this area
       
   599 		htype = 1; // ethernet
       
   600 		hlen = 6; // mac address length
       
   601 		}
       
   602 
       
   603 	v4Msg->SetHeader(EDHCPBootRequest,  htype /*hardware addr type*/,  hlen /*hardware addr length*/,  0 /*hops*/);
       
   604 	v4Msg->SetFlags(0x0000);
       
   605 #ifdef _DEBUG
       
   606 	if (CDHCPServer::DebugFlags() & KDHCP_RequestIP4BroadcastOffer)
       
   607 		{
       
   608 		v4Msg->SetFlags(0x8000); // force broadcast
       
   609 		}
       
   610 #endif
       
   611 	// +++++++++++++++++++++ Message Type (1 byte) ++++++++++++++++++++++++++++++++/
       
   612 	v4Msg->AddOptionL(EDHCPMessageType, 1)->SetBigEndian(aMsgType);
       
   613 	}
       
   614 
       
   615 
       
   616 
       
   617 
       
   618 TUint8 CDHCPIP4StateMachine::GetMessageTypeL() const
       
   619 /**
       
   620   * Returns the message type from the DHCP message
       
   621   * i.e. whether the message is an offer, ack, nak...
       
   622   *
       
   623   * @internalTechnology 
       
   624   */
       
   625 	{
       
   626 	CDHCPMessageHeaderIP4* v4Msg = DhcpMessage();
       
   627 	v4Msg->ParseL();
       
   628 	v4Msg->Dump();	
       
   629 	
       
   630 	return v4Msg->iOptions.GetMessageType();
       
   631 	}
       
   632 
       
   633 TBool CDHCPIP4StateMachine::CheckXid() const
       
   634 /**
       
   635   * Checks xid of incoming packet against that of last message sent
       
   636   * must be called after GetMessageType so that message has been parsed!
       
   637   *
       
   638   * @internalTechnology
       
   639   */
       
   640 	{
       
   641 	CDHCPMessageHeaderIP4* v4Msg = DhcpMessage();
       
   642 	// check the Xid matches the xid we put in the discover
       
   643 	if (v4Msg->GetXid()!=iXid.Xid())
       
   644 		{
       
   645 		__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::GetMessageTypeL - non-matching xid")));
       
   646 		return EFalse;	// does not match so we are not interested in this message
       
   647 		}
       
   648 	return ETrue;
       
   649 	}
       
   650 
       
   651 void CDHCPIP4StateMachine::CreateDiscoverMsgL()
       
   652 /**
       
   653   * Puts the specifics of the discover message into
       
   654   * the message buffer
       
   655   *
       
   656   * @internalTechnology
       
   657   */
       
   658 	{
       
   659 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::CreateDiscoverMsgL")));
       
   660 	
       
   661 	if(iTaskStartedAt == 0)
       
   662 		{
       
   663 		// set time stamp to now
       
   664 		iTaskStartedAt.HomeTime();
       
   665 		iMessageSender->SetTaskStartedTime(iTaskStartedAt);
       
   666 		}
       
   667 	iXid.SetXid(static_cast<TUint32>(iXid.Rnd(0,KMaxTInt)));
       
   668 	SetMessageHeaderL(EDHCPDiscover);
       
   669 
       
   670 	CDHCPMessageHeaderIP4* v4Msg = DhcpMessage();
       
   671 	
       
   672 	// +++++++++++++++++++++ requested IP address +++++++++++++++++++++++++++++++++/
       
   673 	TInetAddr unspAddr;  //creates unspecified address
       
   674 	// now check to see if a previous address exists in CommDB with an existing lease
       
   675 	if (!iCurrentAddress.Match(unspAddr))
       
   676 		{
       
   677 		// if we have a known address (perhaps from an expired lease) then request it
       
   678 		// an address is 4 bytes long
       
   679 		v4Msg->AddOptionL(EDHCPRequestedIPAddr, KIp4AddrByteLength)->SetBigEndian(iCurrentAddress.Address());
       
   680 		}
       
   681 	// XXX: Add hostname to discover (maybe request), update device hostname
       
   682 	// if offered value differs - repeat for IPv6
       
   683 	
       
   684 	// +++++++++++++++++++++ FQDN update request ++++++++++++++++++++++++++++++++++/
       
   685 	CreateFqdnUpdateRequestL();
       
   686 	}
       
   687 
       
   688 void CDHCPIP4StateMachine::CreateOfferAcceptanceRequestMsgL()
       
   689 /**
       
   690   * Puts the specifics of the offer acceptance request
       
   691   * message into the message buffer
       
   692   *
       
   693   * @internalTechnology
       
   694   */
       
   695 	{
       
   696 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::CreateOfferAcceptanceRequestMsgL")));
       
   697 	
       
   698 	SetMessageHeaderL(EDHCPRequest);
       
   699 	CDHCPMessageHeaderIP4* v4Msg = DhcpMessage();
       
   700 	
       
   701 	// +++++++++++++++++++++ requested IP address +++++++++++++++++++++++++++++++++/
       
   702 	v4Msg->AddOptionL(EDHCPRequestedIPAddr, KIp4AddrByteLength)->SetBigEndian(iCurrentAddress.Address());
       
   703 	
       
   704 	// +++++++++++++++++++++ server ID ++++++++++++++++++++++++++++++++++++++++++++/
       
   705 	v4Msg->AddOptionL(EDHCPServerID, KIp4AddrByteLength)->SetBigEndian(iDHCPServerID.Address());
       
   706 	
       
   707 	// +++++++++++++++++++++ FQDN update request ++++++++++++++++++++++++++++++++++/
       
   708 	CreateFqdnUpdateRequestL();	
       
   709 	}
       
   710 
       
   711 
       
   712 void CDHCPIP4StateMachine::CreateRebootRequestMsgL()
       
   713 /**
       
   714   * Puts the specifics of a reboot request message
       
   715   * into the message buffer 
       
   716   *
       
   717   * @internalTechnology
       
   718   */
       
   719 	{
       
   720 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::CreateRebootRequestMsgL")));
       
   721 	
       
   722 	iTaskStartedAt.HomeTime();	// set time stamp to now
       
   723 	iMessageSender->SetTaskStartedTime(iTaskStartedAt);
       
   724 	iXid.SetXid(static_cast<TUint32>(iXid.Rnd(0,KMaxTInt)));
       
   725 	SetMessageHeaderL(EDHCPRequest);
       
   726 
       
   727 	CDHCPMessageHeaderIP4* v4Msg = DhcpMessage();
       
   728 	
       
   729 	// +++++++++++++++++++++ requested IP address +++++++++++++++++++++++++++++++++/
       
   730 	v4Msg->AddOptionL(EDHCPRequestedIPAddr, KIp4AddrByteLength)->SetBigEndian(iCurrentAddress.Address());
       
   731 	}
       
   732 
       
   733 
       
   734 void CDHCPIP4StateMachine::CreateInformMsgL()
       
   735 /**
       
   736   * Puts the specifics of an inform message
       
   737   * into the message buffer
       
   738   *
       
   739   * @internalTechnology
       
   740   */
       
   741 	{
       
   742 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::CreateInformMsgL")));
       
   743 	 
       
   744 	iXid.SetXid(static_cast<TUint32>(iXid.Rnd(0,KMaxTInt)));
       
   745 	iTaskStartedAt.HomeTime();	// set time stamp to now
       
   746 	SetMessageHeaderL(EDHCPInform);
       
   747 
       
   748 	CDHCPMessageHeaderIP4* v4Msg = DhcpMessage();
       
   749 	v4Msg->SetCIAddr(iCurrentAddress.Address());
       
   750 	//v4Msg->SetFlags(0);		// indicates that the response should be unicast back
       
   751 	
       
   752 	}
       
   753 
       
   754 void CDHCPIP4StateMachine::CreateRenewRequestMsgL()
       
   755 /**
       
   756   * Puts the specifics of the renew message
       
   757   * into the mesage buffer
       
   758   *
       
   759   * @internalTechnology
       
   760   */
       
   761 	{
       
   762 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::CreateRenewRequestMsgL")));
       
   763 	
       
   764 	 if(iTaskStartedAt != 0)
       
   765 		{
       
   766 		iTaskStartedAt.HomeTime();
       
   767 		iMessageSender->SetTaskStartedTime(iTaskStartedAt);
       
   768 		}
       
   769 	SetMessageHeaderL(EDHCPRequest);
       
   770 
       
   771 	CDHCPMessageHeaderIP4* v4Msg = DhcpMessage();
       
   772 	v4Msg->SetCIAddr(iCurrentAddress.Address());
       
   773 	v4Msg->SetFlags(0);		// indicates that the response should be unicast back
       
   774 	}	
       
   775 
       
   776 void CDHCPIP4StateMachine::CreateRebindRequestMsgL()
       
   777 /**
       
   778   * Puts the specifics of the rebind message
       
   779   * into the mesage buffer which happened to be the same as the renew message
       
   780   *
       
   781   * @internalTechnology
       
   782   */
       
   783    {
       
   784 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::CreateRebindRequestMsgL")));
       
   785    CDHCPIP4StateMachine::CreateRenewRequestMsgL(); //to avoid virtual call generation
       
   786    }
       
   787 
       
   788 void CDHCPIP4StateMachine::CreateReleaseMsgL()
       
   789 /**
       
   790   * Puts the specifics of the release message
       
   791   * into the message buffer
       
   792   * 
       
   793   * @internalTechnology
       
   794   */
       
   795 	{
       
   796 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::CreateReleaseMsgL")));
       
   797 
       
   798 	SetMessageHeaderL(EDHCPReleaseMsg);
       
   799 	
       
   800 	CDHCPMessageHeaderIP4* v4Msg = DhcpMessage();
       
   801 	v4Msg->SetCIAddr(iCurrentAddress.Address());
       
   802 	v4Msg->SetFlags(0);		// probably don't need to set...as there is no respsonse...
       
   803 	
       
   804 	// +++++++++++++++++++++ server ID ++++++++++++++++++++++++++++++++++++++++++++/
       
   805 	v4Msg->AddOptionL(EDHCPServerID, KIp4AddrByteLength)->SetBigEndian(iDHCPServerID.Address());
       
   806 	//remove the configured address ater Completion of the Release Message
       
   807 	}
       
   808 
       
   809 void CDHCPIP4StateMachine::CreateDeclineMsgL()
       
   810 /**
       
   811   * Puts the specifics of the decline message
       
   812   * into the message buffer
       
   813   *
       
   814   * @internalTechnology
       
   815   */
       
   816 	{
       
   817 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::CreateDeclineMsgL")));
       
   818 	
       
   819 	SetMessageHeaderL(EDHCPDecline);
       
   820 
       
   821 	CDHCPMessageHeaderIP4* v4Msg = DhcpMessage();
       
   822 	
       
   823 	// +++++++++++++++++++++ server ID ++++++++++++++++++++++++++++++++++++++++++++/
       
   824 	v4Msg->AddOptionL(EDHCPServerID, KIp4AddrByteLength)->SetBigEndian(iDHCPServerID.Address());
       
   825 	
       
   826 	// +++++++++++++++++++++ requested IP address +++++++++++++++++++++++++++++++++/
       
   827 	v4Msg->AddOptionL(EDHCPRequestedIPAddr, KIp4AddrByteLength)->SetBigEndian(iCurrentAddress.Address());
       
   828 	RemoveConfiguredAddress();
       
   829 	iRetryDhcpIpCount++;
       
   830 	}
       
   831 
       
   832 #ifdef SYMBIAN_NETWORKING_DHCPSERVER
       
   833 void CDHCPIP4StateMachine::CreateOfferMsgL()
       
   834 /**
       
   835   *  CreateOfferMsgL
       
   836   *
       
   837   * Puts the specifics of the Offer message into the message buffer
       
   838   * 
       
   839   * @internalTechnology
       
   840   */
       
   841 	{
       
   842 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::CreateOfferMsgL")));
       
   843 
       
   844 	CDHCPMessageHeaderIP4* v4Msg = DhcpMessage();
       
   845 	iXid.SetXid(v4Msg->GetXid());
       
   846 	iTaskStartedAt.HomeTime();
       
   847 	// remember the client hardware address from message for later use
       
   848 	v4Msg->GetCHAddr(iClientHWAddr);
       
   849 	
       
   850 	// check if the broadcast flag is set for this client then we sent broadcast message to it
       
   851 	TUint16 flags  = v4Msg->GetFlags();
       
   852 	if(flags & KBroadCastFlagMask)
       
   853 		iBroadCastFlag = ETrue;
       
   854 
       
   855 	// Create DHCPOFFER message
       
   856 	iFlag = 0x8000;			
       
   857 	SetMessageHeaderAsServerL(EDHCPOffer);	
       
   858 	
       
   859 	// generate the client IP addres that is to be offered to the client
       
   860 	TUint32 offeredAddress = GenerateClientIPAddress();
       
   861 	
       
   862 	if(iSvrState == ESvrWaitForAnyDHCPMsgs)
       
   863 		{
       
   864 		if(iInformClientAddr.Address())
       
   865 			v4Msg->SetYIAddr(iInformClientAddr.Address());
       
   866 		else
       
   867 			v4Msg->SetYIAddr(offeredAddress);
       
   868 		}
       
   869 	else
       
   870 		{
       
   871 		v4Msg->SetYIAddr(offeredAddress);
       
   872 		}	
       
   873 	SetClientIdentified(EFalse);	
       
   874 	AddMessageOptionsL();
       
   875 	}
       
   876 
       
   877 void CDHCPIP4StateMachine::HandleInformMsgL()
       
   878 /**
       
   879   *  HandleInformMsgL
       
   880   *
       
   881   * Handles DHCPInform message and sends DHCPAck
       
   882   * 
       
   883   * @internalTechnology
       
   884   */
       
   885 	{
       
   886 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::CreateResponseMsgL")));
       
   887 	
       
   888 	CDHCPMessageHeaderIP4* v4Msg = DhcpMessage();
       
   889 	
       
   890 	iXid.SetXid(v4Msg->GetXid());
       
   891 	iTaskStartedAt.HomeTime();
       
   892 	
       
   893 	v4Msg->GetCHAddr(iClientHWAddr);
       
   894 	
       
   895 	iCiaddr = v4Msg->GetCIAddr();
       
   896 	iYiaddr = v4Msg->GetYIAddr();
       
   897 	iFlag = 0x0000;	
       
   898 	
       
   899 	SetMessageHeaderAsServerL(EDHCPAck);	
       
   900 	iYiaddr = iCiaddr;
       
   901 	}
       
   902 
       
   903 void CDHCPIP4StateMachine::CheckClientParamListL()
       
   904 	{
       
   905 	CDHCPMessageHeaderIP4* v4Msg = DhcpMessage();
       
   906 	// check for the Parameter request list option code
       
   907 	DHCPv4::COptionNode* pOption = v4Msg->iOptions.FindOption(EDHCPParameterReqList);
       
   908 	
       
   909 	if(pOption)
       
   910 		{
       
   911 		TUint8* headerPtr = pOption->Ptr();	
       
   912 		
       
   913 		// const TUint8 KParamReqTypeOffset = 0; never used
       
   914 		const TUint8 KParamReqLengthOffset = 1;
       
   915 				
       
   916 		//  TUint encoding = headerPtr[KParamReqTypeOffset];   never used
       
   917 		TUint length = headerPtr[KParamReqLengthOffset]; // n octets
       
   918 	
       
   919 		TUint8* bodyPtr = pOption->GetBodyPtr();
       
   920 		
       
   921 		TUint paramReqAddrOffset;
       
   922 		TUint8 paramReqValue;
       
   923 		
       
   924 		for(TInt i=1; i <= length; i++)
       
   925 			{
       
   926 			// read the requested parameter list 
       
   927 			paramReqAddrOffset = 1 * i;	
       
   928 			Mem::Copy(&paramReqValue,(bodyPtr + paramReqAddrOffset),1);  
       
   929 			
       
   930 			AddParamRequestOptionL(paramReqValue);
       
   931 			}
       
   932 		}
       
   933 	}
       
   934 
       
   935 void CDHCPIP4StateMachine::AddParamRequestOptionL(TUint8 aParamReqValue)
       
   936 	{
       
   937 	CDHCPMessageHeaderIP4* v4Msg = DhcpMessage();
       
   938 	// default values determined to be used widely are provided by the DHCP server
       
   939 	// for these requested parameters
       
   940 	
       
   941 	// few of the widely requested options are provided, remainning options are ignored
       
   942 	switch(aParamReqValue)	
       
   943 		{
       
   944 	case EDHCPRouter:
       
   945 		v4Msg->AddOptionL(EDHCPRouter, KIp4AddrByteLength)->SetBigEndian(iCurrentAddress.Address());	
       
   946 		break;
       
   947 	case EDHCPBroadcastAddr:
       
   948 		v4Msg->AddOptionL(EDHCPBroadcastAddr, KIp4AddrByteLength)->SetBigEndian(KInetAddrBroadcast);	
       
   949 		break;	
       
   950 	case EDHCPServerID:
       
   951 		v4Msg->AddOptionL(EDHCPServerID,KIp4AddrByteLength)->SetBigEndian(iCurrentAddress.Address());	
       
   952 		break;
       
   953 	case EDHCPSubnetMask:
       
   954 		v4Msg->AddOptionL(EDHCPSubnetMask,KIp4AddrByteLength)->SetBigEndian(KInetAddrNetMaskC); 
       
   955 		break;	
       
   956 	case EDHCPEnd:
       
   957 		v4Msg->AddOptionL(EDHCPEnd, 0);
       
   958 		break;
       
   959 		}
       
   960 	}
       
   961 
       
   962 void CDHCPIP4StateMachine::HandleRequestMsgL()
       
   963 /**
       
   964   * CreateRequestResponseMsgL
       
   965   *
       
   966   * Creates DHCPACK or DHCPNAK in response to DHCPREQUEST (Renew, Rebind and Init-Reboot)
       
   967   * 
       
   968   * @internalTechnology
       
   969   */
       
   970 	{
       
   971 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::CreateRequestResponseMsgL")));
       
   972 	
       
   973 	CDHCPMessageHeaderIP4* v4Msg = DhcpMessage();
       
   974 	
       
   975 	iXid.SetXid(v4Msg->GetXid());
       
   976 	iTaskStartedAt.HomeTime();
       
   977 	
       
   978 	v4Msg->GetCHAddr(iClientHWAddr);
       
   979 
       
   980 	iCiaddr = v4Msg->GetCIAddr();
       
   981 	
       
   982 	// check if the broadcast flag is set for this client then we sent broadcast message to it
       
   983 	TUint16 flags  = v4Msg->GetFlags();
       
   984 	if(flags & KBroadCastFlagMask)
       
   985 		iBroadCastFlag = ETrue;
       
   986 	 
       
   987 	TUint32 offeredAddress = GetIPAddressToOffer();
       
   988 		
       
   989 	// Check the requested parameter list from client and provide them
       
   990 	CheckClientParamListL();
       
   991 	
       
   992 	TInetAddr reqIPAddress ;
       
   993 	reqIPAddress.SetAddress(v4Msg->iOptions.GetRequestedIPAddress());
       
   994 				
       
   995 	//Check if the message contains the Requested IPAddress 
       
   996 	if(reqIPAddress.Address())
       
   997 		{
       
   998 		//Compare the requested IP Address with the generated offered IP Address.
       
   999 		// If same as the offered IP Address,then send DHCPACK
       
  1000 		if(reqIPAddress.Address() == offeredAddress)
       
  1001 			{
       
  1002 			iFlag = 0x8000;			
       
  1003 			SetMessageHeaderAsServerL(EDHCPAck);
       
  1004 			iYiaddr = offeredAddress;
       
  1005 			v4Msg->SetYIAddr(iYiaddr);
       
  1006 			AddMessageOptionsL();
       
  1007 			}
       
  1008 		else
       
  1009 			{
       
  1010 			// cannot provide requested IP address
       
  1011 			iFlag = 0x8000;
       
  1012 			SetMessageHeaderAsServerL(EDHCPNak);
       
  1013 			}
       
  1014 		}
       
  1015 	else				
       
  1016 		{
       
  1017 		// No Requested IP address when DHCPRequest is received during
       
  1018 		// Renewal and Rebind of IPAddress
       
  1019 		iFlag = 0x0000;
       
  1020 		SetMessageHeaderAsServerL(EDHCPAck);
       
  1021 		iYiaddr = iCiaddr;
       
  1022 		v4Msg->SetYIAddr(iYiaddr);
       
  1023 		AddMessageOptionsL();
       
  1024 	   	}
       
  1025 	}
       
  1026 
       
  1027 TUint32 CDHCPIP4StateMachine::GetIPAddressToOffer()
       
  1028 	{
       
  1029 	TUint32 offeredAddress;
       
  1030 	// check if we ever offered any client which was statically configured
       
  1031 	// and we responded to DHCPINFORM from it
       
  1032 	// We offer the same IP address to any second client so that if the first client
       
  1033 	// existed then the second client fails with DAD
       
  1034 	if(iSvrState == ESvrWaitForAnyDHCPMsgs)
       
  1035 		{
       
  1036 		if(iInformClientAddr.Address())
       
  1037 			offeredAddress = iInformClientAddr.Address();
       
  1038 		else 
       
  1039 			offeredAddress = GenerateClientIPAddress();
       
  1040 		}
       
  1041 	else
       
  1042 		{
       
  1043 		// Generate a valid IP address which can be offered to the client 
       
  1044 		offeredAddress = GenerateClientIPAddress();
       
  1045 		}
       
  1046 #ifdef SYMBIAN_DNS_PROXY	
       
  1047 	iOfferedAddress = offeredAddress;
       
  1048 #endif
       
  1049 	return offeredAddress;	
       
  1050 	}
       
  1051 
       
  1052 void CDHCPIP4StateMachine::AddMessageOptionsL()
       
  1053 /**
       
  1054   * AddMessageOptionsL
       
  1055   *
       
  1056   * Adds Lease Time,Renew Time and Rebind Time options
       
  1057   * 
       
  1058   * @internalTechnology
       
  1059   */
       
  1060 	{
       
  1061 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::AddMessageOptionsL")));
       
  1062 	
       
  1063 	CDHCPMessageHeaderIP4* v4Msg = DhcpMessage();
       
  1064 
       
  1065 // Providing support for handling custom lease time being set for DHCP server
       
  1066 // in DEBUG builds using RProperty API's
       
  1067 	TInt defLeaseTime;
       
  1068 #ifdef _DEBUG
       
  1069 	RProperty::Get(KMyPropertyCat, KMyDefaultLeaseTime, defLeaseTime);
       
  1070 #else
       
  1071 	defLeaseTime = KDefaultLeaseTime;
       
  1072 #endif
       
  1073 	// +++++++++++++++++ Default Fixed Lease Time - 6 hours ++++++++++++++++++++++++++++++++++++++++/
       
  1074 	v4Msg->AddOptionL(EDHCPLeaseTime, KIp4AddrByteLength)->SetBigEndian(defLeaseTime);
       
  1075 	// +++++++++++++++++ Renewal Time (T1) - 50% of Lease time ++++++++++++++++++++++++++++++++++++++++/				
       
  1076 	v4Msg->AddOptionL(EDHCPRenewalT1,KIp4AddrByteLength)->SetBigEndian(defLeaseTime/2);
       
  1077 	// +++++++++++++++++ Rebind Time (T2) - 75% of Lease time ++++++++++++++++++++++++++++++++++++++++/				
       
  1078 	v4Msg->AddOptionL(EDHCPRebindT2,KIp4AddrByteLength)->SetBigEndian(defLeaseTime/2+defLeaseTime/4);
       
  1079 	// These are the options which the client might ask later
       
  1080 	// Simplified DHCP server is not capable of generating values for these option codes
       
  1081 	// They will be set later using Ioctl() call
       
  1082 	v4Msg->AddOptionL(EDHCPNameServer,KIp4AddrByteLength);		
       
  1083 	v4Msg->AddOptionL(EDHCPSIPServers,KIp4AddrByteLength);		
       
  1084 		
       
  1085 	if(!iDNSInformation)
       
  1086 		{
       
  1087 		v4Msg->AddOptionL(EDHCPDomainNameServer,KIp4AddrByteLength);
       
  1088 		
       
  1089 #ifdef SYMBIAN_DNS_PROXY
       
  1090 		if(iProxyDnsSrvAddr.Address())		
       
  1091 		   v4Msg->AddOptionL(EDHCPDomainNameServer,KIp4AddrByteLength)->SetBigEndian(iProxyDnsSrvAddr.Address());
       
  1092 		if(iProxyDomainName.Length())
       
  1093 		   v4Msg->AddOptionL(EDHCPDomainName, iProxyDomainName.Length())->GetBodyDes().Copy(iProxyDomainName);
       
  1094 #endif
       
  1095 		}
       
  1096 	else
       
  1097 		{
       
  1098 		// point to the option code value in the raw option buffer
       
  1099 		TPtr8 dnsPtr(const_cast<TUint8*>(iDNSInformation->Ptr()), iDNSInformation->Length(), iDNSInformation->Length());
       
  1100 		dnsPtr.Set((TUint8*)(dnsPtr.Ptr()+1),dnsPtr.Length()-1,dnsPtr.MaxLength()-1);
       
  1101 	
       
  1102 		v4Msg->AddOptionL(EDHCPDomainNameServer,dnsPtr.Length())->GetBodyDes().Copy(dnsPtr);
       
  1103 		}
       
  1104 	}
       
  1105 
       
  1106 #endif // SYMBIAN_NETWORKING_DHCPSERVER
       
  1107 	
       
  1108 TInt CDHCPIP4StateMachine::CreateIPv4LinkLocal()
       
  1109 /**
       
  1110   * Notifies the TCP/IP6 stack whenever the assignment process fails
       
  1111   * so that a link local may be created.
       
  1112   * 
       
  1113   *
       
  1114   * @internalTechnology
       
  1115   */
       
  1116 	{
       
  1117 	__CFLOG( KLogSubSysDHCP, KLogCode, _L8( "CDHCPIP4StateMachine::CreateIPv4LinkLocal" ) );
       
  1118 
       
  1119 	iSocket.Close();	
       
  1120 	
       
  1121 	TInt err = iSocket.Open(iEsock, KAfInet, KSockDatagram, KProtocolInetUdp, iConnection);
       
  1122 	
       
  1123 	if( err == KErrNone )
       
  1124 		{
       
  1125 		// make socket invisible for interface counting
       
  1126 		(void)iSocket.SetOpt(KSoKeepInterfaceUp, KSolInetIp, 0);
       
  1127 
       
  1128 		TPckgBuf<TSoInet6InterfaceInfo> configInfo;
       
  1129 
       
  1130 		configInfo().iHwAddr = iHardwareAddr;
       
  1131 		configInfo().iName = iInterfaceName;
       
  1132 		configInfo().iDelete = EFalse;
       
  1133 		configInfo().iAlias = EFalse;
       
  1134 		configInfo().iDoId = EFalse;
       
  1135 		configInfo().iState = EIfUp;
       
  1136 		configInfo().iDoState = ETrue;
       
  1137 		
       
  1138 		// zero value better than junk value
       
  1139 		configInfo().iMtu = 0;
       
  1140 		configInfo().iSpeedMetric = 0;
       
  1141 		configInfo().iFeatures = 0; 
       
  1142 
       
  1143 		err = iSocket.SetOpt( KSoInetCreateIPv4LLOnInterface, KSolInetIfCtrl, configInfo );
       
  1144 		}
       
  1145 		
       
  1146 	return err;
       
  1147 	}
       
  1148 
       
  1149 void CDHCPIP4StateMachine::HandleOfferL()
       
  1150 /**
       
  1151   * Handles an offer from a dhcp server, providing
       
  1152   * an offer of configuration parameters
       
  1153   *
       
  1154   * @internalTechnology
       
  1155   *
       
  1156   */
       
  1157 	{
       
  1158 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::HandleOffer")));
       
  1159 	
       
  1160 	CDHCPMessageHeaderIP4* v4Msg = DhcpMessage();
       
  1161 	// at this stage just the offered ip address is set into the current address for efficiency
       
  1162 	iCurrentAddress.SetAddress(v4Msg->GetYIAddr());	
       
  1163 	
       
  1164 	TUint32 addr = v4Msg->iOptions.GetServerId();
       
  1165 	if ( !addr )
       
  1166 		User::Leave(KErrNotFound);
       
  1167 	iDHCPServerID.SetAddress(addr);
       
  1168 	}
       
  1169 
       
  1170 CDHCPState* CDHCPIP4StateMachine::HandleReplyL( TRequestStatus* aStatus )
       
  1171 {
       
  1172 	iReceiving = EFalse;
       
  1173 	
       
  1174 	TInt err = KErrNone;
       
  1175 
       
  1176 	if (CheckXid())
       
  1177 		{
       
  1178 		switch (GetMessageTypeL())
       
  1179 			{
       
  1180 			case EDHCPAck:
       
  1181 #ifdef SYMBIAN_NETWORKING_DHCP_MSG_HEADERS 	
       
  1182 				if (!iDhcpInformAckPending)
       
  1183 				{
       
  1184 #endif//SYMBIAN_NETWORKING_DHCP_MSG_HEADERS	
       
  1185 				HandleAckL();
       
  1186 #ifdef SYMBIAN_NETWORKING_DHCP_MSG_HEADERS 					
       
  1187 				}
       
  1188 #endif//SYMBIAN_NETWORKING_DHCP_MSG_HEADERS	
       
  1189 
       
  1190 				break;
       
  1191 			case EDHCPNak:
       
  1192 				err = KErrAccessDenied;
       
  1193 
       
  1194 				break;
       
  1195 			default:
       
  1196 				return ReceiveL(aStatus);
       
  1197 			}
       
  1198 		}
       
  1199 	else
       
  1200 		{
       
  1201 		return ReceiveL(aStatus);
       
  1202 		}
       
  1203 		
       
  1204 	User::RequestComplete(aStatus, err);
       
  1205 	
       
  1206 	if( err == KErrNone )
       
  1207 	{
       
  1208 		return static_cast<CDHCPState*>(iActiveEvent->Next());
       
  1209 	}
       
  1210 	
       
  1211 	return NULL;
       
  1212 }
       
  1213 
       
  1214 void CDHCPIP4StateMachine::HandleAckL()
       
  1215 /**
       
  1216   * Handles an acknowledgement from a dhcp server, storing
       
  1217   * configuration parameters and a committed ip address
       
  1218   *
       
  1219   * @internalTechnology
       
  1220   *
       
  1221   */
       
  1222 	{
       
  1223 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::HandleAck")));
       
  1224 	
       
  1225 	if(iRetryDhcpIpCount >= KDHCPv4MaxRetryCount)
       
  1226  	{
       
  1227 	TPckgBuf<TSoInetInterfaceInfo> opt;
       
  1228 	TInetAddr addr;
       
  1229 	while (iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, opt) == KErrNone)
       
  1230 		{
       
  1231 	  	if (opt().iName == InterfaceName())
       
  1232 			{
       
  1233 		  	addr = opt().iAddress;
       
  1234 		  	if (addr.IsLinkLocal() && addr.IsV4Compat() )
       
  1235 		  		{
       
  1236 		  		RemoveConfiguredAddress(&addr);
       
  1237 		  		break;
       
  1238 		  		}
       
  1239 		  	}
       
  1240 		}
       
  1241 	}
       
  1242 	ConfigureInterfaceL();
       
  1243 
       
  1244 	CDHCPMessageHeaderIP4* v4Msg = DhcpMessage();
       
  1245 	if (!IsUsingStaticAddress())
       
  1246 		{
       
  1247 		iRenewalTimeT1 = v4Msg->iOptions.GetRenewalTime();
       
  1248 		iRebindTimeT2 = v4Msg->iOptions.GetRebindTime();
       
  1249 		iLeaseTime = v4Msg->iOptions.GetLeaseTime();
       
  1250 		
       
  1251 		#ifdef _LOG
       
  1252 			TBuf<39> addrStr;
       
  1253 			
       
  1254 			TInetAddr( v4Msg->GetYIAddr(), 0 ).Output( addrStr );
       
  1255 			
       
  1256 			__CFLOG_1( KLogSubSysDHCP, KLogCode, _L( "DHCP server assigned client IP address %S" ), &addrStr );
       
  1257 		#endif
       
  1258 		
       
  1259 #ifdef _DEBUG
       
  1260 		if (CDHCPServer::DebugFlags() & KDHCP_SetShortLease)
       
  1261 			{
       
  1262 			iLeaseTime = KDHCP_ShortLeaseLeaseTime;
       
  1263 			iRenewalTimeT1 = KDHCP_ShortLeaseRenewTime;
       
  1264 			iRebindTimeT2 = KDHCP_ShortLeaseRebindTime;
       
  1265 			CDHCPServer::DebugFlags() &= ~( KDHCP_SetShortLease | KDHCP_SetShortRetryTimeOut );	// we only want this to have an affect the first time...
       
  1266 			}
       
  1267 #endif
       
  1268 		// -- Infinite leases -- INC078424 --
       
  1269 		//
       
  1270 		// This block caters for the following 2 cases:
       
  1271 		//  1. Server sent 0 lease time, meaning "forever". This behaviour wasn't defined in the 
       
  1272 		//     original RFC but many servers work this way so we need to support it.
       
  1273 		//  2. Server sent extremely large lease time (e.g. 0xffffffff as specified in RFC).
       
  1274 		//     As TTimeIntervalSeconds has a maximum of 0x7fffffff, we must enforce this maximum.
       
  1275 		//
       
  1276 		if ( iLeaseTime == 0 || iLeaseTime > KReallyLongLease )
       
  1277 			{
       
  1278 			iLeaseTime = KReallyLongLease;  // 68 years should be long enough
       
  1279 			}
       
  1280 			
       
  1281 		if (iRenewalTimeT1 == iRebindTimeT2)
       
  1282 			{
       
  1283 			// may have only been provided with a lease time...
       
  1284 			// we need time to renew the lease before it runs out
       
  1285 			// so we'd better set some times from the overall lease time
       
  1286 			
       
  1287 			__CFLOG_VAR((KLogSubSysDHCP, KLogCode,
       
  1288 				_L8("Invalid Renew/Rebind times received: (RenewT1: %d, RebindT2: %d, Lease: %d)"),
       
  1289 						iRenewalTimeT1, iRebindTimeT2, iLeaseTime));
       
  1290 						
       
  1291 			TUint32 temp = iLeaseTime/4;
       
  1292 			iRenewalTimeT1=iLeaseTime/2;
       
  1293 			iRebindTimeT2=iRenewalTimeT1+temp;		
       
  1294 			
       
  1295 			__CFLOG_VAR((KLogSubSysDHCP, KLogCode,
       
  1296 				_L8("New Renew/Rebind Time calculated: (RenewT1: %d, RebindT2: %d)"),
       
  1297 						iRenewalTimeT1, iRebindTimeT2));	
       
  1298 						
       
  1299 			}
       
  1300 		else if (iRenewalTimeT1<iRebindTimeT2 && iRebindTimeT2<iLeaseTime)
       
  1301 			{
       
  1302 			// do nothing as we have got the valid values we were expecting
       
  1303 			__CFLOG_VAR((KLogSubSysDHCP, KLogCode,
       
  1304 				_L8("Times received from server: (RenewT1: %d, RebindT2: %d, lease: %d)"),
       
  1305 						iRenewalTimeT1, iRebindTimeT2, iLeaseTime));
       
  1306 			}
       
  1307 		else
       
  1308 			{
       
  1309 			__CFLOG_VAR((KLogSubSysDHCP, KLogCode,
       
  1310 					_L8("HandleAckL Error: invalid times received from server (RenewT1: %d, RebindT2: %d, lease: %d)"),
       
  1311 							iRenewalTimeT1, iRebindTimeT2, iLeaseTime));
       
  1312 			User::Leave(KErrArgument);
       
  1313 			}	
       
  1314 		
       
  1315 		}
       
  1316 
       
  1317 	delete iHostName;
       
  1318 	delete iDomainName;
       
  1319 	iHostName = NULL;
       
  1320 	iDomainName = NULL;
       
  1321 
       
  1322 	v4Msg->iOptions.CopyHostNameL(iHostName);
       
  1323 	v4Msg->iOptions.CopyDomainNameL(iDomainName);
       
  1324 	}
       
  1325 
       
  1326 #ifdef _DEBUG
       
  1327 TInt CDHCPIP4StateMachine::GetDestPort()
       
  1328 	{
       
  1329 	TInt destPort;
       
  1330 	User::LeaveIfError(RProperty::Get(KMyPropertyCat, KMyPropertyDestPortv4, destPort));
       
  1331 	return destPort;
       
  1332 	}
       
  1333 #endif
       
  1334 
       
  1335 void CDHCPIP4StateMachine::InitialiseSocketL()
       
  1336 /**
       
  1337   * Sets up socket, by opening one associated with the connection
       
  1338   * and sets the interface to use for traffic
       
  1339   *
       
  1340   * @internalTechnology
       
  1341   *
       
  1342   */
       
  1343 	{
       
  1344 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::InitialiseSocketL")));
       
  1345 	
       
  1346 	iSocket.Close();
       
  1347 	
       
  1348 	User::LeaveIfError(iSocket.Open(iEsock, KAfInet, KSockDatagram, KProtocolInetUdp, iConnection));
       
  1349 	User::LeaveIfError(iSocket.SetOpt(KSoReuseAddr, KSolInetIp, 1));
       
  1350 #ifndef _DEBUG
       
  1351 	User::LeaveIfError(iSocket.SetLocalPort(KDhcpSrcPort));
       
  1352 #else
       
  1353 	User::LeaveIfError(iSocket.SetLocalPort(GetDestPort() + 1));
       
  1354 #endif
       
  1355     TInetAddr existingGlobalAddr = this->GetInterfaceGlobalAddress();
       
  1356     if( existingGlobalAddr.IsUnspecified() || existingGlobalAddr.IsLinkLocal() )
       
  1357     	{
       
  1358     	User::LeaveIfError(iSocket.SetOpt(KSoNoSourceAddressSelect, KSolInetIp, 1));
       
  1359     	}
       
  1360 	// make socket invisible for interface counting
       
  1361 	User::LeaveIfError(iSocket.SetOpt(KSoKeepInterfaceUp, KSolInetIp, 0));
       
  1362 	
       
  1363 	TPckgBuf<TSoInetIfQuery> query;
       
  1364 	query().iName = iInterfaceName;
       
  1365 	User::LeaveIfError(iSocket.GetOpt(KSoInetIfQueryByName, KSolInetIfQuery, query));
       
  1366 	User::LeaveIfError(iSocket.SetOpt(KSoInterfaceIndex, KSolInetIp, query().iIndex));
       
  1367 	User::LeaveIfError(iSocket.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl));
       
  1368 	// loopback of broadcast/multicast packets to the stack is disabled
       
  1369 	User::LeaveIfError(iSocket.SetOpt(KSoIp6MulticastLoop, KSolInetIp, 0));
       
  1370 	}
       
  1371 
       
  1372 void CDHCPIP4StateMachine::RemoveConfiguredAddress(const TInetAddr * aAddr)
       
  1373 /**
       
  1374   * This function can be called as a result of DAD failing
       
  1375   * or the lease expiring! It removes the address from the interface
       
  1376   * inside the TCP/IP6 stack as the address cannot continue to be used.
       
  1377   *
       
  1378   * @see "Implementation of IPv4/IPv6 Basic Socket API for Symbian OS"
       
  1379   * document for explanation of TSoInet6InterfaceInfo and its use
       
  1380   * @internalTechnology
       
  1381   */
       
  1382 	{
       
  1383 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::RemoveConfiguredAddress")));
       
  1384 	
       
  1385 	TSoInet6InterfaceInfo interfaceInfo;
       
  1386 	interfaceInfo.iHwAddr = iHardwareAddr;
       
  1387 	if(aAddr)
       
  1388 		{
       
  1389 		interfaceInfo.iAddress.SetV4MappedAddress(aAddr->Address());
       
  1390 		interfaceInfo.iState = EIfDown;
       
  1391 		}
       
  1392 	else
       
  1393 		{
       
  1394 		interfaceInfo.iAddress.SetV4MappedAddress(iCurrentAddress.Address());
       
  1395 		interfaceInfo.iState = EIfUp;	
       
  1396 		}
       
  1397 	interfaceInfo.iDefGate.SetV4MappedAddress(iDefGateway.Address());
       
  1398 	interfaceInfo.iName = iInterfaceName;
       
  1399 	interfaceInfo.iDelete = ETrue;
       
  1400 	interfaceInfo.iAlias = EFalse;
       
  1401 	interfaceInfo.iDoId = ETrue;
       
  1402 	
       
  1403 	interfaceInfo.iDoState = ETrue;
       
  1404 	interfaceInfo.iDoAnycast = EFalse;
       
  1405 	
       
  1406 	// zero value better than junk value
       
  1407 	interfaceInfo.iMtu = 0;
       
  1408 	interfaceInfo.iSpeedMetric = 0;
       
  1409 	interfaceInfo.iFeatures = 0; 
       
  1410     CDHCPStateMachine::RemoveConfiguredAddress( interfaceInfo );
       
  1411     
       
  1412 	// Clear the DHCP server address now that we no longer have a lease.
       
  1413     iDHCPServerAddr.SetAddress( KInet6AddrNone );
       
  1414     //clear the client address & lease time
       
  1415    	iCurrentAddress = TInetAddr();
       
  1416    	iLeaseTime = 0;
       
  1417 
       
  1418 	}
       
  1419 
       
  1420 void CDHCPIP4StateMachine::AssignAddresses( TInetAddr& aDest, const TInetAddr& aSrc ) const
       
  1421 {
       
  1422 	aDest.SetFamily(KAfInet);
       
  1423 	aDest.SetAddress(aSrc.Address());
       
  1424 #ifdef SYMBIAN_NETWORKING_DHCPSERVER
       
  1425 	if(iServerImpl)
       
  1426 		{
       
  1427 // The DHCP server can listen on custom ports
       
  1428 // Supported only on DEBUG builds
       
  1429 #ifdef _DEBUG
       
  1430 		aDest.SetPort(GetDestPort());
       
  1431 #else
       
  1432 		aDest.SetPort(KDhcpServerPort);
       
  1433 #endif
       
  1434 		}
       
  1435 	else
       
  1436 #endif // SYMBIAN_NETWORKING_DHCPSERVER	
       
  1437 #ifndef _DEBUG
       
  1438 	aDest.SetPort(KDhcpSrcPort);
       
  1439 #else
       
  1440 	{
       
  1441 	// Simulate initialisation, renewal or rebind failure by using the wrong port.
       
  1442 	if( ( CDHCPServer::DebugFlags() & KDHCP_FailDiscover ) || ( CDHCPServer::DebugFlags() & KDHCP_FailRenew ) || ( CDHCPServer::DebugFlags() & KDHCP_FailRebind ) )
       
  1443 		{
       
  1444 		aDest.SetPort(KDhcpWrongSrcPort);
       
  1445 		}
       
  1446 	else
       
  1447 		{
       
  1448 		aDest.SetPort(GetDestPort() + 1);
       
  1449 		}
       
  1450 	}
       
  1451 #endif
       
  1452 	
       
  1453 }
       
  1454 
       
  1455 void CDHCPIP4StateMachine::BindSocketForUnicastL()
       
  1456 /**
       
  1457   * Open a new socket and bind it to the configured source address
       
  1458   * ready for a unicast renew message
       
  1459   *
       
  1460   * @internalTechnology
       
  1461   */
       
  1462 	{
       
  1463     __CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPStateMachine::BindSocketForRenewL")));
       
  1464     iSocket.Close();	// destroy the old socket
       
  1465 
       
  1466     UpdateHistory(CDHCPState::EBindToSource);
       
  1467     // Start a new one.
       
  1468     User::LeaveIfError(iSocket.Open(iEsock, KAfInet, KSockDatagram, KProtocolInetUdp, iConnection));
       
  1469 	User::LeaveIfError(iSocket.SetOpt(KSoReuseAddr, KSolInetIp, 1));
       
  1470     TInetAddr bindTo;
       
  1471     AssignAddresses( bindTo, iCurrentAddress );
       
  1472 
       
  1473     User::LeaveIfError(iSocket.Bind(bindTo));
       
  1474 
       
  1475 	// So we can still receive packets from naughty servers who send broadcasts back to 
       
  1476 	//  unicast requests, we do this:
       
  1477 	User::LeaveIfError(iSocket.SetOpt(KSoNoSourceAddressSelect, KSolInetIp, 1));
       
  1478 	User::LeaveIfError(iSocket.SetOpt(KSoUdpAddressSet, KSolInetUdp, 0));
       
  1479 	// make socket invisable for interface counting
       
  1480 	User::LeaveIfError(iSocket.SetOpt(KSoKeepInterfaceUp, KSolInetIp, 0));
       
  1481 	}
       
  1482 
       
  1483 void CDHCPIP4StateMachine::ConfigureInterfaceL()
       
  1484 /**
       
  1485   * Set the interface IP address and other params
       
  1486   * into the TCP/IP6 stack.
       
  1487   *
       
  1488   * What we set depends on the setup
       
  1489   * in commDB for the service.  If ipAddressFromServer
       
  1490   * is true then we set the ip address that has
       
  1491   * been assigned by DHCP, along with the netmask and gateway.
       
  1492   * If ipAddressFromServer is false, then we set the static ip
       
  1493   * address as long as it has been okayed by the DHCP server after
       
  1494   * we have sent an inform.  We will then set the netmask and gateway
       
  1495   * choosing from those in commDB if they have been given values, or 
       
  1496   * those returned in the DHCP Server ACK if a zero address is in commDB
       
  1497   * The same principle applies to DNS Server addresses.
       
  1498   *
       
  1499   * @internalTechnology
       
  1500   */
       
  1501 	{
       
  1502 
       
  1503 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::ConfigureInterfaceL - Cancel Message Sender")));
       
  1504 	iMessageSender->Cancel();
       
  1505 
       
  1506 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::ConfigureInterfaceL - KSoNoSourceAddressSelect")));
       
  1507 	User::LeaveIfError(iSocket.SetOpt(KSoNoSourceAddressSelect, KSolInetIp, 0));
       
  1508 
       
  1509 	TSoInet6InterfaceInfo interfaceInfo;
       
  1510 	
       
  1511 	CDHCPMessageHeaderIP4* v4Msg = DhcpMessage();
       
  1512 
       
  1513 	if (!IsUsingStaticAddress())
       
  1514 		{
       
  1515 		iCurrentAddress.SetAddress(v4Msg->GetYIAddr());
       
  1516 		iServerAddress = v4Msg->iOptions.GetServerId();
       
  1517 		
       
  1518 		TInetAddr nullAddr;  //creates unspecif. (null) address
       
  1519 
       
  1520 		// we want to use CommDb settings if present
       
  1521 		// but those ifs aren't the solution for that as
       
  1522 		// these values will potentially fail for renegotiation
       
  1523 		// for now we should live with this, as there is no time
       
  1524 		// to change it.
       
  1525 		if (iSubnetMask.Match(nullAddr))
       
  1526 			{
       
  1527 			iSubnetMask.SetAddress(v4Msg->iOptions.GetSubnetMask());
       
  1528 			}
       
  1529 
       
  1530 		if (iBroadcastAddress.Match(nullAddr))
       
  1531 			{
       
  1532 			iBroadcastAddress.SetV4MappedAddress(v4Msg->iOptions.GetBroadcastAddress());
       
  1533 			}
       
  1534 		
       
  1535 		if (iDefGateway.Match(nullAddr))
       
  1536 			{
       
  1537 			iDefGateway.SetV4MappedAddress(v4Msg->iOptions.GetRouterAddress());
       
  1538 			}		
       
  1539 		}
       
  1540 
       
  1541 	if( iNameServerAddressesFromServer )
       
  1542 		{	
       
  1543 		TInt num = v4Msg->iOptions.NumberOfDomainServers();
       
  1544 		if (num>0)
       
  1545 			{
       
  1546 			iNameServer1.SetAddress(v4Msg->iOptions.GetDomainNameServer(0));
       
  1547 			if (num>1)
       
  1548 				{
       
  1549 				iNameServer2.SetAddress(v4Msg->iOptions.GetDomainNameServer(1));
       
  1550 				}
       
  1551 			}
       
  1552 		}
       
  1553 
       
  1554 	
       
  1555 	interfaceInfo.iHwAddr = iHardwareAddr;
       
  1556 	interfaceInfo.iAddress.SetV4MappedAddress(iCurrentAddress.Address());
       
  1557 	interfaceInfo.iNetMask.SetAddress(iSubnetMask.Address());
       
  1558 	interfaceInfo.iBrdAddr.SetV4MappedAddress(iBroadcastAddress.Address());
       
  1559 	interfaceInfo.iDefGate.SetV4MappedAddress(iDefGateway.Address());
       
  1560 	if( iNameServerAddressesFromServer )
       
  1561 		{
       
  1562 		interfaceInfo.iNameSer1.SetV4MappedAddress(iNameServer1.Address());
       
  1563 		interfaceInfo.iNameSer2.SetV4MappedAddress(iNameServer2.Address());	
       
  1564 		}
       
  1565 	else
       
  1566 		{
       
  1567 		//We need to set the family to KAFUnspec to ensure that the Stack does not overwrite the existing address
       
  1568 		interfaceInfo.iNameSer1.SetFamily(KAFUnspec);
       
  1569 		interfaceInfo.iNameSer2.SetFamily(KAFUnspec);
       
  1570 		}
       
  1571 	interfaceInfo.iName = iInterfaceName;
       
  1572 	interfaceInfo.iMtu = 0;
       
  1573 	interfaceInfo.iSpeedMetric = 0;
       
  1574 	interfaceInfo.iFeatures = 0; // zero value better than junk value
       
  1575 	
       
  1576 	interfaceInfo.iState = EIfUp;
       
  1577 	
       
  1578 	interfaceInfo.iDelete = EFalse;
       
  1579 	interfaceInfo.iAlias = EFalse;
       
  1580 	interfaceInfo.iDoId = ETrue;
       
  1581 	interfaceInfo.iDoState = ETrue;
       
  1582 	interfaceInfo.iDoAnycast = EFalse;
       
  1583 	interfaceInfo.iDoProxy = EFalse;
       
  1584 
       
  1585 	CDHCPStateMachine::ConfigureInterfaceL( interfaceInfo );
       
  1586 	}
       
  1587 
       
  1588 void CDHCPIP4StateMachine::CreateFqdnUpdateRequestL()
       
  1589 	{	
       
  1590 #ifndef SYMBIAN_COMMS_REPOSITORY
       
  1591 	CCommsDatabase* commDb = CCommsDatabase::NewL();
       
  1592 	CleanupStack::PushL(commDb);
       
  1593 	
       
  1594 	CCommsDbTableView* tableView = commDb->OpenViewMatchingUintLC(TPtrC16(NETWORK), TPtrC16(COMMDB_ID), GetNetworkIdL());
       
  1595 	
       
  1596 	TDomainName hostName;
       
  1597 	if (tableView->GotoFirstRecord() == KErrNone)
       
  1598 		{
       
  1599 		tableView->ReadTextL(TPtrC16(HOST_NAME), hostName);
       
  1600 		}
       
  1601 #else
       
  1602 #ifdef SYMBIAN_NON_SEAMLESS_NETWORK_BEARER_MOBILITY
       
  1603 	CMDBSession* session = CMDBSession::NewLC(KCDVersion1_2);
       
  1604 #else
       
  1605 	CMDBSession* session = CMDBSession::NewLC(KCDVersion1_1);
       
  1606 #endif
       
  1607 
       
  1608 	// Reveal hidden or private IAP records if a licensee has chosen to protect a record
       
  1609 	// using one of these flags - the API to do this is public so internal components
       
  1610 	// have to support the use of such records.
       
  1611 	session->SetAttributeMask(ECDHidden | ECDPrivate);
       
  1612 	
       
  1613 	CCDNetworkRecord* networkRecord = static_cast<CCDNetworkRecord*>(CCDRecordBase::RecordFactoryL(KCDTIdNetworkRecord));;
       
  1614 	CleanupStack::PushL(networkRecord);
       
  1615 	networkRecord->SetRecordId(GetNetworkIdL());
       
  1616   	networkRecord->LoadL(*session);
       
  1617 
       
  1618 	TDomainName hostName;
       
  1619 	hostName.Copy(networkRecord->iHostName);
       
  1620 #endif
       
  1621 		
       
  1622 	if (hostName.Length() > 0)
       
  1623 		{
       
  1624 		CDnsUpdateOption* dnsUpdateOption = new(ELeave) CDnsUpdateOption();
       
  1625 		CleanupStack::PushL(dnsUpdateOption);
       
  1626 		
       
  1627 		dnsUpdateOption->SetFlag(CDnsUpdateOption::EDnsUpdateFlagE);
       
  1628 		dnsUpdateOption->SetFlag(CDnsUpdateOption::EDnsUpdateFlagS);
       
  1629 		dnsUpdateOption->SetDomainName(hostName);
       
  1630 		
       
  1631 		RBuf8 optionData;
       
  1632 		optionData.CleanupClosePushL();
       
  1633 		
       
  1634 		dnsUpdateOption->ToStringL(optionData);
       
  1635 		
       
  1636 		CDHCPMessageHeaderIP4* v4Msg = DhcpMessage();
       
  1637 		COptionNode* optionNode = 
       
  1638 			v4Msg->AddOptionL(EDHCPDNSUpdate, optionData.Length());
       
  1639 		
       
  1640 		optionNode->SetBody(optionData);
       
  1641 		
       
  1642 		CleanupStack::PopAndDestroy(&optionData);
       
  1643 		CleanupStack::PopAndDestroy(dnsUpdateOption);
       
  1644 		}	
       
  1645 	
       
  1646 #ifndef SYMBIAN_COMMS_REPOSITORY
       
  1647 	CleanupStack::PopAndDestroy(2, commDb);
       
  1648 #else
       
  1649 	CleanupStack::PopAndDestroy(2, session);
       
  1650 #endif
       
  1651 	}
       
  1652 	
       
  1653 #ifdef SYMBIAN_NETWORKING_DHCPSERVER	
       
  1654 void CDHCPIP4StateMachine::InitialiseServerSocketL()
       
  1655 /**
       
  1656   * Sets up socket, by opening one associated with the connection
       
  1657   * and sets the interface to use for traffic
       
  1658   *%
       
  1659   * @internalTechnology
       
  1660   *
       
  1661   */
       
  1662 	{
       
  1663 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::InitialiseServerSocket")));
       
  1664 	
       
  1665 	iSvrSocket.Close();
       
  1666 	
       
  1667 	User::LeaveIfError(iSvrSocket.Open(iEsock, KAfInet, KSockDatagram, KProtocolInetUdp, iConnection));
       
  1668 	User::LeaveIfError(iSvrSocket.SetOpt(KSoReuseAddr, KSolInetIp, 1));
       
  1669 	
       
  1670 // The DHCP server can listen on custom ports
       
  1671 // Supported only on DEBUG builds
       
  1672 #ifdef _DEBUG
       
  1673 	User::LeaveIfError(iSvrSocket.SetLocalPort(GetDestPort()));
       
  1674 #else
       
  1675 	User::LeaveIfError(iSvrSocket.SetLocalPort(KDhcpServerPort));
       
  1676 #endif
       
  1677 	}
       
  1678 
       
  1679 	
       
  1680 void CDHCPIP4StateMachine::InitServerStateMachineL(MStateMachineNotify* aStateMachineNotify)
       
  1681 /**
       
  1682   * Reset the lower state machine for DHCP server implementation.
       
  1683   * Set the state machine to wait for client messages on port 67 and 
       
  1684   * to handle the messages
       
  1685   *
       
  1686   * @internalTechnology
       
  1687   */
       
  1688 	{
       
  1689 	ASSERT(!iFirstState);
       
  1690 	// after start up wait on port 67 for DHCP client msgs 
       
  1691 	iFirstState = new(ELeave) CDHCPIP4WaitForClientMsgs(*this);
       
  1692 	// handle the client messages
       
  1693 	CDHCPState* handleClientMsg = new(ELeave) CDHCPIP4HandleClientMsgs(*this);
       
  1694 	iFirstState->SetNext( handleClientMsg);
       
  1695 	
       
  1696 	CDHCPStateMachine::Start(aStateMachineNotify);
       
  1697 	}	
       
  1698 
       
  1699 void CDHCPIP4StateMachine::InitServerBinding(MStateMachineNotify* aStateMachineNotify)
       
  1700 /**
       
  1701   * 
       
  1702   *
       
  1703   * @internalTechnology
       
  1704   */
       
  1705 	{
       
  1706 	ASSERT(!iFirstState);
       
  1707 	// binds the server with the static IP address from Comms database
       
  1708 	iFirstState = new(ELeave) CDHCPIP4BindServer(*this);
       
  1709 
       
  1710 	CDHCPStateMachine::Start(aStateMachineNotify);
       
  1711 	}	
       
  1712 
       
  1713 
       
  1714 void CDHCPIP4StateMachine::ProcessDiscoverL()
       
  1715 /** Set the state machine to handle discover message using lower state machine
       
  1716   * discover-> offer -> request -> ack
       
  1717   *  
       
  1718   * @internalTechnology
       
  1719   */
       
  1720 	{
       
  1721 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::ProcessDiscoverL()")));
       
  1722 	
       
  1723 	// the active state was to handle the client message - here Discover message
       
  1724 	CDHCPState* handleDiscoverMsg = static_cast<CDHCPState*>(iActiveEvent); 
       
  1725 
       
  1726 #ifdef SYMBIAN_DNS_PROXY
       
  1727 	HBufC8*   hostName = HBufC8::NewLC(KMaxName);
       
  1728 	CDHCPMessageHeaderIP4* v4Msg = DhcpMessage();
       
  1729 	v4Msg->iOptions.CopyHostNameL(hostName);
       
  1730 	iClientHostName.Copy(hostName->Des());
       
  1731 	CleanupStack::PopAndDestroy(hostName);
       
  1732 #endif // SYMBIAN_DNS_PROXY	
       
  1733 	
       
  1734 	CDHCPState* provideOffer = new(ELeave) CDHCPIP4ProvideOffer(*this);
       
  1735     handleDiscoverMsg->SetNext( provideOffer );
       
  1736     			
       
  1737     CDHCPState* sendRequestResponse = new(ELeave) CDHCPIP4SendRequestResponse(*this);
       
  1738     provideOffer->SetNext( sendRequestResponse );
       
  1739     		
       
  1740     iSvrSpecificState = ESvrDiscoverInProgress;
       
  1741 	}
       
  1742 	
       
  1743 void CDHCPIP4StateMachine::ProcessInformL()
       
  1744 /** Set the state machine to handle inform message using lower state machine
       
  1745   * inform -> ack
       
  1746   *  
       
  1747   * @internalTechnology
       
  1748   */
       
  1749 	{
       
  1750 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::ProcessInformL()")));
       
  1751 
       
  1752 #ifdef SYMBIAN_DNS_PROXY
       
  1753 	ReadDhcpMsgParamsL();
       
  1754 #endif // SYMBIAN_DNS_PROXY		
       
  1755 	
       
  1756 	CDHCPState* handleInformMsg = static_cast<CDHCPState*>(iActiveEvent); 
       
  1757 				
       
  1758 	CDHCPState* sendInformResponse = new(ELeave) CDHCPIP4SendInformResponse(*this);
       
  1759 	handleInformMsg->SetNext(sendInformResponse);
       
  1760 		    
       
  1761 	iSvrSpecificState = ESvrInformInProgress;
       
  1762 	}
       
  1763     
       
  1764 void CDHCPIP4StateMachine::ProcessRequestL()
       
  1765 /** Set the state machine to handle Request message using lower state machine
       
  1766   * Request -> Ack / Nak
       
  1767   *  
       
  1768   * @internalTechnology
       
  1769   */
       
  1770 	{
       
  1771 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::ProcessRequestL()")));
       
  1772 		
       
  1773 	CDHCPState* handleRequestMsg = static_cast<CDHCPState*>(iActiveEvent); 
       
  1774 
       
  1775 	CDHCPState* sendRequestResponse = new(ELeave) CDHCPIP4SendRequestResponse(*this);
       
  1776     handleRequestMsg->SetNext(sendRequestResponse);
       
  1777 		    
       
  1778     iSvrSpecificState = ESvrRenewInProgress;
       
  1779 	}
       
  1780 			
       
  1781 
       
  1782 void CDHCPIP4StateMachine::CheckClientMsgL()
       
  1783 	{
       
  1784 	switch(GetClientMessageTypeL())
       
  1785 		{
       
  1786 		case EDHCPDiscover:
       
  1787 			ProcessDiscoverL();
       
  1788 	    	break;
       
  1789     	
       
  1790 		case EDHCPInform:
       
  1791 			if(iSvrState != ESvrWaitForAnyDHCPMsgs)
       
  1792 				{
       
  1793 				ProcessInformL();
       
  1794 				}
       
  1795   			break;
       
  1796   		
       
  1797 		case EDHCPRequest:
       
  1798 			ProcessRequestL();
       
  1799 			break;
       
  1800 
       
  1801 		case EDHCPReleaseMsg:
       
  1802 #ifdef SYMBIAN_DNS_PROXY
       
  1803 			ReadDhcpMsgParamsL();
       
  1804 #endif // SYMBIAN_DNS_PROXY
       
  1805 			iSvrSpecificState = ESvrReleaseInProgress;
       
  1806 			break;
       
  1807 
       
  1808     	case EDHCPDecline:
       
  1809 #ifdef SYMBIAN_DNS_PROXY
       
  1810 			ReadDhcpMsgParamsL();
       
  1811 #endif // SYMBIAN_DNS_PROXY
       
  1812     		iSvrSpecificState = ESvrDeclineInProgress;
       
  1813 			break;
       
  1814 		}
       
  1815 	}
       
  1816 	
       
  1817 #ifdef SYMBIAN_DNS_PROXY
       
  1818 void CDHCPIP4StateMachine::ReadDhcpMsgParamsL()
       
  1819 	{
       
  1820 	HBufC8*   hostName = HBufC8::NewLC(KMaxName);
       
  1821 	CDHCPMessageHeaderIP4* v4Msg = DhcpMessage();
       
  1822 	TUint32 staticAddr = v4Msg->GetCIAddr();
       
  1823 	iClientStaticAddr.SetAddress(staticAddr);
       
  1824 	v4Msg->iOptions.CopyHostNameL(hostName);
       
  1825 	iClientHostName.FillZ();
       
  1826 	iClientHostName.Copy(hostName->Des());
       
  1827 	CleanupStack::PopAndDestroy(hostName);
       
  1828 	}
       
  1829 #endif // SYMBIAN_DNS_PROXY
       
  1830 #ifdef SYMBIAN_NETWORKING_ADDRESS_PROVISION
       
  1831 TBool CDHCPIP4StateMachine::ClientHwAddrProvisioned()
       
  1832 	{
       
  1833 /** DHCP server server checks in which mode it has to offer the IP to clients.
       
  1834   * 1. If no HW address is provisioned, don't provide IP to any client.
       
  1835   * 2. Provide IP for any client if the DHCP server has already received the MAC as 0xFFFFFFFFFFFF through IOCTL call.
       
  1836   * 3. Provide IP for only clients whose MAC address is provisioned using the IOCTL call.
       
  1837   * 4. Reset the HW address list if DHCP server receives HW address as 0x000000000000
       
  1838   *  
       
  1839   * @internalTechnology
       
  1840   * @return - ETrue if the client is eligible to get the IP, otherwise EFalse.
       
  1841   */
       
  1842 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("CDHCPIP4StateMachine::ClientHwAddrProvisioned()")));
       
  1843 	if(iDhcpHwAddrManager->IsHwAddressProvisioned())
       
  1844 		{
       
  1845 		if(iDhcpHwAddrManager->IsAnyClientAllowed())
       
  1846 			{
       
  1847 			__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("DHCP server assigns IP without MAC provisioning")));
       
  1848 				return ETrue;
       
  1849 			}
       
  1850 		else
       
  1851 			{
       
  1852 			Uint64 clientHwAddress = 0;
       
  1853 			TSockAddr hwAddr;
       
  1854 			CDHCPMessageHeaderIP4* v4Msg = DhcpMessage();
       
  1855 			v4Msg->GetCHAddr(hwAddr);
       
  1856 			TPtrC8 hwAddrPtr(hwAddr.Mid(KHwAddrOffset, KHwAddrLength));
       
  1857 			TInt index = 0;
       
  1858 			TInt length = hwAddrPtr.Length();
       
  1859 			//Convert buffer data to Uint64
       
  1860 			for(; index < length; index++)
       
  1861 				{
       
  1862 				clientHwAddress <<= 8;
       
  1863 				clientHwAddress += hwAddrPtr[index];
       
  1864 				}
       
  1865 			//Check the received MAC address is provisioned. If true provide the DHCP OFFER.
       
  1866 			//Otherwise go back to wait for any DHCP client messages state
       
  1867 			if(iDhcpHwAddrManager->Provisioned(clientHwAddress))
       
  1868 				{
       
  1869 				__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("Client Harware address provisioned")));
       
  1870 				return ETrue;
       
  1871 				}
       
  1872 			}
       
  1873 		}
       
  1874 	__CFLOG_VAR((KLogSubSysDHCP, KLogCode, _L8("Client Harware address not provisioned")));
       
  1875 	return EFalse;
       
  1876 	}
       
  1877 #endif //SYMBIAN_NETWORKING_ADDRESS_PROVISION
       
  1878 #endif // SYMBIAN_NETWORKING_DHCPSERVER