realtimenetprots/sipfw/SIP/ConnectionMgr/src/CIcmpV4Receiver.cpp
changeset 0 307788aac0a8
--- /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 <ip4_hdr.h>
+#include <icmp6_hdr.h> // This is identical to ICMPv4 header
+#include <udp_hdr.h>
+#include <in_sock.h>
+#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();
+		}
+	}