networkingtestandutils/networkingunittest/dummynif/dummynif6.cpp
changeset 0 af10295192d8
child 5 1422c6cd3f0c
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 2003-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 //
       
    15 
       
    16 #include <e32hal.h>	// UserHal::MachineInfo()
       
    17 #include <comms-infras/nifif.h>
       
    18 #include <nifvar.h>
       
    19 #include <nifutl.h>
       
    20 #include <es_mbuf.h>
       
    21 #include <in_iface.h>
       
    22 #include <comms-infras/commsdebugutility.h>
       
    23 #include <connectprog.h>
       
    24 
       
    25 #include <in_chk.h>
       
    26 #include <in_sock.h>
       
    27 #include <in6_if.h>	// KSoIface*, KIf*, TSoInet6IfConfig
       
    28 #include "dummynifvar.h"
       
    29 #include "dummynif.h"
       
    30 
       
    31 
       
    32 /*
       
    33  * The IPv6 interface binder class
       
    34  */
       
    35 
       
    36 CDummyIf6::CDummyIf6(CDummyIfLink& aLink)
       
    37 	: CNifIfBase(aLink)
       
    38 	{
       
    39 	CDummyIfLog::Printf(_L("CDummyIf6::CDummyIf6()"));
       
    40 
       
    41 	iLink = &aLink;
       
    42 
       
    43 	//
       
    44 	// Use the 64 bit id of MARM machines as our interface id
       
    45 	//
       
    46 	TMachineInfoV1Buf machineInfo;
       
    47 
       
    48 	UserHal::MachineInfo(machineInfo);
       
    49 	iLocalIfId.SetAddr(machineInfo().iMachineUniqueId);
       
    50 	iLocalIfId.SetUniversalBit(0);
       
    51 
       
    52 	//
       
    53 	// In WINS environment the id is zero which is no-no
       
    54 	//
       
    55 	if (iLocalIfId.IsZero())
       
    56 		iLocalIfId.SetAddrRandomNZ();
       
    57 
       
    58 	iIfName.Format(_L("dummynif6[0x%08x]"), this);
       
    59 	}
       
    60 
       
    61 void CDummyIf6::BindL(TAny *aId)
       
    62 	{
       
    63 	CDummyIfLog::Printf(_L("CDummyIf6::BindL(aId %x)"), aId);
       
    64 	if(iProtocol)
       
    65 		User::Leave(KErrAlreadyExists);
       
    66 	iProtocol = (CProtocolBase*)aId;	
       
    67 	}
       
    68 
       
    69 TInt CDummyIf6::Send(RMBufChain& aPdu, TAny*)
       
    70 	{
       
    71 	Recv(aPdu);
       
    72 	return 1;
       
    73 	}
       
    74 
       
    75 TInt CDummyIf6::State()
       
    76     {
       
    77     return EIfUp;
       
    78     }
       
    79 
       
    80 void CDummyIf6::UpdateHeaders(TInet6HeaderIP* aIp6, TInet6HeaderUDP* /*aUdp*/)
       
    81 {
       
    82 	// swap over the destination and source addresses
       
    83 	TIp6Addr temp;
       
    84 	temp = aIp6->SrcAddr();
       
    85 	aIp6->SetSrcAddr(aIp6->DstAddr());
       
    86 	aIp6->SetDstAddr(temp);
       
    87 }
       
    88 
       
    89 void CDummyIf6::Recv(RMBufChain& aPdu)
       
    90 	{
       
    91 
       
    92 	TInt res;
       
    93 
       
    94 	// this received data has already been looped back...
       
    95 	// get the ip header from the RMBufChain
       
    96 	TInet6HeaderIP* ip6 = (TInet6HeaderIP*) aPdu.First()->Next()->Ptr();
       
    97 	TInet6HeaderUDP* udp = NULL;
       
    98 
       
    99 	if ((TUint)ip6->NextHeader() == KProtocolInetUdp)
       
   100 		{
       
   101 		// get the udp header as well - assume only udp traffic here
       
   102 		udp = (TInet6HeaderUDP*) ip6->EndPtr();
       
   103 
       
   104 		CDummyIfLog::Printf(_L("CDummyIf6::Recv(...): UDP length %d, src port %d, dst port %d"),
       
   105 			udp->Length(), udp->SrcPort(), udp->DstPort());
       
   106 
       
   107 		// depending on the contents, pass it on up thru the stack 
       
   108 		// or maybe do something else
       
   109 
       
   110 		// use the destination port number to decide whether or not the payload is a command
       
   111 		TUint dstPort = udp->DstPort();
       
   112 		if (KDummyNifCmdPort == dstPort)
       
   113 			{	
       
   114 			// let's use the first payload byte as the command byte
       
   115 			switch (*(udp->EndPtr()))
       
   116 				{
       
   117 			case KForceDisconnect:
       
   118 				CDummyIfLog::Printf(_L("KForceDisconnect command"));
       
   119 				// do some action
       
   120 				iNotify->IfProgress(KLinkLayerClosed, KErrCommsLineFail);
       
   121 				iNotify->LinkLayerDown(KErrCommsLineFail, MNifIfNotify::EDisconnect);
       
   122 				// no return code so all we can do is respond with what we got
       
   123 				UpdateHeaders(ip6, udp);
       
   124 				iProtocol->Process(aPdu, (CProtocolBase*)this);
       
   125 				break;
       
   126 
       
   127 			case KForceReconnect:
       
   128 				CDummyIfLog::Printf(_L("KForceReconnect command"));
       
   129 				// do some action
       
   130 				iNotify->IfProgress(KLinkLayerClosed, KErrCommsLineFail);
       
   131 				iNotify->LinkLayerDown(KErrCommsLineFail, MNifIfNotify::EReconnect);
       
   132 				// no return code so all we can do is respond with what we got
       
   133 				UpdateHeaders(ip6, udp);
       
   134 				iProtocol->Process(aPdu, (CProtocolBase*)this);
       
   135 				break;
       
   136 
       
   137 			case KSendNotification:
       
   138 				CDummyIfLog::Printf(_L("KSendNotification command"));
       
   139 				res = iNotify->Notification(ENifToAgentEventTypeQueryIsDialIn);
       
   140 				//let's write the result in the next byte of the reply
       
   141 				if (res == KErrNotSupported)
       
   142 					udp->EndPtr()[1] = (unsigned char) KErrNone;
       
   143 				else
       
   144 					udp->EndPtr()[1] = (unsigned char) KErrGeneral; // this will lose it's sign :-(
       
   145 				
       
   146 				UpdateHeaders(ip6, udp);
       
   147 				iProtocol->Process(aPdu, (CProtocolBase*)this);
       
   148 				break;
       
   149 
       
   150 			default:
       
   151 				CDummyIfLog::Printf(_L("Unknown command - ignoring it"));
       
   152 				break;
       
   153 				// unknown command, just ignore this packet???
       
   154 				}
       
   155 			return;
       
   156 			}
       
   157 
       
   158 		}
       
   159 	else
       
   160 		{
       
   161 		CDummyIfLog::Printf(_L("CDummyIf6::Recv(...): IPv6 length %d, next header %d"),
       
   162 			ip6->PayloadLength(), ip6->NextHeader());
       
   163 		}
       
   164 
       
   165 	// just echo the packet back to the original sender
       
   166 
       
   167 	// update the headers (addresses, checksums etc).  If "udp" is non-NULL, then
       
   168 	// the UDP ports will be updated as well.
       
   169 	UpdateHeaders(ip6, udp);
       
   170 	// now process it (pass up the stack)
       
   171 	iProtocol->Process(aPdu, (CProtocolBase*)this);		
       
   172 }
       
   173 
       
   174 void CDummyIf6::Info(TNifIfInfo& aInfo) const
       
   175 	{
       
   176 	aInfo.iVersion = TVersion(1,1,1);
       
   177 	aInfo.iFlags = KNifIfIsBase | KNifIfUsesNotify | KNifIfCreatedByLink;
       
   178 	aInfo.iName.Copy(iIfName);
       
   179 	aInfo.iProtocolSupported = 0;
       
   180 	}
       
   181 
       
   182 TInt CDummyIf6::Control(TUint aLevel, TUint aName, TDes8& aOption, TAny* /* aSource */)
       
   183 	{
       
   184 
       
   185 	if (aLevel==KSOLInterface)
       
   186 		{
       
   187 		switch (aName)
       
   188 			{
       
   189 		case KSoIfInfo6:
       
   190 			{
       
   191 			CDummyIfLog::Printf(_L("CDummyIf6::Control(KSOLInterface, KSoIfInfo6, ...)"));
       
   192 			__ASSERT_DEBUG((TUint)aOption.MaxLength() >= sizeof (TSoIfInfo6), User::Panic(_L("Dummy6"), 0));
       
   193 
       
   194 			if ((TUint)aOption.MaxLength() < sizeof (TSoIfInfo6))
       
   195 				return KErrArgument;
       
   196 
       
   197 			TSoIfInfo6& opt = *(TSoIfInfo6*)aOption.Ptr();
       
   198 			opt.iFeatures = KIfCanBroadcast | KIfCanMulticast;
       
   199 			opt.iName.Copy(iIfName);
       
   200 			opt.iMtu = 1500;
       
   201 			opt.iRMtu = opt.iMtu;
       
   202 			opt.iSpeedMetric = 0;
       
   203 
       
   204 			return KErrNone;
       
   205 			}
       
   206 
       
   207 		case KSoIfHardwareAddr:
       
   208 			return KErrNotSupported;
       
   209 
       
   210 		case KSoIfConfig:
       
   211 			{
       
   212 			CDummyIfLog::Printf(_L("CDummyIf6::Control(KSOLInterface, KSoIfConfig, ...)"));
       
   213 			__ASSERT_DEBUG((TUint)aOption.MaxLength() >= sizeof (TSoInet6IfConfig), User::Panic(_L("Dummy6"), 0));
       
   214 
       
   215 			if ((TUint)aOption.MaxLength() < sizeof (TSoInet6IfConfig))
       
   216 				return KErrArgument;
       
   217 
       
   218 			TSoInet6IfConfig& opt = *(TSoInet6IfConfig*)aOption.Ptr();
       
   219 			if (opt.iFamily != KAfInet6)
       
   220 				return KErrNotSupported;
       
   221 
       
   222 			TEui64Addr* ifId = (TEui64Addr*)&opt.iLocalId;
       
   223 
       
   224 			ifId->Init();
       
   225 			ifId->SetAddress(iLocalIfId);
       
   226 
       
   227 			ifId = (TEui64Addr*)&opt.iRemoteId;
       
   228 			ifId->Init();
       
   229 			ifId->SetAddress(iRemoteIfId);
       
   230 
       
   231 			// Setup static DNS address if required
       
   232 
       
   233 			if (!iPrimaryDns.IsUnspecified())
       
   234 				{
       
   235 				opt.iNameSer1.SetAddress(iPrimaryDns);
       
   236 				if (!iSecondaryDns.IsUnspecified())
       
   237 					opt.iNameSer2.SetAddress(iSecondaryDns);
       
   238 				}
       
   239 
       
   240 			opt.idPaddingBits = 0;
       
   241 			return KErrNone;
       
   242 			}
       
   243 
       
   244 		case KSoIfGetConnectionInfo:
       
   245 			{
       
   246 			CDummyIfLog::Printf(_L("CDummyIf6::Control(KSOLInterface, KSoIfGetConnectionInfo, ...)"));
       
   247 			TSoIfConnectionInfo& opt = *(TSoIfConnectionInfo*)aOption.Ptr();
       
   248 			TInt err = KErrNone;
       
   249 			TBuf<2*KCommsDbSvrMaxColumnNameLength+1> fieldName;
       
   250 			_LIT(KSlashChar, "\\");
       
   251 
       
   252 			fieldName.Copy(TPtrC(IAP));
       
   253 			fieldName.Append(KSlashChar);
       
   254 			fieldName.Append(TPtrC(COMMDB_ID));
       
   255 			if ((err = iNotify->ReadInt(fieldName, opt.iIAPId)) != KErrNone)
       
   256 				return err;
       
   257 
       
   258 			fieldName.Copy(TPtrC(IAP));
       
   259 			fieldName.Append(KSlashChar);
       
   260 			fieldName.Append(TPtrC(IAP_NETWORK));
       
   261 			if ((err = iNotify->ReadInt(fieldName, opt.iNetworkId)) != KErrNone)
       
   262 				return err;
       
   263 
       
   264 			return KErrNone;
       
   265 			}
       
   266 		default:
       
   267 			CDummyIfLog::Printf(_L("CDummyIf6::Control(KSOLInterface, aName %x, ...)"), aName);
       
   268 			break;
       
   269 			}
       
   270 		}
       
   271 	else
       
   272 		{
       
   273 		CDummyIfLog::Printf(_L("CDummyIf6::Control(aLevel %x, aName %x, ...)"), aLevel, aName);
       
   274 		}
       
   275 	return KErrNotSupported;
       
   276 	}
       
   277 
       
   278 TInt CDummyIf6::Notification(TAgentToNifEventType /*aEvent*/, void * /*aInfo*/)
       
   279 	{
       
   280 	return KErrNone;
       
   281 	}
       
   282 
       
   283 void CDummyIf6::StaticDnsConfiguration()
       
   284 	{
       
   285 	TBool requestDynamicDNSAddress;
       
   286 	// See whether we are configured to request a dynamic DNS address.
       
   287 	if (iNotify->ReadBool(TPtrC(SERVICE_IP6_DNS_ADDR_FROM_SERVER), requestDynamicDNSAddress) != KErrNone)
       
   288 		{
       
   289 		// Default behaviour
       
   290 		requestDynamicDNSAddress = ETrue;
       
   291 		}
       
   292 
       
   293 	if(!requestDynamicDNSAddress)
       
   294 		{
       
   295 		// Setup static DNS addresses from CommDb
       
   296 		CDummyIfLog::Printf(_L("CDummyIf6: Configuring static DNS addresses"));
       
   297 		PresetAddr(iPrimaryDns, TPtrC(SERVICE_IP6_NAME_SERVER1));
       
   298 		PresetAddr(iSecondaryDns, TPtrC(SERVICE_IP6_NAME_SERVER2));
       
   299 		}
       
   300 	else
       
   301 		{
       
   302 		// Ensure that static DNS addresses are set as unspecified,
       
   303 		// so they are not used in Control(KSoIfConfig).
       
   304 		iPrimaryDns = KInet6AddrNone;
       
   305 		iSecondaryDns = KInet6AddrNone;
       
   306 		}
       
   307 	}
       
   308 
       
   309 TInt CDummyIf6::PresetAddr(TIp6Addr& aAddr, const TDesC& aVarName)
       
   310 /**
       
   311  * Preset IP adress in aAddr with value from CommDB. The field name
       
   312  * is given in aVarName. Examples are "IpAddr" and "IpNameServer1"
       
   313  *
       
   314  * @param aAddr    IP address to be set
       
   315  * @param aVarName name of CommDB field
       
   316  * @return KErrNone if success, global error code otherwise
       
   317  */
       
   318 	{
       
   319 	if (!aAddr.IsUnspecified())
       
   320 		return KErrNone;
       
   321 	
       
   322 	TBuf<KCommsDbSvrMaxFieldLength> name;
       
   323 
       
   324 	(void)iNotify->ReadDes(aVarName, name); // ignore return value
       
   325 	TInetAddr ip6Addr;
       
   326 
       
   327 	TInt ret = ip6Addr.Input(name);
       
   328 	if (ret == KErrNone)
       
   329 		{
       
   330 		aAddr = ip6Addr.Ip6Address();
       
   331 		}
       
   332 	return ret;
       
   333 	}