networkprotocols/tcpipv4v6prt/src/rawip_sap.cpp
changeset 0 af10295192d8
--- /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);
+	}
+
+