linklayerprotocols/ethernetnif/EthInt/CLanIp6Bearer.cpp
changeset 0 af10295192d8
child 5 1422c6cd3f0c
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 1997-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 CLanIp6Bearer class, a derived from CLanxBearer.
       
    15 // History
       
    16 // 15/11/01 Started by Julian Skidmore.
       
    17 // 11/03		Refactored as part of the DHCP relocation work 
       
    18 // 
       
    19 //
       
    20 
       
    21 /**
       
    22  @file
       
    23 */
       
    24 
       
    25 #include <in_sock.h> // Header is retained, but in_sock.h is modified for ipv6
       
    26 #include <in6_if.h>
       
    27 #include <in_pkt.h>
       
    28 #include <comms-infras/connectionsettings.h>
       
    29 #include "CLanIp6Bearer.h"
       
    30 #include "EthProto.h"
       
    31 #include <comms-infras/es_protbinder.h>
       
    32 #include "EthProvision.h"
       
    33 
       
    34 using namespace ESock;
       
    35 
       
    36 /**
       
    37 Required ConstructL() method.  Performs the following:
       
    38 "	Sets a unique name for this binder instance in the iIfName field - "eth6[0x%x]" where "%x"
       
    39     is the hexadecimal address of the "this" object.
       
    40 "	Update the MAC address from link using UpdateMACAddr()
       
    41 "	Reads CommDb settings (e.g. IPv6 static DNS configuration) from the LAN Service Table via 
       
    42     ReadCommDbLanSettingsL().
       
    43 */
       
    44 void CLanIp6Bearer::ConstructL()
       
    45 {
       
    46 	iIfName.Format(_L("eth6[0x%08x]"), this);
       
    47    	UpdateMACAddr();
       
    48 	// ReadCommDbLanSettingsL() moved from here to point when provisioning information received
       
    49 }
       
    50 
       
    51 TInt CLanIp6Bearer::Control(TUint aLevel,TUint aName,TDes8& aOption)
       
    52 {
       
    53 	if ((aLevel==KCOLInterface) || (aLevel==KSOLInterface))
       
    54    		{
       
    55 		switch (aName)
       
    56       		{
       
    57 			case KSoIfHardwareAddr:
       
    58 			 	{
       
    59 				typedef TPckgBuf<TSoIfHardwareAddr> THwAddr;
       
    60 				THwAddr& theHwAddrRef=((THwAddr&)aOption);
       
    61 				THwAddr hwAddrCopy(theHwAddrRef);
       
    62 				theHwAddrRef().iHardwareAddr.SetFamily(1); // Set the address family type
       
    63 				theHwAddrRef().iHardwareAddr.SetLength(4); // The length of the family part.
       
    64 				theHwAddrRef().iHardwareAddr.Append(hwAddrCopy.Mid(12,4));		// set the hardware type in the port field
       
    65 				theHwAddrRef().iHardwareAddr.Append(Link()->MacAddress());
       
    66 				return KErrNone;
       
    67 				}
       
    68         	default:
       
    69          		return KErrNotSupported;
       
    70       		}
       
    71    		}
       
    72 	return KErrNotSupported;
       
    73 }
       
    74 
       
    75 /**
       
    76 ResolveMulticastIp6 is a helper method for Process. It takes a TSockAddr& destination address
       
    77 and a reference to the packet and generates a destination Mac address automatically from the 
       
    78 destination Ip6 address, by applying the standard KMulticastPrefix (which is the byte sequence
       
    79 {0x33, 0x33}) and then appending bytes 12 to 15 of the Ip6 destination address.
       
    80 @param aDstAddr The destination address from the info header on the packet
       
    81 @param aPdu		The Ip6 packet (actually an RMBufPacket).
       
    82 */
       
    83 void CLanIp6Bearer::ResolveMulticastIp6(TSockAddr& aDstAddr,RMBufChain& aPdu)
       
    84 { 
       
    85 	// We need to obtain the IPv6 header - i.e. the destination address.
       
    86 	// Octets 12 to 15 of the destination address, should be copied to
       
    87 	// Octets 2 to 5 of the aDstAddr.
       
    88 	// Octets 0 and 1 should be 0x3333.
       
    89 	TIpv6Header* header = (TIpv6Header*)aPdu.First()->Next()->Ptr(); 
       
    90 	//__ASSERT_DEBUG(header->GetVersion()==6, User::Panic(_L("Ether6:3"), 0));
       
    91 	TUint ix;
       
    92 	for(ix=0; ix<2; ix++)
       
    93 		{
       
    94 		aDstAddr[ix]=KMulticastPrefix[ix];
       
    95 		}
       
    96 	for(ix=2; ix<KMACByteLength; ix++)
       
    97 		{
       
    98 		aDstAddr[ix]=header->iDestAddrB[ix+10];
       
    99 		}
       
   100 }
       
   101 
       
   102 /**
       
   103 ShiftLinkLayerAddress is a helper method for Process. It takes a TSockAddr& destination address 
       
   104 which already contains the correct information, but in the wrong place and copies bytes 8 to 1
       
   105 3 of the aDstAddr to 0 to 5 of aDstAddr.
       
   106 @param aDstAddr The destination address from the info header on the packet
       
   107 */
       
   108 void CLanIp6Bearer::ShiftLinkLayerAddress(TSockAddr& aDstAddr)
       
   109 {
       
   110 	for(TUint ix=0; ix<KMACByteLength; ix++)
       
   111 		{
       
   112 		aDstAddr[ix]=aDstAddr[ix+8];
       
   113 		}
       
   114 }
       
   115 
       
   116 /**
       
   117 Call down from the Protocol
       
   118 Real Protocol data is in the second MBuf of the RMBufChain
       
   119 ARP will modify the first MBuf so it's ready for EtherXX Framing and
       
   120 will have inserted the dest MAC address if it could resolve it
       
   121 ARP send method returns KErrNotFound if it can't resolve and ARP
       
   122 hangs onto the packet data till the address is resolved at which
       
   123 point it calls us back to forward the pdu to the packet driver.
       
   124 Caller Flow controls off if the return to this method is <= 0
       
   125 @param aPdu		A reference to the packet to be sent (really an RMBufPkt)
       
   126 @param aSource  A pointer to the source protocol.
       
   127 @return The no. of bytes send.
       
   128 */
       
   129 MLowerDataSender::TSendResult CLanIp6Bearer::Send(RMBufChain& aPdu)
       
   130 {
       
   131 	// Check that we are allowed to send data
       
   132 	if (!Link()->BearerIsActive(this))
       
   133 		{
       
   134 			aPdu.Free();
       
   135 			return ESendBlocked;
       
   136 		}
       
   137 
       
   138 	// just some checking.
       
   139 	RMBufPktInfo* info = RMBufPacket::PeekInfoInChain(aPdu);
       
   140 	TUint32 family = info->iDstAddr.Family();
       
   141 	__ASSERT_DEBUG(family!=KAfInet, User::Panic(_L("Ether6:1"), 0));
       
   142 	if(family==KAfInet6)
       
   143 		{											// Have to generate the MAC as described in 
       
   144 		ResolveMulticastIp6(info->iDstAddr,aPdu); 	//the RFC2464, section 7.
       
   145 		}
       
   146 	else if (family==0x1)
       
   147 		{
       
   148 		ShiftLinkLayerAddress(info->iDstAddr);
       
   149 		}
       
   150 	return static_cast<MLowerDataSender::TSendResult>(Link()->FrameSend(aPdu,NULL,KIP6FrameType));
       
   151 }
       
   152 
       
   153 /**
       
   154 WantsProtocol, takes an ethernet aProtocolCode code and the initial part of the packet's 
       
   155 payload as input and returns ETrue if the bearer wants the packet of this type of protocol 
       
   156 and payload, or EFalse otherwise. CLanIp6Bearer wants the protocol if it is an Arp message or
       
   157 an Ip6 protocol (an Ip protocol, whose Version field == 6). WantsProtocol also sets 
       
   158 iArpMsgNext to ETrue if the protocol was Arp or EFalse otherwise.
       
   159 @param aProtocolCode The Ethernet protocol Type.
       
   160 @param aPayload A pointer to the beginning of the packet payload.
       
   161 @return sets iArpMsgNext to ETrue if the protocol was Arp or EFalse otherwise.
       
   162 */
       
   163 TBool CLanIp6Bearer::WantsProtocol(TUint16 aProtocolCode,const TUint8* aPayload)
       
   164 {
       
   165 	return (aProtocolCode==KIP6FrameType && (aPayload[0]>>4)==KIP6Protocol) ? ETrue:EFalse;
       
   166 }
       
   167 
       
   168 /**
       
   169 Process processes a packet received from the LinkLayer.
       
   170 @param aPdu The Packet to be sent (actually an RMBufPkt).
       
   171 @param aLLC Unclear.
       
   172 */
       
   173 void CLanIp6Bearer::Process(RMBufChain& aPdu, TAny* /*aLLC*/)
       
   174 {
       
   175 	if(iUpperReceiver)
       
   176 		{
       
   177 		iUpperReceiver->Process(aPdu);
       
   178 		}
       
   179 	else
       
   180 		{
       
   181 	  	aPdu.Free();
       
   182 	  	}
       
   183 }
       
   184 
       
   185 void CLanIp6Bearer::UpdateMACAddr()
       
   186 {
       
   187 	TE64Addr myEuMac;
       
   188 	myEuMac.SetAddrFromEUI48(Link()->MacAddress().Ptr());
       
   189 	iEuiMac.SetAddress(myEuMac);
       
   190 }
       
   191 
       
   192 /**
       
   193 Read any static DNS configuration information from CommDb
       
   194 ReadCommDbLanSettingsL() reads CommDb settings from the LAN Service Table.  In particular, it 
       
   195 reads the fields related to IPv6 Static DNS configuration.  The LAN_IP6_DNS_ADDR_FROM_SERVER 
       
   196 field is a boolean that indicates whether IPv6 Static DNS configuration is required or not.  
       
   197 If FALSE, then static configuration is required.  In this case, the IPv6 primary and secondary 
       
   198 DNS server addresses are read from the CommDb fields LAN_IP6_NAME_SERVER1 and LAN_IP6_NAME_SERVER2 
       
   199 and stored in the iPrimaryDns and iSecondaryDns data members.  They are later presented to 
       
   200 the TCP/IP stack when the Control() method is called with the KSoIfConfig option.
       
   201 */
       
   202 void CLanIp6Bearer::ReadCommDbLanSettingsL()
       
   203 {
       
   204 	ASSERT(iProvision);
       
   205 	iPrimaryDns = iProvision->PrimaryDns();
       
   206 	iSecondaryDns = iProvision->SecondaryDns();
       
   207 }
       
   208 
       
   209 TInt CLanIp6Bearer::GetConfig(TBinderConfig& aConfig)
       
   210 	{
       
   211     TBinderConfig6* config = TBinderConfig::Cast<TBinderConfig6>(aConfig);
       
   212     
       
   213 	if(config == NULL)
       
   214 		{
       
   215 		return KErrNotSupported;
       
   216 		}
       
   217 
       
   218 	config->iFamily = KAfInet6;
       
   219 		
       
   220 	config->iInfo.iFeatures = KIfNeedsND | KIfCanMulticast;
       
   221 	config->iInfo.iMtu = Link()->Mtu();
       
   222 	config->iInfo.iRMtu = Link()->Mtu();
       
   223 	config->iInfo.iSpeedMetric = Link()->SpeedMetric();
       
   224 	
       
   225 	TEui64Addr& localId = TEui64Addr::Cast(config->iLocalId);
       
   226 	localId = iEuiMac;
       
   227 
       
   228 	// If required, configure static DNS addresses
       
   229 
       
   230 	if (!iPrimaryDns.IsUnspecified())
       
   231 		{
       
   232 		config->iNameSer1.SetAddress(iPrimaryDns);
       
   233 		if (!iSecondaryDns.IsUnspecified())
       
   234 			config->iNameSer2.SetAddress(iSecondaryDns);
       
   235 		}
       
   236 
       
   237 	return KErrNone;
       
   238 	}
       
   239 
       
   240 const TDesC8& CLanIp6Bearer::ProtocolName() const
       
   241 /**
       
   242 Return the protocol name of this bearer
       
   243 
       
   244 Called from CLANLinkCommon
       
   245 */
       
   246 	{
       
   247 	_LIT8(KProtocolName, "ip6");
       
   248 	return KProtocolName();
       
   249 	}
       
   250 
       
   251 void CLanIp6Bearer::SetProvisionL(const Meta::SMetaData* aProvision)
       
   252 	{
       
   253 	if (iProvision == NULL)
       
   254 		{
       
   255 		iProvision = static_cast<const TLanIp6Provision*>(aProvision);
       
   256    		ReadCommDbLanSettingsL();
       
   257 		}
       
   258 	}
       
   259