diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/SIP/ConnectionMgr/src/CIcmpV4Receiver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/realtimenetprots/sipfw/SIP/ConnectionMgr/src/CIcmpV4Receiver.cpp Tue Feb 02 01:03:15 2010 +0200 @@ -0,0 +1,181 @@ +// Copyright (c) 2002-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: +// Name : CIcmpV4Receiver.cpp +// Part of : ConnectionMgr +// Version : SIP/4.0 +// Destination Unreachable Message: +// 0 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// | Type | Code | Checksum | +// | unused | +// | Internet Header + 64 bits of Original Data Datagram | +// Internet header: +// 0 1 2 3 +// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +// |Version| IHL |Type of Service| Total Length | +// | Identification |Flags| Fragment Offset | +// | Time to Live | Protocol | Header Checksum | +// | Source Address | +// | Destination Address | +// | Options | Padding | +// User datagram: +// 0 7 8 15 16 23 24 31 +// | Source | Destination | +// | Port | Port | +// | Length | Checksum | +// | data octets ... +// In the code the data is located in bytes. +// + + + + +#include +#include // This is identical to ICMPv4 header +#include +#include +#include "CIcmpV4Receiver.h" +#include "MIcmpReceiver.h" +#include "CommonConsts.h" +#include "SipLogs.h" + + +// ----------------------------------------------------------------------------- +// CIcmpV4Receiver::NewL +// ----------------------------------------------------------------------------- +// +CIcmpV4Receiver* CIcmpV4Receiver::NewL(MIcmpErrorObserver& aObserver, + RSocketServ& aServer) + { + CIcmpV4Receiver* self = new (ELeave) CIcmpV4Receiver(); + CleanupStack::PushL(self); + self->ConstructL(aObserver, aServer); + CleanupStack::Pop(); + return self; + } + +// ----------------------------------------------------------------------------- +// CIcmpV4Receiver::CIcmpV4Receiver +// ----------------------------------------------------------------------------- +// +CIcmpV4Receiver::CIcmpV4Receiver() : CActive( CActive::EPriorityStandard ) + { + } + +// ----------------------------------------------------------------------------- +// CIcmpV4Receiver::ConstructL +// ----------------------------------------------------------------------------- +// +void CIcmpV4Receiver::ConstructL(MIcmpErrorObserver& aObserver, + RSocketServ& aServer) + { + CActiveScheduler::Add(this); + iObserver = &aObserver; + iServer = &aServer; + + // Start + User::LeaveIfError(iSocket.Open(*iServer, KAfInet, KSockDatagram, + KProtocolInetIcmp)); + Receive(); + } + +// ----------------------------------------------------------------------------- +// CIcmpV4Receiver::~CIcmpV4Receiver +// ----------------------------------------------------------------------------- +// +CIcmpV4Receiver::~CIcmpV4Receiver() + { + Cancel(); + iSocket.Close(); + } + +// ----------------------------------------------------------------------------- +// CIcmpV4Receiver::RunL +// ----------------------------------------------------------------------------- +// +void CIcmpV4Receiver::RunL() + { + if (iStatus == KErrNone) + { + CheckError(); + Receive(); + } + } + +// Disabled PC-Lint warning for "Suspicious pointer-to-pointer conversion +// (area too small))". It was caused by TUin8* to TInet6xxx typecasts and could +// not be avoided otherwise. +/*lint -e826 */ + +// ----------------------------------------------------------------------------- +// CIcmpV4Receiver::CheckError +// ----------------------------------------------------------------------------- +// +void CIcmpV4Receiver::CheckError() + { + const TUint KDestinationUnreachable = 3; + + // Pointer to ICMP header + TInet6HeaderICMP* icmpPtr = ( TInet6HeaderICMP* ) iData.Ptr(); + + // Pointer to IPv4 header + TInet6HeaderIP4* ipv4Ptr = ( TInet6HeaderIP4* )( iData.Ptr() + 8 ); + + // Error message type + TUint32 error = icmpPtr->Type(); + if ( error == KDestinationUnreachable ) + { + // Check that protocol is UDP + TUint32 protocol = ipv4Ptr->Protocol(); + if ( protocol == KProtocolInetUdp ) + { + // Pointer to UDP data + TInet6HeaderUDP* udpPtr = ( TInet6HeaderUDP* )( ipv4Ptr->EndPtr() ); + + // Get the destination port number + iAddress.SetPort( udpPtr->DstPort() ); + + // Set the destination address + iAddress.SetAddress( ipv4Ptr->DstAddr() ); + + __SIP_INT_LOG1( "ICMP error", error ) + __SIP_ADDR_LOG( "ICMP error address", iAddress ) + + // Error message to observer + iObserver->IcmpError( iAddress ); + } + } + } + +// ----------------------------------------------------------------------------- +// CIcmpV4Receiver::DoCancel +// ----------------------------------------------------------------------------- +// +void CIcmpV4Receiver::DoCancel() + { + iSocket.CancelRecv(); + } + +// ----------------------------------------------------------------------------- +// CIcmpV4Receiver::Receive +// ----------------------------------------------------------------------------- +// +void CIcmpV4Receiver::Receive() + { + if(!IsActive()) + { + iSocket.Recv( iData, 0, iStatus ); + SetActive(); + } + }