--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/networkprotocols/tcpipv4v6prt/src/rawip_sap.cpp Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,159 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// rawip_sap.cpp - Raw IP socket
+//
+
+#include "rawip.h"
+#include <in_pkt.h>
+#include <in_chk.h>
+#include "in_net.h"
+//
+
+class CProtocolRawBinder;
+
+class CProviderRawIp : public CProviderInet6Network
+ {
+public:
+ CProviderRawIp(CProtocolInet6Base* aProtocol);
+ ~CProviderRawIp();
+ virtual TInt SetLocalName(TSockAddr &aAddr);
+ virtual TInt DoWrite(RMBufSendPacket &aPacket, RMBufSendInfo &aInfo, TUint aOptions, TUint aOffset);
+ virtual TInt SecurityCheck(MProvdSecurityChecker *aChecker);
+ virtual void InitL();
+private:
+ CProtocolRawBinder *iBinder;
+ };
+
+
+class CProtocolRawBinder : public CProtocolBase
+ {
+public:
+ CProtocolRawBinder(CProviderRawIp &aProvider) : iProvider(aProvider) {}
+ virtual void Identify(TServerProtocolDesc *) const;
+ virtual void Process(RMBufChain&, CProtocolBase* aSourceProtocol=NULL);
+private:
+ CProviderRawIp &iProvider;
+ };
+
+
+CServProviderBase *RAWIP::NewSAPL(TUint aSockType, CProtocolInet6Base *aProtocol)
+ {
+ LOG(Log::Printf(_L("NewSAPL\t%S SockType=%d"), &aProtocol->ProtocolName(), aSockType));
+ if (aSockType != KSockRaw)
+ User::Leave(KErrNotSupported);
+ CProviderRawIp *provider = new (ELeave) CProviderRawIp(aProtocol);
+ CleanupStack::PushL(provider);
+ provider->InitL();
+ CleanupStack::Pop();
+ LOG(Log::Printf(_L("NewSAPL\t%S SAP[%u] OK"), &aProtocol->ProtocolName(), (TInt)provider));
+ return provider;
+ }
+
+//
+
+CProviderRawIp::CProviderRawIp(CProtocolInet6Base* aProtocol) :
+ CProviderInet6Network(aProtocol)
+ {
+ }
+
+void CProviderRawIp::InitL()
+ {
+ iBinder = new (ELeave) CProtocolRawBinder(*this);
+ CProviderInet6Network::InitL();
+ }
+
+CProviderRawIp::~CProviderRawIp()
+ {
+ iProtocol->NetworkService()->Protocol()->Unbind(iBinder);
+ delete iBinder;
+ }
+
+// SetLocalName (Bind() in application) with non-zero port activates
+// the incoming path for packets of the specific protocol.
+TInt CProviderRawIp::SetLocalName(TSockAddr &aAddr)
+ {
+ const TInt id = aAddr.Port();
+ // Only bind as real upper layer protocol, limit the value...
+ if (id < 0 || id > 255)
+ return KErrNotSupported;
+ if (iProtocol == NULL || iProtocol->NetworkService() == NULL)
+ return KErrNotReady; // Should never really happen...
+ iProtocol->NetworkService()->Protocol()->Unbind(iBinder);
+ if (id > 0)
+ {
+ // Only non-zero protocol is bound.
+ TRAPD(err, iProtocol->NetworkService()->BindL(iBinder, id));
+ if (err != KErrNone)
+ return err;
+ }
+ // iProtocolId is used to fill in the protocol number
+ // for outgoing packets, if non-zero (if zero, then
+ // the port of the destination address is used as protocol).
+ iProtocolId = id;
+ // Do the default SetLocalName without the port!
+ aAddr.SetPort(0);
+ return CProviderInet6Network::SetLocalName(aAddr);
+ }
+
+
+TInt CProviderRawIp::DoWrite(RMBufSendPacket & /*aPacket*/, RMBufSendInfo &aInfo, TUint /*aOptions*/, TUint /*aOffset*/)
+ {
+ iFlow.SetIcmpType(0, 0);
+ iFlow.SetNotify(this);
+ if (aInfo.iSrcAddr.Family())
+ iFlow.SetLocalAddr(aInfo.iSrcAddr);
+ if (aInfo.iDstAddr.Family())
+ iFlow.SetRemoteAddr(aInfo.iDstAddr);
+ return aInfo.iFlow.Open(iFlow, &aInfo);
+ }
+
+// Require network control for raw ip sockets
+TInt CProviderRawIp::SecurityCheck(MProvdSecurityChecker *aChecker)
+ {
+ const TInt res = CProviderInet6Network::SecurityCheck(aChecker);
+ if (res == KErrNone)
+ return CheckPolicy(KPolicyNetworkControl, "TCPIP RAWIP SAP");
+ return res;
+ }
+
+void CProtocolRawBinder::Process(RMBufChain &aPacket,CProtocolBase * /*aSourceProtocol*/)
+ {
+ for (;;) // LOOP ONLY FOR EASY BREAK EXITS!
+ {
+ RMBufRecvInfo *const info = (RMBufRecvInfo *)RMBufPacketBase::PeekInfoInChain(aPacket);
+ if (info == NULL)
+ break;
+ if (info->iIcmp)
+ {
+ // For now, ignore ICMP error reports.
+ // Could do the save icmp error to support the "Last ICMP" error feature,
+ // in socket. That would require translating ICMP error codes into Symbian
+ // error codes (which is done in udp.cpp for example -- should have some
+ // shared code for this ICMP handling).
+ break;
+ }
+ iProvider.Process(aPacket);
+ // ALWAYS TERMINATE THE LOOP
+ break;
+ }
+ aPacket.Free();
+ }
+
+void CProtocolRawBinder::Identify(TServerProtocolDesc *aInfo) const
+ {
+ // If asked, the binder returns the same info as the "rawip" protocol.
+ RAWIP::Identify(*aInfo);
+ }
+
+