diff -r 000000000000 -r af10295192d8 networkprotocols/tcpipv4v6prt/src/rawip_sap.cpp --- /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 +#include +#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); + } + +