linklayerprotocols/tundriver/src/tundriverbinder.cpp
branchRCL_3
changeset 63 425d8f4f7fa5
equal deleted inserted replaced
58:8d540f55e491 63:425d8f4f7fa5
       
     1 /**
       
     2 *   Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 *   All rights reserved.
       
     4 *   This component and the accompanying materials are made available
       
     5 *   under the terms of "Eclipse Public License v1.0"
       
     6 *   which accompanies this distribution, and is available
       
     7 *   at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *   
       
     9 *   Initial Contributors:
       
    10 *   Nokia Corporation - initial contribution.
       
    11 *   
       
    12 *   Contributors:
       
    13 *
       
    14 *   Description:
       
    15 *   Ipv4 and Ipv6 Binder configuration source file.
       
    16 * 
       
    17 *
       
    18 */
       
    19 
       
    20 /**
       
    21  @file tundriverbinder.cpp
       
    22  @internalTechnology
       
    23  */
       
    24 
       
    25 #include <e32std.h>
       
    26 #include <eui_addr.h>
       
    27 #include <ip4_hdr.h>
       
    28 #include <udp_hdr.h>
       
    29 #include <in_chk.h>
       
    30 #include <in_iface.h>
       
    31 #include <comms-infras/nifif.h>
       
    32 #include <in_sock.h>
       
    33 #include <flow.h>
       
    34 #include "tundriverbinder.h"
       
    35 #include "tundriverprovision.h"
       
    36 
       
    37 using namespace ESock;
       
    38 
       
    39 #ifdef _DEBUG
       
    40 _LIT8(KNif,"TunDriver");
       
    41 _LIT8(KBinder4,"Binder4");
       
    42 #ifdef IPV6SUPPORT
       
    43 _LIT8(KBinder6,"Binder6");
       
    44 #endif
       
    45 #endif
       
    46 
       
    47 //////////////////////
       
    48 // CTunDriverBinder //
       
    49 //////////////////////
       
    50 
       
    51 CTunDriverBinder::CTunDriverBinder(CTunDriverSubConnectionFlow& aTunDriverSubConnectionFlow) : iTunDriverSubConnectionFlow(aTunDriverSubConnectionFlow)
       
    52 /*
       
    53 * Default constructor for Binder Base Class.
       
    54 */
       
    55         {
       
    56         }
       
    57 
       
    58 MLowerDataSender* CTunDriverBinder::Bind(MUpperDataReceiver& /*aUpperReceiver*/, MUpperControl& /*aUpperControl*/)
       
    59 /**
       
    60 * Virtual Function, Implementation is binder specific (IPv4 or IPv6)
       
    61 * If This Bind function is called, then there is an error in binding.
       
    62 * @param Not used here
       
    63 * @return NULL.
       
    64 */
       
    65     {
       
    66     return NULL;
       
    67     }
       
    68 
       
    69 void CTunDriverBinder::Unbind(MUpperDataReceiver& /*aUpperReceiver*/, MUpperControl& /*aUpperControl*/)
       
    70 /**
       
    71 * Virtual Function, Implementation is binder specific (IPv4 or IPv6)
       
    72 * @param Not used here
       
    73 */
       
    74     {
       
    75     }
       
    76 
       
    77 void CTunDriverBinder::SetPort(TUint aPort)
       
    78 /**
       
    79 * CTunDriverBinder::SetPort is used to set port common for Ip4Binder and Ip6Binder
       
    80 * @param aPort
       
    81 * @return
       
    82 */
       
    83     {
       
    84     iPort = aPort;
       
    85     }
       
    86 
       
    87 TUint CTunDriverBinder::GetPort()
       
    88 /**
       
    89 * CTunDriverBinder::GetPort is used to obtain port common for Ip4Binder and Ip6Binder
       
    90 * @param Not used here
       
    91 * @return iPort
       
    92 */
       
    93     {
       
    94     return iPort;
       
    95     }
       
    96 
       
    97 TBool CTunDriverBinder::MatchesUpperControl(ESock::MUpperControl* /*aUpperControl*/) const
       
    98 /**
       
    99 * Virtual Function, Implementation is binder specific (IPv4 or IPv6)
       
   100 * If This MatchesUpperControl function is called, then there is an error in binding.
       
   101 * @param Not used here
       
   102 * @return EFalse.
       
   103 */
       
   104     {
       
   105     return EFalse;
       
   106     }
       
   107 
       
   108 CTunDriverBinder4* CTunDriverBinder4::NewL(CTunDriverSubConnectionFlow& aTunDriverSubConnectionFlow)
       
   109 /**
       
   110 * CTunDriverBinder4::NewL
       
   111 * This function is invoked by the flow. This CTunDriverBinder4 is IPv4 specific.
       
   112 * @param CTunDriverSubConnectionFlow
       
   113 * @return CTunDriverSubConnectionFlow.
       
   114 */
       
   115     {
       
   116     CTunDriverBinder4* self = new (ELeave)CTunDriverBinder4(aTunDriverSubConnectionFlow);
       
   117     CleanupStack::PushL(self);
       
   118     self->ConstructL();
       
   119     CleanupStack::Pop(self);
       
   120     return self;
       
   121     }
       
   122 
       
   123 void CTunDriverBinder4::ConstructL()
       
   124 /**
       
   125 * CTunDriverBinder4::ConstructL is the second-phase constructor.
       
   126 * This function is invoked by NewL.
       
   127 * This function initializes the asynchronous callback functions for sending and receiving packets.
       
   128 * @param 
       
   129 * @return.
       
   130 */
       
   131     {
       
   132     TCallBack scb(SendCallBack, this);
       
   133     iSendCallBack = new(ELeave) CAsyncCallBack(scb, EPriorityNormal);
       
   134 
       
   135     TCallBack rcb(RecvCallBack, this);
       
   136     iRecvCallBack = new(ELeave) CAsyncCallBack(rcb, EPriorityNormal);
       
   137     }
       
   138 
       
   139 CTunDriverBinder4::CTunDriverBinder4(CTunDriverSubConnectionFlow& aTunDriverSubConnectionFlow) : CTunDriverBinder(aTunDriverSubConnectionFlow),iTunDriverSubConnectionFlow(aTunDriverSubConnectionFlow)
       
   140 /**
       
   141 * CTunDriverBinder4::CTunDriverBinder4 is the default constructor.
       
   142 * This function is invoked by NewL.
       
   143 * This function initializes localaddress to 0.0.0.0.
       
   144 * @param 
       
   145 * @return.
       
   146 */
       
   147         {
       
   148         __FLOG_OPEN(KNif, KBinder4);
       
   149         iLocalAddress = KInetAddrNone;
       
   150         __FLOG_3(_L8("CTunDriverBinder4 %08x:\tCTunDriverBinder4(CTunDriverSubConnectionFlow& %08x): iLocalAddress %08x"), this, &aTunDriverSubConnectionFlow, iLocalAddress.Address());
       
   151         }
       
   152 
       
   153 CTunDriverBinder4::~CTunDriverBinder4()
       
   154 /**
       
   155 * CTunDriverBinder4::CTunDriverBinder4 is the default destructor.
       
   156 * This function frees the RMBufPkt queues and 
       
   157 * deletes the asynchrounous call back pointers initialized at the time of construction.
       
   158 * @param 
       
   159 * @return.
       
   160 */
       
   161     {
       
   162     __FLOG_1(_L8("CTunDriverBinder4 %08x:\t~CTunDriverBinder4()"), this);
       
   163     iRecvQ.Free();
       
   164     iSendQ.Free();
       
   165     delete iRecvCallBack;
       
   166     delete iSendCallBack;
       
   167     }
       
   168 
       
   169 MLowerDataSender* CTunDriverBinder4::Bind(MUpperDataReceiver& aUpperReceiver, MUpperControl& aUpperControl)
       
   170 /**
       
   171 * CTunDriverBinder4::Bind Binds upper CommsFramwork Protocol to this CommsFramwork Protocol.
       
   172 * @param aUpperReceiver A pointer to Upper layer Receive class
       
   173 * @param aUpperControl A pointer to Upper layer control class
       
   174 * @return this.
       
   175 */
       
   176     {
       
   177     __FLOG_3(_L8("CTunDriverBinder4 %08x:\tBind(aUpperReceiver %08x, aUpperControl %08x)"), this, &aUpperReceiver, &aUpperControl);
       
   178     iUpperReceiver = &aUpperReceiver;
       
   179     iUpperControl = &aUpperControl;
       
   180     return this;
       
   181     }
       
   182 
       
   183 void CTunDriverBinder4::Unbind(MUpperDataReceiver& /*aUpperReceiver*/, MUpperControl& /*aUpperControl*/)
       
   184 /**
       
   185 * CTunDriverBinder4::UnBind UnBinds the assocication of CommsFramwork Protocol from this CommsFramwork Protocol.
       
   186 * @param aUpperReceiver A pointer to Upper layer Receive class
       
   187 * @param aUpperControl A pointer to Upper layer control class
       
   188 * @return.
       
   189 */
       
   190     {
       
   191     __FLOG_1(_L8("CTunDriverBinder4 %08x:\tUnbind()"), this);
       
   192     iUpperReceiver = NULL;
       
   193     iUpperControl = NULL;
       
   194     }
       
   195 
       
   196 void CTunDriverBinder4::StartSending()
       
   197 /**
       
   198 * CTunDriverBinder4::StartSending is signaled to the upperlayer that Binder is ready to send packets.
       
   199 * This function will be called only once when the interface is started.
       
   200 * @param 
       
   201 * @return.
       
   202 */
       
   203     {
       
   204     __FLOG_1(_L8("CTunDriverBinder4 %08x:\tBinderReady()"), this);
       
   205     iUpperControl->StartSending();
       
   206     }
       
   207 
       
   208 TBool CTunDriverBinder4::MatchesUpperControl(ESock::MUpperControl* aUpperControl) const
       
   209 /**
       
   210 * CTunDriverBinder4::MatchesUpperControl returns whether this binder is associated with the
       
   211 * MUpperControl object passed as argument.
       
   212 * This function will be called while Unbinding the flow.
       
   213 * @param aUpperControl upper layer to match against
       
   214 * @return ETrue on a match else EFalse.
       
   215 */
       
   216     {
       
   217     return (aUpperControl == iUpperControl);
       
   218     }
       
   219 
       
   220 MLowerDataSender::TSendResult CTunDriverBinder4::Send(RMBufChain& aData)
       
   221 /**
       
   222 * CTunDriverBinder4::Send places the stack packet in SendQueue and breaks the call.
       
   223 * Then asynchrounous callback function is invoked.
       
   224 * @param aData MBuf chain containing data to send
       
   225 * @return ESendAccepted.
       
   226 */
       
   227     {
       
   228     iSendQ.Append(aData);
       
   229     iSendCallBack->CallBack();
       
   230     return ESendAccepted;
       
   231     }
       
   232 
       
   233 TInt CTunDriverBinder4::GetConfig(TBinderConfig& aConfig)
       
   234 /**
       
   235 * CTunDriverBinder4::GetConfig populates the interface IPv4 configuration information.
       
   236 * This function is invoked by the upperlayer
       
   237 * @param aConfig structure.
       
   238 * @return KErrNone if IPv4 binderconfiguration exists.
       
   239 * @return KErrNotSupported otherwise. 
       
   240 */ 
       
   241     {
       
   242     TBinderConfig4* config = TBinderConfig::Cast<TBinderConfig4>(aConfig);
       
   243 
       
   244     if(config == NULL)
       
   245         {
       
   246         return KErrNotSupported;
       
   247         }
       
   248     const TTunDriverIp4Provision* ip4Provision = Flow()->Ip4Provision();
       
   249     // Setup config
       
   250     iLocalAddress = ip4Provision->LocalAddr();
       
   251     config->iInfo.iFeatures = KIfCanBroadcast | KIfCanMulticast;
       
   252     config->iInfo.iMtu = KMTU;
       
   253     config->iInfo.iRMtu = KMTU;
       
   254     config->iInfo.iSpeedMetric = KSpeedMetric;
       
   255     config->iFamily = KAfInet;
       
   256 
       
   257     __FLOG_2(_L8("CTunDriverBinder4 %08x:\tGetConfig(): iLocalAddress %08x"), this, iLocalAddress.Address());
       
   258     config->iAddress.SetAddress(iLocalAddress.Address());
       
   259 
       
   260 
       
   261     TInetAddr address = ip4Provision->DefGateway();
       
   262     config->iDefGate.SetAddress(address.Address());
       
   263     // primary DNS, just make same as default gateway
       
   264     address = ip4Provision->PrimaryDns();
       
   265     config->iNameSer1.SetAddress(address.Address());
       
   266     // secondary DNS
       
   267     address = ip4Provision->SecondaryDns();
       
   268     config->iNameSer2.SetAddress(address.Address());
       
   269     return KErrNone;
       
   270     }
       
   271 
       
   272 TInt CTunDriverBinder::Control(TUint aLevel, TUint aName, TDes8& aOption)
       
   273 /**
       
   274 * CTunDriverBinder::Control is to check wether the packet is intended for tundriver or not.
       
   275 * Called from the upperlayer to identify the special control functionality.
       
   276 * Also the sets the port number.
       
   277 * @param aLevel
       
   278 * @param aName
       
   279 * @param aOption
       
   280 * @return KErrNone if packet is intended for Ipv4 tundriver.
       
   281 * @return KErrNotSupported otherwise. 
       
   282 */ 
       
   283     {
       
   284     __FLOG_3(_L("CTunDriverBinder %08x:\tControl(aLevel %x, aName %x)"), this, aLevel, aName);
       
   285     if((aLevel == KSolInetIp) && (aName == KSoTunnelPort))
       
   286         {
       
   287         TInetAddr& localAddress = *(TInetAddr*) aOption.Ptr();
       
   288         SetPort(localAddress.Port());
       
   289         return KErrNone;
       
   290         }
       
   291     return KErrNotSupported;
       
   292     }
       
   293 
       
   294 TInt CTunDriverBinder4::GetName(TDes& aName)
       
   295 /**
       
   296 * CTunDriverBinder4::GetName is to retreive the Binder4 Name.
       
   297 * Called from the upperlayer. aName is filled with Binder4 Name. 
       
   298 * @param aName
       
   299 * @return KErrNone if packet is intended for Ipv4 tundriver.
       
   300 * @return KErrNotSupported otherwise. 
       
   301 */
       
   302     {
       
   303     aName.Format(_L("TunDriver4[0x%08x]"), this);
       
   304     __FLOG_2(_L("CTunDriverBinder4 %08x:\tGetName(): %S"), this, &aName);
       
   305     return KErrNone;
       
   306     }
       
   307 
       
   308 TInt CTunDriverBinder4::RecvCallBack(TAny* aCProtocol)
       
   309 /**
       
   310 * CTunDriverBinder4::RecvCallBack is asynchronous callback function to send the packets to IP Layer.
       
   311 * Will be invoked whenever there is a packet in the RMBufPkt Receive Buffer.
       
   312 * @param aCProtocol contains the this object.
       
   313 * @return KErrNone 
       
   314 */
       
   315     {
       
   316     ((CTunDriverBinder4*)aCProtocol)->DoProcess();
       
   317     return KErrNone;
       
   318     }
       
   319 
       
   320 TInt CTunDriverBinder4::SendCallBack(TAny* aCProtocol)
       
   321 /**
       
   322 * CTunDriverBinder4::SendCallBack is asynchronous callback function to send the packets to IP Layer.
       
   323 * Will be invoked whenever there is a packet in the RMBufPkt Send Buffer.
       
   324 * DoSend will process the packets if required and place the packet in the RMBufPkt Receive Queue 
       
   325 * @param aCProtocol contains the this object.
       
   326 * @return KErrNone 
       
   327 */
       
   328     {
       
   329     ((CTunDriverBinder4*)aCProtocol)->DoSend();
       
   330     return KErrNone;
       
   331     }
       
   332 
       
   333 void CTunDriverBinder4::DoSend()
       
   334 /**
       
   335 * CTunDriverBinder4::DoSend will retreive the packet from RMBufPkt Send Buffer.
       
   336 * Process the packets if required and puts the packet back in Receive Buffer.
       
   337 * Will be invoked by CTunDriverBinder4::SendCallback
       
   338 * @param 
       
   339 * @return  
       
   340 */
       
   341     {
       
   342     RMBufPacket send;
       
   343     RMBufPacket recv;
       
   344     while (iSendQ.Remove(send))
       
   345         {
       
   346         TunnelProcessing(send,recv);
       
   347         iRecvQ.Append(recv);
       
   348         iRecvCallBack->CallBack();
       
   349         send.Free();
       
   350         }
       
   351     }
       
   352 
       
   353 void CTunDriverBinder4::DoProcess()
       
   354 /**
       
   355 * CTunDriverBinder4::DoProcess will retreive the packet from RMBufPkt Receive Buffer.
       
   356 * send the packet to IP Layer for processing the packet.
       
   357 * Will be invoked by CTunDriverBinder4::ReceiveCallback
       
   358 * @param 
       
   359 * @return  
       
   360 */
       
   361     {
       
   362     RMBufPacket packet;
       
   363     while (iRecvQ.Remove(packet))
       
   364         {
       
   365         iUpperReceiver->Process(packet);
       
   366         }
       
   367     }
       
   368 
       
   369 void CTunDriverBinder4::TunnelProcessing(RMBufPacket& aPacket, RMBufPacket& aRecv )
       
   370 /**
       
   371 * CTunDriverBinder4::TunnelProcessing will encapsulate with IPv4 Header if the packet is to be tunneled.
       
   372 * IP Number and port number will be configure by TUN Client.
       
   373 * If the IPPacket contains TOS Option set with 192, Packet is encapsulated else packet will be send as is.
       
   374 * Will be invoked by CTunDriverBinder4::DoSend
       
   375 * @param aPacket contains the raw packet.
       
   376 * @param aRecv will contain the payload and the encapsulated IPv4 Header.
       
   377 * @return  
       
   378 */
       
   379     {
       
   380     TInt  ret;
       
   381     TUint origPktLen;
       
   382 
       
   383     TInet6HeaderIP4* lip4 = (TInet6HeaderIP4*) aPacket.First()->Next()->Ptr();
       
   384     TInt outerHdrLen = TInet6HeaderIP4::MinHeaderLength()
       
   385                        + TInet6HeaderUDP::MinHeaderLength();
       
   386     
       
   387     if((lip4->TOS() & KTUNDriverTos) == KTUNDriverTos)
       
   388         {
       
   389         RMBufChain outerHdr;
       
   390         aRecv.Assign(aPacket);
       
   391         RMBufPktInfo *info = aRecv.Unpack();
       
   392         aRecv.SetInfo(info);
       
   393         
       
   394         origPktLen = aRecv.Length();
       
   395         TRAP(ret, outerHdr.AllocL(outerHdrLen));
       
   396         if (ret != KErrNone)
       
   397             {
       
   398             RDebug::Printf("\nVirtual tunnel nif: tunnel processing: Error in Allocating the outer IP header.");
       
   399             aRecv.Free();
       
   400             }
       
   401 
       
   402         aRecv.Prepend(outerHdr);
       
   403         info->iLength += outerHdrLen;
       
   404 
       
   405         TInet6Checksum<TInet6HeaderUDP> outerUdp(aRecv, 20);
       
   406         if (outerUdp.iHdr == NULL)
       
   407             {
       
   408             RDebug::Printf("\nVirtual tunnel nif: tunnel processing: Error in Allocating the outer UDP header.");
       
   409             aRecv.Free();
       
   410             }
       
   411 
       
   412         outerUdp.iHdr->SetSrcPort(GetPort());
       
   413         outerUdp.iHdr->SetDstPort(GetPort());
       
   414         outerUdp.iHdr->SetLength(origPktLen + TInet6HeaderUDP::MinHeaderLength());
       
   415         outerUdp.iHdr->SetChecksum(0);       // Compute checksum
       
   416 
       
   417         TInet6Checksum<TInet6HeaderIP4> outerIP(aRecv);
       
   418         outerIP.iHdr->Init();
       
   419         outerIP.iHdr->SetHeaderLength(TInet6HeaderIP4::MinHeaderLength());
       
   420         outerIP.iHdr->SetTotalLength(origPktLen + outerHdrLen);
       
   421         outerIP.iHdr->SetTOS(1);
       
   422         outerIP.iHdr->SetProtocol(KProtocolInetUdp);
       
   423         outerIP.iHdr->SetSrcAddr(iLocalAddress.Address()) ;
       
   424         outerIP.iHdr->SetDstAddr(iLocalAddress.Address());
       
   425         outerIP.ComputeChecksum();
       
   426         aRecv.Pack();
       
   427         }
       
   428     }
       
   429 #ifdef IPV6SUPPORT
       
   430 CTunDriverBinder6* CTunDriverBinder6::NewL(CTunDriverSubConnectionFlow& aTunDriverSubConnectionFlow)
       
   431 /**
       
   432 * CTunDriverBinder6::NewL
       
   433 * This function is invoked by the flow. This CTunDriverBinder4 is IPv4 specific.
       
   434 * @param CTunDriverSubConnectionFlow
       
   435 * @return CTunDriverSubConnectionFlow.
       
   436 */
       
   437     {
       
   438     CTunDriverBinder6* self = new (ELeave)CTunDriverBinder6(aTunDriverSubConnectionFlow);
       
   439     CleanupStack::PushL(self);
       
   440     self->ConstructL();
       
   441     CleanupStack::Pop(self);
       
   442     return self;
       
   443     }
       
   444 
       
   445 void CTunDriverBinder6::ConstructL()
       
   446 /**
       
   447 * CTunDriverBinder4::ConstructL is the second-phase constructor.
       
   448 * This function is invoked by NewL.
       
   449 * This function initializes the asynchronous callback functions for sending and receiving packets.
       
   450 * @param 
       
   451 * @return.
       
   452 */
       
   453     {
       
   454     TCallBack scb(SendCallBack, this);
       
   455     iSendCallBack = new(ELeave) CAsyncCallBack(scb, EPriorityNormal);
       
   456 
       
   457     TCallBack rcb(RecvCallBack, this);
       
   458     iRecvCallBack = new(ELeave) CAsyncCallBack(rcb, EPriorityNormal);
       
   459     }
       
   460 
       
   461 CTunDriverBinder6::CTunDriverBinder6(CTunDriverSubConnectionFlow& aTunDriverSubConnectionFlow) : CTunDriverBinder(aTunDriverSubConnectionFlow),iTunDriverSubConnectionFlow(aTunDriverSubConnectionFlow)
       
   462 /**
       
   463 * CTunDriverBinder4::CTunDriverBinder4 is the default constructor.
       
   464 * This function is invoked by NewL.
       
   465 * This function initializes localaddress to 0.0.0.0.
       
   466 * @param 
       
   467 * @return.
       
   468 */        
       
   469     {
       
   470     __FLOG_OPEN(KNif, KBinder6);
       
   471     iLocalAddress.SetAddress(KInet6AddrNone);
       
   472     __FLOG_3(_L8("CTunDriverBinder6 %08x:\tCTunDriverBinder6(CTunDriverSubConnectionFlow& %08x): iLocalAddress %08x"), this, &aTunDriverSubConnectionFlow, iLocalAddress.Address());
       
   473     }
       
   474 
       
   475 CTunDriverBinder6::~CTunDriverBinder6()
       
   476 /**
       
   477 * CTunDriverBinder4::CTunDriverBinder4 is the default destructor.
       
   478 * This function frees the RMBufPkt queues and 
       
   479 * deletes the asynchrounous call back pointers initialized at the time of construction.
       
   480 * @param 
       
   481 * @return.
       
   482 */
       
   483     {
       
   484     __FLOG_1(_L8("CTunDriverBinder6 %08x:\t~CTunDriverBinder6()"), this);
       
   485     iRecvQ.Free();
       
   486     iSendQ.Free();
       
   487     delete iRecvCallBack;
       
   488     delete iSendCallBack;
       
   489     }
       
   490 
       
   491 MLowerDataSender* CTunDriverBinder6::Bind(MUpperDataReceiver& aUpperReceiver, MUpperControl& aUpperControl)
       
   492 /**
       
   493 * CTunDriverBinder4::Bind Binds upper CommsFramwork Protocol to this CommsFramwork Protocol.
       
   494 * @param aUpperReceiver A pointer to Upper layer Receive class
       
   495 * @param aUpperControl A pointer to Upper layer control class
       
   496 * @return this.
       
   497 */
       
   498     {
       
   499     __FLOG_3(_L8("CTunDriverBinder6 %08x:\tBind(aUpperReceiver %08x, aUpperControl %08x)"), this, &aUpperReceiver, &aUpperControl);
       
   500     iUpperReceiver = &aUpperReceiver;
       
   501     iUpperControl = &aUpperControl;
       
   502     return this;
       
   503     }
       
   504 
       
   505 void CTunDriverBinder6::Unbind(MUpperDataReceiver& /*aUpperReceiver*/, MUpperControl& /*aUpperControl*/)
       
   506 /**
       
   507 * CTunDriverBinder4::UnBind UnBinds the assocication of CommsFramwork Protocol from this CommsFramwork Protocol.
       
   508 * @param aUpperReceiver A pointer to Upper layer Receive class
       
   509 * @param aUpperControl A pointer to Upper layer control class
       
   510 * @return.
       
   511 */
       
   512     {
       
   513     __FLOG_1(_L8("CTunDriverBinder6 %08x:\tUnbind()"), this);
       
   514     iUpperReceiver = NULL;
       
   515     iUpperControl = NULL;
       
   516     }
       
   517 
       
   518 void CTunDriverBinder6::StartSending()
       
   519 /**
       
   520 * CTunDriverBinder4::StartSending is signaled to the upperlayer that Binder is ready to send packets.
       
   521 * This function will be called only once when the interface is started.
       
   522 * @param 
       
   523 * @return.
       
   524 */
       
   525     {
       
   526     __FLOG_1(_L8("CTunDriverBinder6 %08x:\tBinderReady()"), this);
       
   527     iUpperControl->StartSending();
       
   528     }
       
   529 
       
   530 TBool CTunDriverBinder6::MatchesUpperControl(ESock::MUpperControl* aUpperControl) const
       
   531 /**
       
   532 * CTunDriverBinder4::MatchesUpperControl returns whether this binder is associated with the
       
   533 * MUpperControl object passed as argument.
       
   534 * This function will be called while Unbinding the flow.
       
   535 * @param aUpperControl upper layer to match against
       
   536 * @return ETrue on a match else EFalse.
       
   537 */
       
   538     {
       
   539     return (aUpperControl == iUpperControl);
       
   540     }
       
   541 
       
   542 MLowerDataSender::TSendResult CTunDriverBinder6::Send(RMBufChain& aData)
       
   543 /**
       
   544 * CTunDriverBinder4::Send places the stack packet in SendQueue and breaks the call.
       
   545 * Then asynchrounous callback function is invoked.
       
   546 * @param aData MBuf chain containing data to send
       
   547 * @return ESendAccepted.
       
   548 */
       
   549     {
       
   550     iSendQ.Append(aData);
       
   551     iSendCallBack->CallBack();
       
   552     return ESendAccepted;
       
   553     }
       
   554 
       
   555 TInt CTunDriverBinder6::GetConfig(TBinderConfig& aConfig)
       
   556 /**
       
   557 * CTunDriverBinder4::GetConfig populates the interface IPv4 configuration information.
       
   558 * This function is invoked by the upperlayer
       
   559 * @param aConfig structure.
       
   560 * @return KErrNone if IPv4 binderconfiguration exists.
       
   561 * @return KErrNotSupported otherwise. 
       
   562 */
       
   563     {
       
   564     TBinderConfig6* config = TBinderConfig::Cast<TBinderConfig6>(aConfig);
       
   565 
       
   566     if(config == NULL)
       
   567         {
       
   568         return KErrNotSupported;
       
   569         }
       
   570     const TTunDriverIp6Provision* ip6Provision = Flow()->Ip6Provision();
       
   571     // Setup config
       
   572     iLocalAddress = ip6Provision->LocalAddr();
       
   573     config->iInfo.iFeatures = KIfCanBroadcast | KIfCanMulticast;
       
   574     config->iInfo.iMtu = KMTU;
       
   575     config->iInfo.iRMtu = KMTU;
       
   576     config->iInfo.iSpeedMetric = KSpeedMetric;
       
   577     config->iFamily = KAfInet6;
       
   578 
       
   579     __FLOG_2(_L8("CTunDriverBinder6 %08x:\tGetConfig(): iLocalAddress %08x"), this, iLocalAddress.Address());
       
   580 
       
   581     // primary DNS, just make same as default gateway
       
   582     TInetAddr address = ip6Provision->PrimaryDns();
       
   583     config->iNameSer1 = address;
       
   584     // secondary DNS
       
   585     address = ip6Provision->SecondaryDns();
       
   586     config->iNameSer2 = address;
       
   587     return KErrNone;
       
   588     }
       
   589 
       
   590 TInt CTunDriverBinder6::GetName(TDes& aName)
       
   591 /**
       
   592 * CTunDriverBinder4::GetName is to retreive the Binder4 Name.
       
   593 * Called from the upperlayer. aName is filled with Binder4 Name. 
       
   594 * @param aName
       
   595 * @return KErrNone if packet is intended for Ipv4 tundriver.
       
   596 * @return KErrNotSupported otherwise. 
       
   597 */
       
   598     {
       
   599     aName.Format(_L("TunDriver6[0x%08x]"), this);
       
   600     __FLOG_2(_L("CTunDriverBinder6 %08x:\tGetName(): %S"), this, &aName);
       
   601     return KErrNone;
       
   602     }
       
   603 
       
   604 TInt CTunDriverBinder6::RecvCallBack(TAny* aCProtocol)
       
   605 /**
       
   606 * CTunDriverBinder4::RecvCallBack is asynchronous callback function to send the packets to IP Layer.
       
   607 * Will be invoked whenever there is a packet in the RMBufPkt Receive Buffer.
       
   608 * @param aCProtocol contains the this object.
       
   609 * @return KErrNone 
       
   610 */
       
   611     {
       
   612     ((CTunDriverBinder6*)aCProtocol)->DoProcess();
       
   613     return KErrNone;
       
   614     }
       
   615 
       
   616 TInt CTunDriverBinder6::SendCallBack(TAny* aCProtocol)
       
   617 /**
       
   618 * CTunDriverBinder4::SendCallBack is asynchronous callback function to send the packets to IP Layer.
       
   619 * Will be invoked whenever there is a packet in the RMBufPkt Send Buffer.
       
   620 * DoSend will process the packets if required and place the packet in the RMBufPkt Receive Queue 
       
   621 * @param aCProtocol contains the this object.
       
   622 * @return KErrNone 
       
   623 */
       
   624     {
       
   625     ((CTunDriverBinder6*)aCProtocol)->DoSend();
       
   626     return KErrNone;
       
   627     }
       
   628 
       
   629 void CTunDriverBinder6::DoSend()
       
   630 /**
       
   631 * CTunDriverBinder4::DoSend will retreive the packet from RMBufPkt Send Buffer.
       
   632 * Process the packets if required and puts the packet back in Receive Buffer.
       
   633 * Will be invoked by CTunDriverBinder4::SendCallback
       
   634 * @param 
       
   635 * @return  
       
   636 */
       
   637     {
       
   638     RMBufPacket send;
       
   639     RMBufPacket recv;
       
   640     while (iSendQ.Remove(send))
       
   641         {
       
   642         TunnelProcessing(send,recv);
       
   643         iRecvQ.Append(recv);
       
   644         iRecvCallBack->CallBack();
       
   645         send.Free();
       
   646         }
       
   647     }
       
   648 
       
   649 void CTunDriverBinder6::DoProcess()
       
   650 /**
       
   651 * CTunDriverBinder4::DoProcess will retreive the packet from RMBufPkt Receive Buffer.
       
   652 * send the packet to IP Layer for processing the packet.
       
   653 * Will be invoked by CTunDriverBinder4::ReceiveCallback
       
   654 * @param 
       
   655 * @return  
       
   656 */
       
   657     {
       
   658     RMBufPacket packet;
       
   659     while (iRecvQ.Remove(packet))
       
   660         {
       
   661         iUpperReceiver->Process(packet);
       
   662         }
       
   663     }
       
   664 
       
   665 void CTunDriverBinder6::TunnelProcessing(RMBufPacket& aPacket, RMBufPacket& aRecv )
       
   666 /**
       
   667 * CTunDriverBinder4::TunnelProcessing will encapsulate with IPv4 Header if the packet is to be tunneled.
       
   668 * IP Number and port number will be configure by TUN Client.
       
   669 * If the IPPacket contains TOS Option set with 192, Packet is encapsulated else packet will be send as is.
       
   670 * Will be invoked by CTunDriverBinder4::DoSend
       
   671 * @param aPacket contains the raw packet.
       
   672 * @param aRecv will contain the payload and the encapsulated IPv4 Header.
       
   673 * @return  
       
   674 */
       
   675     {
       
   676     TInt  ret;
       
   677     TUint origPktLen;
       
   678 
       
   679     TInet6HeaderIP* lip6 = (TInet6HeaderIP*) aPacket.First()->Next()->Ptr();
       
   680     TInt outerHdrLen = TInet6HeaderIP4::MinHeaderLength()
       
   681                        + TInet6HeaderUDP::MinHeaderLength();
       
   682     
       
   683     if((lip6->HopLimit() & KTUNDriverTos) == KTUNDriverTos)        
       
   684         {
       
   685         RMBufChain outerHdr;
       
   686         aRecv.Assign(aPacket);
       
   687         RMBufPktInfo *info = aRecv.Unpack();
       
   688         aRecv.SetInfo(info);
       
   689         
       
   690         origPktLen = aRecv.Length();
       
   691         TRAP(ret, outerHdr.AllocL(outerHdrLen));
       
   692         if (ret != KErrNone)
       
   693             {
       
   694             RDebug::Printf("\nVirtual tunnel nif: tunnel processing: Error in Allocating the outer IP header.");
       
   695             aRecv.Free();
       
   696             }
       
   697 
       
   698         TInet6HeaderIP *hdrBuf = (TInet6HeaderIP*) outerHdr.First()->Buffer();
       
   699         aRecv.Prepend(outerHdr);
       
   700         info->iLength += outerHdrLen;
       
   701 
       
   702         TInet6Checksum<TInet6HeaderUDP> outerUdp(aRecv, 20);
       
   703         if (outerUdp.iHdr == NULL)
       
   704             {
       
   705             RDebug::Printf("\nVirtual tunnel nif: tunnel processing: Error in Allocating the outer UDP header.");
       
   706             aRecv.Free();
       
   707             }
       
   708 
       
   709         outerUdp.iHdr->SetSrcPort(GetPort());
       
   710         outerUdp.iHdr->SetDstPort(GetPort());
       
   711         outerUdp.iHdr->SetLength(origPktLen + TInet6HeaderUDP::MinHeaderLength());
       
   712         outerUdp.iHdr->SetChecksum(0);
       
   713 
       
   714         TInet6Checksum<TInet6HeaderIP> outerIP(aRecv);
       
   715         outerIP.iHdr->Init();
       
   716         outerIP.iHdr->SetHopLimit(1);
       
   717         outerIP.iHdr->SetNextHeader(KProtocolInetUdp);
       
   718         outerIP.iHdr->SetSrcAddr(iLocalAddress.Ip6Address());
       
   719         outerIP.iHdr->SetDstAddr(iLocalAddress.Ip6Address());
       
   720         aRecv.Pack();
       
   721         }
       
   722     }
       
   723     
       
   724 CTunDriverSubConnectionFlow* CTunDriverBinder6::Flow()
       
   725     {
       
   726     return &iTunDriverSubConnectionFlow;
       
   727     }
       
   728 
       
   729 #endif