networkprotocols/tcpipv4v6prt/src/icmp_sap.cpp
changeset 0 af10295192d8
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 2004-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 // icmp_sap.cpp - ICMP service access point
       
    15 //
       
    16 
       
    17 #include "icmp6.h"
       
    18 #include <icmp6_hdr.h>
       
    19 #include <in_pkt.h>
       
    20 #include <in_chk.h>
       
    21 #include "in_net.h"
       
    22 //
       
    23 
       
    24 class CProviderICMP6 : public CProviderInet6Network
       
    25 	{
       
    26 public:
       
    27 	CProviderICMP6(CProtocolInet6Base* aProtocol, TInt aProtocolId);
       
    28 	virtual TInt DoWrite(RMBufSendPacket &aPacket, RMBufSendInfo &aInfo, TUint aOptions, TUint aOffset);
       
    29 	virtual TInt SetLocalName(TSockAddr &aAddr);
       
    30 	virtual TInt SecurityCheck(MProvdSecurityChecker *aChecker);
       
    31 	};
       
    32 
       
    33 CServProviderBase *ICMP6::NewSAPL(TUint aSockType, CProtocolInet6Base *aProtocol, TInt aId)
       
    34 	{
       
    35 	LOG(Log::Printf(_L("NewSAPL\t%S SockType=%d"), &aProtocol->ProtocolName(), aSockType));
       
    36 	if (aSockType != KSockDatagram)
       
    37 		User::Leave(KErrNotSupported);
       
    38 	CProviderICMP6 *provider = new (ELeave) CProviderICMP6(aProtocol, aId);
       
    39 	CleanupStack::PushL(provider);
       
    40 	provider->InitL();
       
    41 	CleanupStack::Pop();
       
    42 	LOG(Log::Printf(_L("NewSAPL\t%S SAP[%u] OK"), &aProtocol->ProtocolName(), (TInt)provider));
       
    43 	return provider;
       
    44 	}
       
    45 
       
    46 //
       
    47 
       
    48 CProviderICMP6::CProviderICMP6(CProtocolInet6Base* aProtocol, TInt aProtocolId) :
       
    49 	CProviderInet6Network(aProtocol)
       
    50 	{
       
    51 	__DECLARE_NAME(_S("CProviderICMP6"));
       
    52 
       
    53 	iProtocolId = aProtocolId;	// either ICMPv4 or ICMPv6 id
       
    54 	}
       
    55 
       
    56 TInt CProviderICMP6::DoWrite(RMBufSendPacket &aPacket, RMBufSendInfo &aInfo, TUint /*aOptions*/, TUint aOffset)
       
    57 	{
       
    58 	TInet6Checksum<TInet6HeaderICMP> icmp(aPacket, aOffset);
       
    59 	if (icmp.iHdr == NULL)
       
    60 		return KErrInet6ShortPacket;
       
    61 
       
    62 	iFlow.SetIcmpType(icmp.iHdr->Type(), icmp.iHdr->Code());
       
    63 	iFlow.SetNotify(this);
       
    64 	if (aInfo.iSrcAddr.Family())
       
    65 		iFlow.SetLocalAddr(aInfo.iSrcAddr);
       
    66 	if (aInfo.iDstAddr.Family())
       
    67 		iFlow.SetRemoteAddr(aInfo.iDstAddr);
       
    68 
       
    69 	const TInt status = aInfo.iFlow.Open(iFlow, &aInfo);
       
    70 	if (status == KErrNone)
       
    71 		{
       
    72 		// Compute the checksum here. This means that currently
       
    73 		// the application cannot compute the checksum into
       
    74 		// ICMP header. This may be a drawback for some situations
       
    75 		// and perhaps some flag is introduced later -- msa
       
    76 		//
       
    77 		// IPv4 ICMP checksum does not use "pseudoheader" => pass NULL for info when IPv4!
       
    78 		icmp.ComputeChecksum(aPacket, iProtocolId == STATIC_CAST(TInt, KProtocolInetIcmp) ? NULL : &aInfo, aOffset);
       
    79 		}
       
    80 	return status;
       
    81 	}
       
    82 
       
    83 //
       
    84 // Need to override the network SetLocalName because by default
       
    85 // the network deliver filters by the port number (compared to
       
    86 // the protocol number).
       
    87 //
       
    88 TInt CProviderICMP6::SetLocalName(TSockAddr &aAddr)
       
    89 	{
       
    90 	// To prevent accidental non-zero values of port messing things up,
       
    91 	// make sure the local port field is zero before doing the bind.
       
    92 	//
       
    93 	aAddr.SetPort(0);
       
    94 	return CProviderInet6Network::SetLocalName(aAddr);
       
    95 	}
       
    96 	
       
    97 // For now, require network control from ICMP sockets, because they
       
    98 // also see all incoming ICMP's, including any bounced packets from
       
    99 // other applications.
       
   100 TInt CProviderICMP6::SecurityCheck(MProvdSecurityChecker *aChecker)
       
   101 	{
       
   102 	const TInt res = CProviderInet6Network::SecurityCheck(aChecker);
       
   103 	if (res == KErrNone)
       
   104 		return CheckPolicy(KPolicyNetworkControl, "TCPIP ICMP SAP");
       
   105 	return res;
       
   106 	}
       
   107 
       
   108