tcpiputils/networkaddressandporttranslation/src/napt.cpp
changeset 0 af10295192d8
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 2008-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 // implementation of UDP and TCP tranlation
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20  @internalTechnology 
       
    21 */
       
    22 
       
    23 #include "hookdefs.h"
       
    24 #include <e32std.h>
       
    25 #include <in6_opt.h>
       
    26 #include <udp_hdr.h>
       
    27 #include <icmp6_hdr.h>
       
    28 #include <udp_hdr.h>
       
    29 #include <in_pkt.h>
       
    30 #include <ext_hdr.h>
       
    31 #include <in_chk.h>
       
    32 #include <tcp_hdr.h>
       
    33 #include <icmp6_hdr.h>
       
    34 #include "naptlog.h"
       
    35 #include "panic.h"
       
    36 #include "napt_ini.h"
       
    37 #include "naptconfigtable.h"
       
    38 #include <posthook.h>
       
    39 #ifdef SYMBIAN_NETWORKING_ADDRESS_PROVISION
       
    40 #include "naptutil.h"
       
    41 #endif //SYMBIAN_NETWORKING_ADDRESS_PROVISION
       
    42 #include <es_prot_internal.h>
       
    43 
       
    44 const TInt KIapUnDefined = 0;
       
    45 
       
    46 
       
    47 void Panic(TNAPTPanic aPanic)
       
    48 	{
       
    49 	User::Panic(_L("NAPTHook panic"), aPanic);
       
    50 	}
       
    51 
       
    52 _LIT(KProtocolNaptName, "napt");
       
    53 
       
    54 
       
    55 //Timer class  Functions..
       
    56 CNaptTimer* CNaptTimer::NewL(CProtocolNapt* aNaptProtocol)
       
    57 	/**
       
    58 	*
       
    59     * Create an instance of the timer
       
    60    	*
       
    61     */
       
    62      {
       
    63      CNaptTimer* timer = new(ELeave)CNaptTimer();
       
    64      CleanupStack::PushL(timer);
       
    65      timer->ConstructL();
       
    66      timer->iNaptProtocol = aNaptProtocol;
       
    67      timer->iMapMgrPtr = 	&(aNaptProtocol->iNaptMapMgr);
       
    68      CleanupStack::Pop(timer);
       
    69      return timer;
       
    70      }
       
    71 
       
    72 
       
    73 void CNaptTimer::StartTimer()
       
    74 	/**
       
    75 	*
       
    76     * Start Timer & Add it Active Scheduler
       
    77     *
       
    78     **/
       
    79 	{
       
    80 	ASSERT(!IsAdded());
       
    81 	CActiveScheduler::Add(this);
       
    82 	//it should be in Micro Seconds..
       
    83 	CTimer::After(iNaptTableScanInterval*1000000);
       
    84 	}
       
    85 
       
    86 
       
    87 void CNaptTimer::RunL()
       
    88 	/**
       
    89 	*	Timer is complete...
       
    90 	*	Delete the TimedOut Entries from the TranslationTable.
       
    91 	*	Check Any Packets are there in TranslationTable to be converted.
       
    92 	*	Restart Timer if they are present by taking iIndexedCount
       
    93 	*	Else Stop the timer
       
    94 	*
       
    95 	*	@internalTechnology
       
    96 	**/
       
    97 	{
       
    98 
       
    99 	//delete timeout transactions..
       
   100 	iMapMgrPtr->TimerComplete();
       
   101 
       
   102 	//reset timer
       
   103 	if (iNaptProtocol->iNaptMapMgr.GetIndexedPortCount())
       
   104 		{
       
   105 		CTimer::After(iNaptTableScanInterval*1000000);
       
   106 		}
       
   107 	else
       
   108 		{
       
   109 		Cancel();
       
   110 		}
       
   111 	}
       
   112 
       
   113 
       
   114 void CNaptTimer::Cancel()
       
   115 	/**
       
   116 	*
       
   117 	* Remove Timer from Active Scheduler
       
   118 	*
       
   119 	**/
       
   120 	{
       
   121 	CTimer::DoCancel();
       
   122 	if (IsAdded())
       
   123 		{
       
   124         Deque();
       
   125         }
       
   126 	}
       
   127 
       
   128 CNaptTimer::~CNaptTimer()
       
   129 	/**
       
   130     *
       
   131     * Timer destructor
       
   132     *
       
   133     */
       
   134      {
       
   135      Cancel();
       
   136      }
       
   137 
       
   138 
       
   139 /**
       
   140 ---------------------------------------------------------------------------------------
       
   141 								CSapNapt
       
   142 ---------------------------------------------------------------------------------------
       
   143  
       
   144 This class is derived from CServProviderBase.CSapNapt is the service class for sockets
       
   145 loading NAPT.But here only one socket will be able to load protocol.If protocol once
       
   146 loaded other socket cannot service protocol by opening socket.
       
   147  
       
   148  */
       
   149 
       
   150 CSapNapt::CSapNapt()
       
   151 	{
       
   152 	iConfigInfo = NULL;
       
   153 	}
       
   154 
       
   155 
       
   156 TNaptConfigInfo* CSapNapt::GetConfigInfo()
       
   157 /** 
       
   158  * This method is used to get the NAPT related configuration for this Service provider
       
   159  * access point.
       
   160  * @param None
       
   161  * return - TNaptConfigInfo*
       
   162 **/
       
   163 	{
       
   164 	return iConfigInfo;
       
   165 	}
       
   166 	
       
   167 void CSapNapt::SetConfigInfo(TNaptConfigInfo *aConfigInfo)	
       
   168 /** 
       
   169  * This method is used to set the NAPT related configuration for this Service provider
       
   170  * access point.
       
   171  * @param None
       
   172  * return - TNaptConfigInfo*
       
   173 **/
       
   174 	{
       
   175 	iConfigInfo = aConfigInfo;
       
   176 	}
       
   177 
       
   178 TInt CSapNapt::SetOption(TUint aLevel ,TUint aName ,const TDesC8& anOption)
       
   179 /** 
       
   180  * This class is used to set interface index information to be used by NAPT.
       
   181  * level will contain Downlink information and name will contain private interface
       
   182  * index. This method will also bind the protocol to the TCP/IP stack if it has not been
       
   183  * done yet.
       
   184  * @param aDownlink-- Downlink Interface Index.
       
   185  * @param aPrivateInterface - Private interface Index.
       
   186  * return - KErrNone if no value is assigned else KErrPermissionDenied
       
   187 **/
       
   188 
       
   189 	{
       
   190 	TInt err = KErrNone;
       
   191 #ifndef SYMBIAN_NETWORKING_ADDRESS_PROVISION
       
   192 
       
   193 	const TInterfaceLockInfo* info= reinterpret_cast<const TInterfaceLockInfo* >(anOption.Ptr());
       
   194 	if(aLevel==KSolNapt &&  aName == KSoNaptSetup)
       
   195 		{
       
   196 		if(anOption.Length()!=sizeof(TInterfaceLockInfo))
       
   197 			{
       
   198 			//this means that Block is not filled properly
       
   199 			return KErrArgument;
       
   200 			}
       
   201 		err = iConfigMgr->UpdateConfigL(info, this);
       
   202 		}//check if option and size
       
   203 	else
       
   204 		{
       
   205 		//options level or Name wrong
       
   206 		return KErrArgument; 
       
   207 		}
       
   208 		
       
   209 #else //SYMBIAN_NETWORKING_ADDRESS_PROVISION
       
   210 		if(aLevel==KSolNapt)
       
   211 		{
       
   212 		switch(aName)
       
   213 			{
       
   214 			case KSoNaptSetup:
       
   215 			case KSoNaptProvision:
       
   216 				{
       
   217 				LOG(Log::Printf(_L("CSapNapt::SetOption(): KSoNaptSetup ")));
       
   218 				const TInterfaceLockInfo* info = reinterpret_cast<const TInterfaceLockInfo* >(anOption.Ptr());
       
   219 				if(anOption.Length()!= sizeof(TInterfaceLockInfo))
       
   220 					{
       
   221 					//this means that Block is not filled properly
       
   222 					return KErrArgument;
       
   223 					}
       
   224 				err = iConfigMgr->UpdateConfigL(info, this) ;
       
   225 				}
       
   226 				break;
       
   227 
       
   228 			default:
       
   229 				{
       
   230 				LOG(Log::Printf(_L("//options level or Name wrong")));
       
   231 				//options level or Name wrong
       
   232 				return KErrArgument;
       
   233 				}
       
   234 			}//switch ends here
       
   235 		}
       
   236 	else
       
   237 		{
       
   238 		//options level or Name wrong
       
   239 		return KErrArgument; 
       
   240 		}
       
   241 #endif //SYMBIAN_NETWORKING_ADDRESS_PROVISION
       
   242     // Bind the protocol to TCP/IP stack and this will result in actually attach of the hook
       
   243     DoBindToL(err);
       
   244     
       
   245     return err;
       
   246 	}//end main function
       
   247 
       
   248 
       
   249 void CSapNapt::DoBindToL(TInt aStatus)
       
   250 /* This method is used to bind the protocol to TCP/IP stack once the client
       
   251  * configures NAPT hook. It checks if the protocol is not already bound in case it is
       
   252  * already bound the method does nothing and simply returns. Until and unless Napt is 
       
   253  * configured it's not actually bound to TCP/IP stack.
       
   254  * @param aStatus -- Status.
       
   255  * return - None
       
   256  *
       
   257  */
       
   258 	{
       
   259 	if ((aStatus == KErrNone) && (iProtocol->iBoundFlag == EFalse))
       
   260 		{
       
   261 		iProtocol->iBoundFlag = ETrue;
       
   262 		iProtocol->BindToL(iProtocol->iProtBase);
       
   263 		}
       
   264 	}
       
   265 
       
   266 TInt CSapNapt::SecurityCheck(MProvdSecurityChecker* aChecker)
       
   267 	/**
       
   268 	* Capability check for the NAPT sockets.
       
   269 	*
       
   270 	* NAPT sockets require the NetworkControl capability.
       
   271 	*
       
   272 	* @param aChecker The policy checker.
       
   273 	* @return The result of the policy check.
       
   274 	*/
       
   275 	{
       
   276 	//	This method is called when a SAP is created and when a socket is transferred between sessions.  The SAP is
       
   277 	//required to check whether the originating client process has enough privileges to request services from the SAP.
       
   278 	//The MProvdSecurityChecker class instance is used to perform security policy checks.  The SAP may choose
       
   279 	//to perform a security policy check in its SecurityCheck(...) method, or it may choose to store the
       
   280 	//MProvdSecurityChecker class instance argument and perform checking later (i.e. when subsequent
       
   281 	//SAP methods are called). 
       
   282 	_LIT_SECURITY_POLICY_C1(KPolicyNetworkControl, ECapabilityNetworkControl);
       
   283 	return aChecker->CheckPolicy(KPolicyNetworkControl, "NAPT policy failed.");
       
   284 	}
       
   285 
       
   286 
       
   287 
       
   288 
       
   289 /*
       
   290 -------------------------------------------------------------------------------------------------
       
   291 									CProtocolNapt
       
   292 
       
   293 -------------------------------------------------------------------------------------------------
       
   294 	
       
   295 	
       
   296 				Protocol loading
       
   297 				----------------
       
   298 					
       
   299 		ESOCK 			
       
   300  			\
       
   301  		      \ 	
       
   302  	       load \
       
   303                   \           load
       
   304  				CProtocolNapt-------->CProtocolNaptIn
       
   305  
       
   306    
       
   307 
       
   308 CProtocolNapt will load CProtocolNaptIn in its constructor. CProtocolNapt will bind itself as forward hook and
       
   309 will bind CProtocolNaptIn as an InboundHook using NetworkServices.
       
   310  
       
   311  
       
   312  */
       
   313 
       
   314 
       
   315 CProtocolNapt* CProtocolNapt::NewL()
       
   316 	{
       
   317 	CProtocolNapt* self = new(ELeave) CProtocolNapt();
       
   318 	CleanupStack::PushL(self);
       
   319 	self->CreateL();
       
   320 	CleanupStack::Pop();
       
   321 	return self;
       
   322 	}
       
   323 
       
   324 
       
   325 void CProtocolNapt::CreateL()
       
   326 /*
       
   327  *ConstructL part of two phase construction. Allocating memory to Inbound class aand passing 
       
   328  * reference to this.
       
   329 */
       
   330 	{
       
   331     iNaptMapMgr.iLastPort = KNaptPort_HIGH;
       
   332     
       
   333     
       
   334     iConfigMgr = CNaptClientConfigMgr::NewL(*this);
       
   335         
       
   336     //Allocating memory for Inbound Hook. No need for cleanup stack here its
       
   337     //a leaving function, so everything should be traped above.
       
   338     iProtInbound = new(ELeave) CProtocolNaptIn(this);
       
   339    
       
   340    	//Create Timer Instance
       
   341    	if (!iTimer) 
       
   342 		{
       
   343 		iTimer = CNaptTimer::NewL(this);
       
   344 		iNaptMapMgr.iTimerPtr = iTimer;
       
   345 		}
       
   346     iBoundFlag = EFalse;
       
   347     }
       
   348 
       
   349 CProtocolNapt::~CProtocolNapt()
       
   350 /** 
       
   351  * Destructor.This is called when NAPT is destroyed. Protocol should unbind it self
       
   352  * from the Network Layer.
       
   353 **/
       
   354 
       
   355 	{
       
   356 	CNaptIPPortMap *table=NULL;
       
   357 	if (iTimer )
       
   358 		{
       
   359 		//running timer will be stopped in destructor
       
   360 		delete iTimer;	
       
   361 		}
       
   362 	for (TInt index=0;index<KTranslationHashTableSize;index++)
       
   363 		{
       
   364 		TNaptTableIter naptTableIter(iNaptMapMgr.iIPPortMap[index]);
       
   365 		naptTableIter.SetToFirst();
       
   366 		while((table=naptTableIter++)!=NULL)
       
   367 			{
       
   368 			iNaptMapMgr.iIPPortMap[index].Remove(*table);
       
   369 			delete table;
       
   370 			}
       
   371 		}
       
   372 	// Protocol is being unloaded and hence clear all SAP references
       
   373 	// We are not really needed to delete the objects as esock will take care of
       
   374 	// deleting all the SAPs.	
       
   375     iSapList.Reset();		
       
   376     //Delete the client config manager.
       
   377     //This in turn destroys all the configurations stored in the list		
       
   378 	delete iConfigMgr;
       
   379 	
       
   380 	if(iBoundFlag != EFalse)
       
   381 		{
       
   382 		//Unbind Hooks.iProtInbound is the inbound hook which should be unbind from
       
   383 		//stack before unbinding main protocol.Should unbind using network service
       
   384 		//which quite important.If unable to unbind then check for network Services.
       
   385 		NetworkService()->Protocol()->Unbind((CProtocolBase*)iProtInbound,0);
       
   386 
       
   387 		NetworkService()->Protocol()->Unbind(this,0);
       
   388 
       
   389 		}
       
   390 	
       
   391 	if(iProtInbound!=NULL)
       
   392   		{
       
   393 		delete iProtInbound;
       
   394 		iProtInbound=NULL; //just safe step
       
   395 		}
       
   396 #ifdef __DEBUG
       
   397 //UnMarking heap which is marked when protocol is loaded in Family.cpp
       
   398 __UHEAP_MARKEND;
       
   399 #endif
       
   400 
       
   401 	}
       
   402 
       
   403 
       
   404 void CProtocolNapt::Identify(TServerProtocolDesc* aProtocolDesc)const 
       
   405 	{
       
   406 	Describe(*aProtocolDesc);
       
   407 	}
       
   408 
       
   409 
       
   410 
       
   411 void CProtocolNapt::BindL(CProtocolBase* /*protocol*/, TUint /*id*/)
       
   412 	{
       
   413 	// We should not overwrite the existing esk files
       
   414 
       
   415 	}
       
   416 
       
   417 
       
   418 
       
   419 void CProtocolNapt::BindToL(CProtocolBase* aProtocol)
       
   420 	/**
       
   421 	* The protocol binds itself to TCP/IP stack. The bind has been delibrately deferred
       
   422 	* here to facilitate opening of multiple sockets without actually loading the hook.
       
   423 	* The hook will be actually loaded when someone configured the setup information in NAPT
       
   424 	* 
       
   425 	**/
       
   426 	{
       
   427 	if(iBoundFlag != EFalse)
       
   428 	{
       
   429 		const TUint id = (TUint)DoBindToL(aProtocol);
       
   430 	}
       
   431 	else
       
   432 		iProtBase = aProtocol;
       
   433 	}
       
   434 
       
   435 
       
   436 void CProtocolNapt::NetworkAttachedL()
       
   437 	/**
       
   438 	* The TCP/IP stack has been attached to this plugin.
       
   439 	*
       
   440 	* The CProtocolPosthook impelements the basic BindL/BindToL and Unbind
       
   441 	* processing. The NetworkAttached is called when the TCP/IP
       
   442 	* is connected with this protocol module.
       
   443 	*
       
   444 	* This function installs a hook for forwarded packets. The function
       
   445 	* ApplyL will be called for each received packet that enters the
       
   446 	* forward path (before actual forwarding decision).
       
   447 	*
       
   448 	* Could also install any other hooks to pull packets.
       
   449 	*/
       
   450 	{
       
   451 	//Read Timer Configuration Parameters
       
   452 	ReadConfigurationFile();
       
   453 			
       
   454 	NetworkService()->BindL(this, BindForwardHook());
       
   455 	
       
   456 	//Binding Inbound hook as hook all. This will take packets from all the interfaces
       
   457 	//and translate only thise which are required.This seperate class optimise RAM usage. 
       
   458 	//and implemented to avoid usage of heavy calls like IsForMeAddress.
       
   459 	NetworkService()->BindL((CProtocolBase*)iProtInbound, BindHookAll());
       
   460 
       
   461 	iManager = NetworkService()->Interfacer();
       
   462 
       
   463 	}
       
   464 
       
   465 
       
   466 void CProtocolNapt::ReadConfigurationFile()
       
   467 	/*
       
   468 	* Timer values are stored in Timer Class.	
       
   469 	* iNaptTableScanInterval value should be less than 2147 seconds, as it is an argument
       
   470 	* to CTimer::After(TTimeIntervalMicroSeconds32).	
       
   471 	*/
       
   472 	{
       
   473 	iTimer->iNaptTableScanInterval	= GetIniValue(NAPT_INI_TIMER,NAPT_INI_TABLESCANINTERVAL,KTableScanIntervalDefault,1,KTimerMaxSeconds);
       
   474 	iTimer->iNaptTcpIdleTimeout		= GetIniValue(NAPT_INI_TIMER,NAPT_INI_TCPIDLETIMEOUT,KTcpIdleTimeOutDefault,1,KMaxTInt);
       
   475 	iTimer->iNaptUdpIdleTimeout		= GetIniValue(NAPT_INI_TIMER,NAPT_INI_UDPIDLETIMEOUT,KUdpIdleTimeoutDefault,1,KMaxTInt);
       
   476 	iTimer->iNaptIcmpIdleTimeout	= GetIniValue(NAPT_INI_TIMER,NAPT_INI_ICMPIDLETIMEOUT,KIcmpIdleTimeoutDefault,1,KMaxTInt);
       
   477 	iTimer->iNaptTcpCloseTimeout	= GetIniValue(NAPT_INI_TIMER,NAPT_INI_TCPCLOSETIMEOUT,KTcpCloseTimeoutDefault,1,KMaxTInt);
       
   478 	iTimer->iNaptTcpOpenTimeout		= GetIniValue(NAPT_INI_TIMER,NAPT_INI_TCPOPENTIMEOUT,KTcpOpenTimeoutDefault,1,KMaxTInt);
       
   479 	}
       
   480 	
       
   481 
       
   482 TInt CProtocolNapt::GetIniValue(const TDesC& aSection, const TDesC& aName, TInt aDefault, TInt aMin, TInt aMax)
       
   483 	/*
       
   484 	* Timer values are read from the configuration file-napt.ini
       
   485 	* If the configuration values are not present default values are stored
       
   486 	*/
       
   487 	{
       
   488 	TInt value;
       
   489 	CESockIniData* config = NULL;
       
   490 	
       
   491 	TRAP_IGNORE(config = CESockIniData::NewL(NAPT_INI_DATA));
       
   492     if (config==NULL || !config->FindVar(aSection, aName, value))
       
   493     	{
       
   494         value = aDefault;
       
   495     	}
       
   496      else if (value < aMin || value > aMax)
       
   497          {
       
   498          value = aDefault;
       
   499          }
       
   500     delete config;
       
   501     return value;	
       
   502 	}
       
   503 	
       
   504 
       
   505 TInt CProtocolNapt::ApplyL(RMBufHookPacket& aPacket, RMBufRecvInfo& aInfo)
       
   506 /*
       
   507  * This function is called for all the packets coming from interfce. This instance of 
       
   508  * ApplyL will be called for forwarding hook as well as inbound hook. Packets are 
       
   509  * translated for both inbound and forwarding packets. Scope is being set for packet 
       
   510  * destined to private interface.
       
   511  * @param aPacket
       
   512  * @param aInfo
       
   513 */
       
   514 	{
       
   515 	const TInetAddr& dest = aInfo.iDstAddr;
       
   516 	const TInetAddr& src= aInfo.iSrcAddr;
       
   517 	const TUint32 ifindex = aInfo.iInterfaceIndex;
       
   518 	TInetAddr addr(aInfo.iSrcAddr);
       
   519 	LOG(Log::Printf(_L("packet received from interface index=[%d] and source ip address is:%x"),ifindex,addr.Address()));
       
   520 	
       
   521 	iCurConfigInfo = iConfigMgr->FindConfig(ifindex);
       
   522 	if(!iCurConfigInfo)
       
   523 		{
       
   524 		
       
   525 		LOG(Log::Printf(_L("No configuration information for interface index=[%d]"),ifindex));
       
   526 		return KIp6Hook_PASS;
       
   527 		}
       
   528 		
       
   529 	//This Flag will make code to traverse extra check.If this is true then code 
       
   530 	//will see if scope of packet and private interface match or not.
       
   531 	TBool checkScopeFlag= EFalse;
       
   532 
       
   533 	//This bit will be used in checking the scope of packet
       
   534 	const TIp6Addr& packetScopeIp = dest.Ip6Address();
       
   535 	TUint packetScope=KIapUnDefined;
       
   536 	
       
   537 	
       
   538 	LOG(Log::Printf(_L("I belong to protocol family--version=[%d]"),aInfo.iVersion));
       
   539 
       
   540 	//check for IP version.
       
   541 	if(aInfo.iVersion==4)
       
   542 		{
       
   543 		LOG(Log::Printf(_L("\tInterface Index --Private IAP=[%d],Public IAP=[%d]"), iCurConfigInfo->iPrivateIap ,iCurConfigInfo->iPublicIap));
       
   544 	
       
   545 		const TIp6Addr& source = iCurConfigInfo->iPrivateIp.Ip6Address();
       
   546 
       
   547 		//Find NET ID i.e. scope for Private Interface. explanation given below.
       
   548 		iCurConfigInfo->iScopeSrc = iManager->RemoteScope(source ,iCurConfigInfo->iPrivateIap ,EScopeType_IAP);
       
   549 		
       
   550 
       
   551 	
       
   552 		//giving iPublicGatewayIP information to tranlsation table manager
       
   553 		iNaptMapMgr.iPublicGatewayIP=iCurConfigInfo->iPublicGatewayIP.Address();
       
   554 
       
   555 		const TIp6Addr& downlink = iCurConfigInfo->iPublicGatewayIP.Ip6Address();
       
   556 			
       
   557 		//Take public interface scope.This will be use in Routing.IAP and Interface IP will 
       
   558 		//select scope i.e. NET ID.
       
   559 		/*
       
   560 		Each interface is assigned 16 scope identifiers, one for each scope level (1..16). 
       
   561 		The set of scope identifiers in each of the interfaces defines a virtual forest of trees (of depth 16),
       
   562 		where the actual interfaces are the leaf nodes. 
       
   563 		Each scope id at net level (16) defines it's own tree.
       
   564 			
       
   565 		scope=16	net=1                                 		net=1                
       
   566 						  |                                           |
       
   567 		scope=14	Global=1                                    Global=1
       
   568 			|		  |                                          / \
       
   569 			|		  |                                         |   |
       
   570 			|		  |	                                        |   |
       
   571 		scope=2		IAP = 1                                   IAP=2 IAP=3
       
   572 				    /  \                                      	|     |                                      
       
   573 		scope=1	 if=1   if=2                                   if=3  if=4  
       
   574 		      		                                              
       
   575 		  
       
   576 		 */
       
   577 		iCurConfigInfo->iScopedest = iManager->RemoteScope(downlink ,iCurConfigInfo->iPublicIap ,EScopeType_IAP);
       
   578 
       
   579 
       
   580 
       
   581 		//Check if source IP of packet and destination IP is same. If yes then extra check
       
   582 		//to find if scope of packet and private Interface match or not
       
   583 		if((iCurConfigInfo->iPublicGatewayIP.Address())==(src.Address()))
       
   584 			{
       
   585 			checkScopeFlag=ETrue;
       
   586 			}
       
   587 		if(checkScopeFlag)
       
   588 			{
       
   589 			//Extract scope of the packet.This will help in deciding what type of packet neet translation
       
   590 			//This fundamental will be quite helpful when subnet for private and public IP will be same
       
   591 			packetScope =iManager->RemoteScope(packetScopeIp , aInfo.iInterfaceIndex ,EScopeType_IF);
       
   592 			}
       
   593 		
       
   594 		//translate accoring to the private range and netmask specified.Extra check is added for the packets coming from 
       
   595 		//private interface to be translated.This check is that packet coming from private scope with relevant
       
   596 		//subnet should be translated.the check is if(packetScope!=iSrcScope) then dont translate.This will resolve issue
       
   597 		//of private and public IP being same
       
   598 		if(iCurConfigInfo->iPrivateIp.Match(aInfo.iSrcAddr,iCurConfigInfo->iNetMaskLength)&& !(dest.Match(iCurConfigInfo->iPrivateIp,iCurConfigInfo->iNetMaskLength)))
       
   599 			{
       
   600 #ifdef SYMBIAN_NETWORKING_ADDRESS_PROVISION
       
   601 			if((src.Address() != iCurConfigInfo->iProvisionedIp) || ! iCurConfigInfo->iUplinkAccess)
       
   602 				{
       
   603 				LOG(Log::Printf(_L("No forward translation %d:"), KIp6Hook_PASS));
       
   604 				return KIp6Hook_PASS;
       
   605 				}
       
   606 #endif //SYMBIAN_NETWORKING_ADDRESS_PROVISION
       
   607 			LOG(
       
   608 			TBuf<70> tmpSrc;
       
   609 			TBuf<70> tmpDst;
       
   610 			TInetAddr::Cast(aInfo.iSrcAddr).OutputWithScope(tmpSrc);
       
   611 			TInetAddr::Cast(aInfo.iDstAddr).OutputWithScope(tmpDst);
       
   612 			LOG(Log::Printf(_L("\t Hi I am packet coming from private interface and need translation\n src=[%S] dst=[%S] proto=%d"), &tmpSrc, &tmpDst, aInfo.iProtocol));
       
   613 			LOG(Log::Printf(_L("I am in Forwarding hook of NAPT")));	
       
   614 			);
       
   615 
       
   616 			//Intelligence maintained if public and private ip are same
       
   617 		
       
   618 			if(aInfo.iProtocol==KProtocolInetUdp ||aInfo.iProtocol== KProtocolInetTcp)
       
   619 				{
       
   620 				if(checkScopeFlag)
       
   621 					{
       
   622 					//No translatation will happen if Pubilc and private IP are same. Stack panics if
       
   623 					//this happens. No need for translation just pass it.
       
   624 					LOG(Log::Printf(_L("public IP is same as  client IP. Sorry no translation")));	
       
   625 
       
   626 					//check if scope for packet matches scope of private interface ot not. If not then dont
       
   627 					//manipulate
       
   628 					if(packetScope!=iCurConfigInfo->iScopeSrc)
       
   629 						{
       
   630 						return KIp6Hook_PASS; 
       
   631 						}
       
   632 					}
       
   633 				//Packet manipulation TCP/UDP
       
   634 				ForwardManipulation(aPacket,aInfo);
       
   635 				}//udp and tcp
       
   636 		
       
   637 			else if(aInfo.iProtocol == KProtocolInetIcmp)
       
   638 				{
       
   639 				if(checkScopeFlag)
       
   640 					{
       
   641 					//No translatation will happen if Pubilc and private IP are same. Stack panics if
       
   642 					//this happens. No need for translation just pass it.
       
   643 					LOG(Log::Printf(_L("public IP is same as  client IP. Sorry no translation")));	
       
   644 
       
   645 					//check if scope for packet matches scope of private interface ot not. If not then dont
       
   646 					//manipulate
       
   647 					if(packetScope!=iCurConfigInfo->iScopeSrc)
       
   648 						{
       
   649 						return KIp6Hook_PASS; 
       
   650 						}
       
   651 					}
       
   652 				else if(dest.Address()== iCurConfigInfo->iPublicGatewayIP.Address())
       
   653 					{
       
   654 					//This is quite special case PINGING Public Gateway wont require NAPT
       
   655 					return KIp6Hook_PASS;
       
   656 					}
       
   657 					
       
   658 				//Packet manipulation ICMP
       
   659 				IcmpHandlerForward(aPacket,aInfo);
       
   660 				} //ICMP
       
   661 			} //end check for packets coming from private interface.
       
   662 		else if(iCurConfigInfo->iPrivateIp.Match(aInfo.iDstAddr,iCurConfigInfo->iNetMaskLength)&& !(iCurConfigInfo->iPrivateIp.Match(aInfo.iSrcAddr,iCurConfigInfo->iNetMaskLength)))
       
   663 			{
       
   664 	 	   // Setting the scope to 0 will cause the stack to automatically fill in the correct scope itself
       
   665 			TInetAddr::Cast(aInfo.iSrcAddr).SetScope(0);
       
   666 
       
   667 			//Setting Network ID of private Interfae as a scope. Route will be searched according 
       
   668 			//to the Destination Id which is set as the scope of private interface.
       
   669 			TInetAddr::Cast(aInfo.iDstAddr).SetScope(iCurConfigInfo->iScopeSrc);
       
   670 			}
       
   671 		//Pass all packets which dont need translation
       
   672 		else
       
   673 			{
       
   674 			return KIp6Hook_PASS;
       
   675 			}
       
   676 			
       
   677 		} // Closing If of Version Check
       
   678 
       
   679 	return KIp6Hook_PASS;
       
   680 	} //Function close
       
   681 
       
   682 
       
   683 
       
   684 
       
   685 
       
   686 void CProtocolNapt::ForwardManipulation(RMBufHookPacket& aPacket, RMBufRecvInfo& aInfo)
       
   687 	{
       
   688 		
       
   689 	 LOG(Log::Printf(_L("CProtocolNapt::ForwardManipulation called for outgoing packets to global interface")));
       
   690 	//retrieve information from aInfo. This information will be maintained in the transation 
       
   691 	//table.
       
   692 	TUint lSrcPort;
       
   693 	TUint lDstPort;
       
   694   
       
   695   	//Declarations of IP to be stored in table.
       
   696  	const TUint32 sourceIP =(TInetAddr::Cast(aInfo.iSrcAddr)).Address();
       
   697     const TUint32 destinationIP=(TInetAddr::Cast(aInfo.iDstAddr)).Address();
       
   698    	const TUint32 targetIP= iCurConfigInfo->iPublicGatewayIP.Address();
       
   699 	TUint translatedPort;
       
   700 	
       
   701 	TInet6Checksum<TInet6HeaderIP4> lIp(aPacket);
       
   702 
       
   703 	//IP header Length ....used to access UDP header
       
   704 	TInt lengthIP	= lIp.iHdr->HeaderLength();
       
   705    	
       
   706    	CNaptIPPortMap* table=NULL;
       
   707 
       
   708 	if(aInfo.iProtocol==KProtocolInetUdp)
       
   709 		{
       
   710 		//UDP header 
       
   711 		TInet6Packet<TInet6HeaderUDP> lUdp(aPacket,lengthIP);
       
   712 		lSrcPort=lUdp.iHdr->SrcPort();
       
   713 		lDstPort =lUdp.iHdr->DstPort();
       
   714 	
       
   715 
       
   716 		//Check if entry is needed or not.If result is KErrNone then record exsists in the table.
       
   717 		TRAPD(ret,table=iNaptMapMgr.FindOrCreateNaptEntryL(KProtocolInetUdp ,sourceIP, destinationIP,lSrcPort ,lDstPort, iCurConfigInfo));
       
   718 		
       
   719 		if(table==NULL || (ret == KErrNoMemory))
       
   720 			{
       
   721 			LOG(Log::Printf(_L("I am UDP packet from private Interface and I need translation")));
       
   722 			return;
       
   723 			} 
       
   724 	
       
   725 		//Get translated port from the table.	
       
   726 		TUint translatedPort = table->iTrPort;
       
   727 		
       
   728 		//Set translated port in the UDP header
       
   729 		lUdp.iHdr->SetSrcPort(translatedPort);
       
   730 		aInfo.iSrcAddr.SetPort(translatedPort);
       
   731 		
       
   732 
       
   733 		//Set source IP of packet as public IP (public refer to Gateway)
       
   734 		lIp.iHdr->SetSrcAddr(targetIP);
       
   735 		TInetAddr::Cast(aInfo.iSrcAddr).SetV4MappedAddress(targetIP);
       
   736 		
       
   737 		//Setting source scope i,e networkID as zero this will allow stack to to set source scope 
       
   738 		//for packet.
       
   739 		TInetAddr::Cast(aInfo.iSrcAddr).SetScope(0);
       
   740 
       
   741 		
       
   742 		//Setting Network ID of desired interface as a scope. Route will be searched according 
       
   743 		//to the Destination Id which is set as the scope of desired interface.
       
   744 
       
   745 		TInetAddr::Cast(aInfo.iDstAddr).SetScope(iCurConfigInfo->iScopedest);
       
   746                
       
   747 		//Compute checksum zero for UDP
       
   748 		lUdp.iHdr->SetChecksum(0);
       
   749 
       
   750 		//Compute IP checksum
       
   751 		lIp.ComputeChecksum();
       
   752 		aInfo.iFlags &= ~KIpAddressVerified;
       
   753 	
       
   754 		}//Protocol Check UDP
       
   755 
       
   756 	// Section for manipulating TCP packets.
       
   757 	else if(aInfo.iProtocol==KProtocolInetTcp)
       
   758 		{
       
   759 		TInet6Checksum<TInet6HeaderTCP> lTcp(aPacket,lengthIP);
       
   760 		lSrcPort = lTcp.iHdr->SrcPort();
       
   761 		lDstPort = lTcp.iHdr->DstPort();
       
   762 
       
   763 		//Finds  Translation Node,if already existing or creates  a new node filled with unique translated port number for 
       
   764 		//translated IP for TCP/UDP/ICMP connections.  
       
   765 		TRAPD(ret,table=iNaptMapMgr.FindOrCreateNaptEntryL(KProtocolInetTcp ,sourceIP, destinationIP,lSrcPort ,lDstPort, iCurConfigInfo));
       
   766 
       
   767 		if(table==NULL || (ret==KErrNoMemory))
       
   768 			{
       
   769 			LOG(Log::Printf(_L("I am TCP packet from private Interface and I need translation")));
       
   770 			return ;
       
   771 			}
       
   772 	
       
   773 
       
   774 		//Get last translated port
       
   775 		translatedPort = table->iTrPort;
       
   776         
       
   777 		lTcp.iHdr->SetSrcPort(translatedPort);
       
   778 		aInfo.iSrcAddr.SetPort(translatedPort);
       
   779 		
       
   780 		lIp.iHdr->SetSrcAddr(targetIP);
       
   781 		TInetAddr::Cast(aInfo.iSrcAddr).SetV4MappedAddress(targetIP);
       
   782 
       
   783  	  // Setting the scope to 0 will cause the stack to automatically fill in the correct scope itself
       
   784 		TInetAddr::Cast(aInfo.iSrcAddr).SetScope(0);
       
   785 		
       
   786 		//Setting Network ID of desired interface as a scope. Route will be searched according 
       
   787 		//to the Destination Id which is set as the scope of desired interface.
       
   788 		TInetAddr::Cast(aInfo.iDstAddr).SetScope(iCurConfigInfo->iScopedest);
       
   789 		
       
   790 		//this one is to avoid armv5 errors and calculate checksum right
       
   791 		RMBufChain& payload = static_cast<RMBufChain&>(aPacket);
       
   792 		
       
   793 		//checksum calculations
       
   794    		lTcp.ComputeChecksum(payload,&aInfo,lengthIP);
       
   795 		lIp.ComputeChecksum();
       
   796 		
       
   797 		aInfo.iFlags &= ~KIpAddressVerified;
       
   798 		
       
   799 	   		
       
   800 	   	iNaptMapMgr.HandleTcpConnectionPhases(lTcp,table,KTcpClosePacketOUT);
       
   801 		}//Protocol Check TCP
       
   802 
       
   803 	}
       
   804 
       
   805 
       
   806 	
       
   807 void CProtocolNapt::Describe(TServerProtocolDesc& anEntry)
       
   808 /* Protocol Description
       
   809  * @param anEntry
       
   810 */
       
   811 	{
       
   812 	anEntry.iName=KProtocolNaptName;
       
   813 	anEntry.iAddrFamily=KAfInet;
       
   814 	anEntry.iSockType=KSockDatagram;
       
   815 	anEntry.iProtocol=KProtocolNAPT;
       
   816 	anEntry.iVersion=TVersion(1, 0, 0);
       
   817 	anEntry.iByteOrder=EBigEndian;
       
   818 	anEntry.iServiceInfo=KSIDatagram | KSIConnectionLess;
       
   819 	anEntry.iNamingServices=0;
       
   820 	anEntry.iSecurity=KSocketNoSecurity;
       
   821 	anEntry.iMessageSize=0xffff;
       
   822 	anEntry.iServiceTypeInfo=0;
       
   823 	anEntry.iNumSockets=KUnlimitedSockets;
       
   824 	anEntry.iServiceTypeInfo=ESocketSupport | EInterface;
       
   825 
       
   826 	}
       
   827 
       
   828 
       
   829 
       
   830 
       
   831 /* 
       
   832 ----------------------------------------------------------------------------------------------------
       
   833 							CProtocolNaptIn code
       
   834 ----------------------------------------------------------------------------------------------------
       
   835 The following code is for inbound Hook.This hook will be bind for all the packets coming from the 
       
   836 all the interfaces.But it will trigger for only packets whose entry is there in translation table.
       
   837 */
       
   838 
       
   839 
       
   840 
       
   841 CProtocolNaptIn::CProtocolNaptIn(CProtocolNapt* aNapt)
       
   842 /*
       
   843  * Consturctor
       
   844 */	
       
   845 	
       
   846 	{
       
   847 	//giving pointer to CProtocolNapt for table manipulation. Now Pointer check 
       
   848 	//is quite important here
       
   849 	if(aNapt!=NULL)
       
   850 		{
       
   851 		iNapt=aNapt;
       
   852 		iConfigMgr = iNapt->iConfigMgr;
       
   853 		}
       
   854 	else
       
   855 		{
       
   856 		Panic(ENAPTPanic_BadCall);
       
   857 
       
   858 		}		
       
   859 	}// end constructor
       
   860 	
       
   861 
       
   862 CProtocolNaptIn::~CProtocolNaptIn()
       
   863 /*
       
   864  * Destructor
       
   865  */
       
   866 	{
       
   867 	}
       
   868 
       
   869 
       
   870 
       
   871 TInt CProtocolNaptIn::ApplyL(RMBufHookPacket& aPacket, RMBufRecvInfo& aInfo)
       
   872 /**
       
   873 * Function for incoming packets coming from all the interface.
       
   874 * Only translate packets whos entry is there in Tanslation table.The query is made to translation table
       
   875 * for entry if not found then PASS packets else Tanslate packets and then pass.
       
   876 * @param aPacket
       
   877 * @param aInfo
       
   878 **/
       
   879 	{
       
   880 	TInt ret=KIp6Hook_PASS;
       
   881 
       
   882 	//only manipulate packets with IPv4 header other should not be tempered.
       
   883 	if(aInfo.iVersion==4)
       
   884 		{
       
   885 		LOG(Log::Printf(_L("Hi I am packet .I am in Inbound hook of NAPT")));
       
   886 		if(aInfo.iProtocol==KProtocolInetUdp || aInfo.iProtocol== KProtocolInetTcp)
       
   887 			{
       
   888 			//udp and tcp packets coming from all interfaces 
       
   889 			ret=IncomingPacketManipulation(aPacket,aInfo);
       
   890 			}
       
   891 		else if(aInfo.iProtocol == KProtocolInetIcmp)
       
   892 			{
       
   893 			//ICMP packets.
       
   894 			ret=IcmpHandler(aPacket , aInfo);
       
   895 			}
       
   896 		}
       
   897 	return ret;
       
   898 	}
       
   899 
       
   900 TInt CProtocolNaptIn::IncomingPacketManipulation(RMBufHookPacket& aPacket, RMBufRecvInfo& aInfo)
       
   901 /**
       
   902 * Function for incoming packets coming from all the interface.
       
   903 * Only translate packets whos entry is there in Tanslation table.The query is made to translation table
       
   904 * for entry if not found then PASS packets else Tanslate packets and then pass.
       
   905 * @param aPacket
       
   906 * @param aInfo
       
   907 **/
       
   908 	{
       
   909 
       
   910 	TUint lDstPort;
       
   911     const TUint32 srcIp = (TInetAddr::Cast(aInfo.iSrcAddr)).Address();
       
   912  
       
   913     // This flag states that packets have been translated and that KIp6Hook_DONE should be used as return value
       
   914 	TBool translatedFlag = EFalse;
       
   915 	
       
   916 	CNaptIPPortMap* table= NULL;
       
   917 	TNaptConfigInfo* info = NULL;
       
   918 
       
   919     TInet6Checksum<TInet6HeaderIP4> lIp(aPacket);
       
   920     TInt lengthIP = lIp.iHdr->HeaderLength();
       
   921 
       
   922 	//if node exist and if destination IP is same as targetIp ( this is just to cross check)
       
   923 	if(aInfo.iProtocol==KProtocolInetUdp)
       
   924 		{
       
   925 	 
       
   926 	 	//UDP packet. Took port information in second line.
       
   927 	  	TInet6Packet<TInet6HeaderUDP> lUdp(aPacket,lengthIP);
       
   928 	    lDstPort= lUdp.iHdr->DstPort();
       
   929 		
       
   930 	   	//get translated table node
       
   931 	   	table = iNapt->iNaptMapMgr.GetIPTranslationNode(lDstPort);
       
   932 	   
       
   933 	   	if (table)
       
   934 	   		{
       
   935 	   		//Take original IP and Port number from the table.
       
   936 	  		TUint32 originalIP;
       
   937 
       
   938 	  		originalIP=table->iSrcIpAddr;
       
   939 			TUint orgPort = table->iSrcPort;
       
   940 			info = table->iConfigInfo;
       
   941 			
       
   942 			if (iNapt->iNaptMapMgr.VerifySender(table,srcIp,lUdp.iHdr->SrcPort()))
       
   943 				{
       
   944 				LOG(Log::Printf(_L("Udp packet translated...see IP's below")));	
       
   945 
       
   946 				lUdp.iHdr->SetDstPort(orgPort);
       
   947 				aInfo.iDstAddr.SetPort(orgPort);
       
   948 
       
   949 				lIp.iHdr->SetDstAddr(originalIP);
       
   950 				TInetAddr::Cast(aInfo.iDstAddr).SetV4MappedAddress(originalIP);
       
   951 			
       
   952 				//Compute checksum zero for UDP
       
   953 				lUdp.iHdr->SetChecksum(0);
       
   954 
       
   955 				//Compute IP checksum
       
   956 				lIp.ComputeChecksum();
       
   957 
       
   958 				//This flag states that packets are translated and should be Done
       
   959 				translatedFlag = ETrue;
       
   960 				}//verify sender
       
   961 	   		}//table
       
   962 		}//udp
       
   963 		
       
   964 	   else	if(aInfo.iProtocol==KProtocolInetTcp)
       
   965    		{
       
   966  		//TCP packet.Took Port information in second line.
       
   967    		TInet6Checksum<TInet6HeaderTCP> lTcp(aPacket,lengthIP);
       
   968    		lDstPort =lTcp.iHdr->DstPort();
       
   969    	
       
   970    		//get translated table node
       
   971 	   	table = iNapt->iNaptMapMgr.GetIPTranslationNode(lDstPort);
       
   972 	   	if (table)
       
   973 	   		{
       
   974 	   		TUint32 originalIP;
       
   975 	  		originalIP=table->iSrcIpAddr;
       
   976 			TUint orgPort = table->iSrcPort;
       
   977 			info = table->iConfigInfo;
       
   978 
       
   979 			//check for match
       
   980 			if (iNapt->iNaptMapMgr.VerifySender(table,srcIp,lTcp.iHdr->SrcPort()))
       
   981 				{
       
   982 				LOG(Log::Printf(_L("Tcp packet translated...see IP's below")));	
       
   983 
       
   984 				//Change port information. Replace translated port by original port.
       
   985 	   			lTcp.iHdr->SetDstPort(orgPort);
       
   986 	   			aInfo.iDstAddr.SetPort(orgPort);
       
   987 	   		
       
   988 				//Change IP address.Replace translate IP by original IP.	   	 
       
   989 	   			lIp.iHdr->SetDstAddr(originalIP);
       
   990 	   			TInetAddr::Cast(aInfo.iDstAddr).SetV4MappedAddress(originalIP);
       
   991 	   		
       
   992 				//this one is to avoid armv5 errors and calculate checksum right
       
   993 				RMBufChain& payload = static_cast<RMBufChain&>(aPacket);	   		
       
   994 	   			
       
   995 	   			//Compute checksum	
       
   996 	   			lTcp.ComputeChecksum(payload,&aInfo,aInfo.iOffset);
       
   997 	   			lIp.ComputeChecksum();
       
   998 		   
       
   999 				//This flag states that packets are translated and should be Done
       
  1000 				translatedFlag = ETrue;	 
       
  1001 				
       
  1002 				iNapt->iNaptMapMgr.HandleTcpConnectionPhases(lTcp,table,KTcpClosePacketIN);
       
  1003 	
       
  1004 	   				
       
  1005 	   			}//verify sender
       
  1006 	   		}//table
       
  1007    		}//tcp
       
  1008  	
       
  1009 	if(	translatedFlag)
       
  1010 		{
       
  1011 		aInfo.iFlags &= ~KIpAddressVerified;
       
  1012 
       
  1013 		LOG(
       
  1014 			TBuf<70> tmpSrc;
       
  1015 			TBuf<70> tmpDst;
       
  1016 			TInetAddr::Cast(aInfo.iSrcAddr).OutputWithScope(tmpSrc);
       
  1017 			TInetAddr::Cast(aInfo.iDstAddr).OutputWithScope(tmpDst);
       
  1018 			LOG(Log::Printf(_L("\t I am translated packet values are after translation \n src=[%S] dst=[%S] proto=%d"), &tmpSrc, &tmpDst, aInfo.iProtocol));
       
  1019 			LOG(Log::Printf(_L("I am in Inbound hook of NAPT")));	
       
  1020 			);
       
  1021 	   // Setting the scope to 0 will cause the stack to automatically fill in the correct scope itself
       
  1022 		TInetAddr::Cast(aInfo.iSrcAddr).SetScope(0);
       
  1023 
       
  1024 		//Setting Network ID of private Interfae as a scope. Route will be searched according 
       
  1025 		//to the Destination Id which is set as the scope of private interface.
       
  1026 		if(!iNapt->iCurConfigInfo)
       
  1027 			LOG(Log::Printf(_L("I am in Inbound hook of NAPT, but no Current Configuration for incoming packet")));	
       
  1028 		TInetAddr::Cast(aInfo.iDstAddr).SetScope(info->iScopeSrc);
       
  1029 
       
  1030 		return KIp6Hook_DONE;
       
  1031 		}
       
  1032 	return KIp6Hook_PASS;
       
  1033 	}
       
  1034 
       
  1035 
       
  1036 
       
  1037 CServProviderBase* CProtocolNapt::NewSAPL(TUint aProtocol)
       
  1038 /** 
       
  1039  * Service Access point for the Protocol. Service Access Point supports sockets and allow them 
       
  1040  * to manipulate protocol. aProtocol is the instance of protocol for which SAP is required.
       
  1041 **/
       
  1042 
       
  1043 	{
       
  1044     //avoid warning.
       
  1045     (void)aProtocol;
       
  1046     
       
  1047     CSapNapt *nsap = NULL;
       
  1048 
       
  1049     nsap = new(ELeave) CSapNapt;
       
  1050 	nsap->iProtocol=this;
       
  1051 	nsap->iConfigMgr = this->iConfigMgr;
       
  1052 	iSapList.AppendL(nsap);		
       
  1053 	return nsap;
       
  1054 	}
       
  1055 
       
  1056 
       
  1057 void CProtocolNapt::CancelSap(CSapNapt *aSap)
       
  1058 /** 
       
  1059  * This method clears the instance of SAP contained in the SAP table of the protocol.
       
  1060  * @param aSap - intance to be set to NULL
       
  1061  * @return None
       
  1062  * 
       
  1063 **/
       
  1064 
       
  1065 	{
       
  1066 	LOG(Log::Printf(_L("CProtocolNapt::CancelSap...Deleting SAP:%d"), aSap));
       
  1067 	TInt index = iSapList.Find(aSap);
       
  1068 	
       
  1069 	//Delete the config and set the reference of the SAP being deleted to NULL
       
  1070 	if(index != KErrNotFound)
       
  1071 		{
       
  1072 	    iSapList[index]->iConfigMgr->DeleteConfig(aSap->iConfigInfo);
       
  1073 		iSapList[index] = NULL;
       
  1074 		iSapList.Compress();		
       
  1075 		}
       
  1076 	}
       
  1077 	
       
  1078 /*
       
  1079 ------------------------------------------------------------------------------------------
       
  1080 
       
  1081                     	SAP UNUSED FUNTION SECTION
       
  1082 ------------------------------------------------------------------------------------------
       
  1083 
       
  1084 SAP definion which are not being used.These functions are not doing anything instead they are 
       
  1085 returning nothing from it.
       
  1086 
       
  1087 */
       
  1088 
       
  1089 void CSapNapt::Ioctl(TUint /*level*/,TUint /*name*/,TDes8*/*anOption*/)
       
  1090 	{}
       
  1091 
       
  1092 void CSapNapt::Start()
       
  1093 	{}
       
  1094 
       
  1095 void CSapNapt::Shutdown(TCloseType /*option*/)
       
  1096 	{}
       
  1097 
       
  1098 void CSapNapt::LocalName(TSockAddr& /*anAddr*/) const
       
  1099 	{}
       
  1100 
       
  1101 TInt CSapNapt::SetLocalName(TSockAddr& /*anAddr*/)
       
  1102 	{
       
  1103 	return KErrNotSupported;
       
  1104 	}
       
  1105 	
       
  1106 void CSapNapt::RemName(TSockAddr& /*anAddr*/) const 
       
  1107 	{}
       
  1108 
       
  1109 TInt CSapNapt::SetRemName(TSockAddr& /*anAddr*/) 
       
  1110 	{ 
       
  1111 	return KErrNotSupported;
       
  1112 	}
       
  1113 
       
  1114 TInt CSapNapt::GetOption(TUint aLevel, TUint aName, TDes8& aOption)const
       
  1115 /** 
       
  1116  * This implements GetOption method for Napt specific service provider.
       
  1117  * @param aLevel
       
  1118  * @param aName
       
  1119  * @param anOption
       
  1120  * @return KErrNone in case of success
       
  1121 **/
       
  1122 	{
       
  1123 	TInt err = KErrNone;
       
  1124 
       
  1125  	const TUplinkInfo* info= reinterpret_cast<const TUplinkInfo* >(aOption.Ptr());
       
  1126 	if(aLevel == KSolNapt &&  aName == KSoNaptUplink)
       
  1127 		{
       
  1128 		if(aOption.Length()!=sizeof(TUplinkInfo))
       
  1129 			{
       
  1130 			//this means that Block is not filled properly
       
  1131 			return KErrArgument;
       
  1132 			}
       
  1133 		TNaptConfigInfo* conf = iConfigMgr->FindConfig(info->iPrivateIap, EFalse);
       
  1134 		if(conf != NULL)
       
  1135 			{
       
  1136 			TUplinkInfo upinfo;
       
  1137 			upinfo.iPrivateIap = info->iPrivateIap;
       
  1138 			upinfo.iPublicIap = conf->iPublicIap;
       
  1139 			aOption.SetLength(sizeof(TUplinkInfo));
       
  1140 			aOption.Copy((TUint8 *)&upinfo, sizeof(TUplinkInfo));
       
  1141 			 
       
  1142 			}
       
  1143 		else
       
  1144 			err = KErrNotFound;
       
  1145 		}//For Uplink Information Option
       
  1146 	else
       
  1147 		{
       
  1148 		//Wrong socket option name /level
       
  1149 		err = KErrArgument;
       
  1150 		}
       
  1151 	 return err;
       
  1152 	}
       
  1153 
       
  1154 void CSapNapt::ActiveOpen()
       
  1155  	 {}
       
  1156  	 
       
  1157 TInt CSapNapt::PassiveOpen(TUint /*aQueSize*/)
       
  1158 	 {
       
  1159 	 return KErrNotSupported;
       
  1160 	 }
       
  1161 	 
       
  1162 void CSapNapt::Shutdown(TCloseType /*option*/,const TDesC8& /*aDisconnectionData*/)
       
  1163 	 {}
       
  1164 	 
       
  1165 void CSapNapt::AutoBind()
       
  1166 	 {}
       
  1167 
       
  1168 TInt CSapNapt::PassiveOpen(TUint /*aQueSize*/,const TDesC8& /*aConnectionData*/)
       
  1169 	{
       
  1170 	return KErrNotSupported;
       
  1171 	}
       
  1172 
       
  1173 void CSapNapt::ActiveOpen(const TDesC8& /*aConnectionData*/)
       
  1174 	{}
       
  1175 
       
  1176 void CSapNapt::CancelIoctl(TUint /*aLevel*/,TUint /*aName*/)
       
  1177 	{}
       
  1178 
       
  1179 CSapNapt::~CSapNapt()
       
  1180 	{
       
  1181 	//Cancel configuration in sap.This will reset all bits (public & private IAP and IP)
       
  1182 	iProtocol->CancelSap(this);
       
  1183 	}
       
  1184 	
       
  1185 
       
  1186