networkprotocols/iphook/inhook6example/src/exadump.cpp
changeset 0 af10295192d8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/networkprotocols/iphook/inhook6example/src/exadump.cpp	Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,427 @@
+// Copyright (c) 2004-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:
+// exadump.cpp - packet dump plugin example module
+// The packet dump implementation.
+//
+
+
+
+/**
+ @file exadump.cpp
+*/
+
+#include <f32file.h>
+
+#include "protocol_module.h"
+#include "exadump.h"
+
+
+//
+// The "glue" between the protocol implementation and the generic protocol family module.
+// (This section should not have any doxygen comments, because the ProtocolModule can be
+// implemented multiple times in different examples -- the comments would be lost).
+//
+TInt ProtocolModule::NumProtocols()
+	{
+	return 1;
+	}
+
+void ProtocolModule::Describe(TServerProtocolDesc &aDesc, const TInt /*aIndex*/)
+	{
+	CProtocolExadump::Describe(aDesc);
+	}
+
+CProtocolBase *ProtocolModule::NewProtocolL(TUint aSockType, TUint aProtocol)
+	{
+	(void)aSockType;
+	(void)aProtocol;
+	return new (ELeave) CProtocolExadump;
+	}
+
+//
+//
+// The real implementation
+//
+//
+
+void CProtocolExadump::Describe(TServerProtocolDesc &aDesc)
+	/**
+	* Fills in the TServerProtocolDesc.
+	*
+	* @retval aDesc	The description of the protocol.
+	*
+	* A class specific static function can be used, as the information is
+	* always the same. Some other impelmentations might have non-static
+	* version, if some fields of the TServerProtocolDesc are dynamic and
+	* depend on the object. The following are initialized:
+	*
+	* - iName		The name of the protocol ("exadump").
+	* - iAddrFamily	The address family of the protocol.
+	* - iProtocol	The protocol number.
+	*				The combination family + protocol number should
+	*				be unique.
+	* - iVersion	Mostly unused?
+	* - iByteOrder	Mostly unused?
+	* - iServiceInfo	Connectionless datagram sockets (only if SAP's)
+	* - iNamingServices	Support RHostResolver and like?
+	* - iSecurity	Mostly unused?
+	* - iMessageSize	??
+	* - iServiceTypeInfo	??
+	* - iNumSockets	Max number of SAP's.)
+	*
+	*/
+	{
+/** @code */
+	aDesc.iName =			_S("exadump");
+	aDesc.iAddrFamily =		0x101f6cfe; // Use UID as family value.
+	aDesc.iSockType =		KSockDatagram;
+	aDesc.iProtocol =		1000;
+	aDesc.iVersion =		TVersion(1, 0, 0);
+	aDesc.iByteOrder =		EBigEndian;
+	aDesc.iServiceInfo =	0;
+	aDesc.iNamingServices = 0;
+	aDesc.iSecurity =		0;
+	aDesc.iMessageSize =	0;
+	aDesc.iServiceTypeInfo = 0;
+	aDesc.iNumSockets =		0;
+/** @endcode */
+	}
+
+
+void CProtocolExadump::Identify(TServerProtocolDesc *aDesc) const
+	/**
+	* Returns the protocol description.
+	*
+	* The socket server and other protocols use this function to
+	* retrieve the basic information about the protocol.
+	*
+	* @retval	aDesc	The protocol description.
+	*/
+	{
+/** @code */
+	Describe(*aDesc);
+/** @endcode */
+	}
+
+
+CProtocolExadump::CProtocolExadump()
+	/** Constructor. */
+	{
+/** @code */
+	// Base time as expected by Unix systems. Note that
+	// day and month numbering starts from ZERO!
+	iBase.Set(_L("19700000:000000.000000"));
+/** @endcode */
+	}
+
+CProtocolExadump::~CProtocolExadump()
+	/**
+	* Destructor.
+	*
+	* Release allocated resources.
+	*/
+	{
+/** @code */
+	if (iOpen > 0)
+		{
+		iDumpFile.Close();
+		iFS.Close();
+		}
+	delete iBuffer;
+/** @endcode */
+	}
+
+//
+
+// CProtocolExadump::NetworkAttachedL
+// ********************************
+void CProtocolExadump::NetworkAttachedL()
+	/**
+	* When network becomes available, do the hooking.
+	*
+	*/
+	{
+/** @code */
+	// Install a hook to dump all accepted packets just
+	// before they are passed to the upper layer
+	// protocol. The calling order of this hook, relative
+	// to other hooks can be controlled through the tcpip.ini
+	// option in the [hook] section
+	//
+	// hook_inany= *,exadump
+	//
+	// (call after all others) or
+	//
+	// hook_inany= exadump
+	//
+	// (call before all others).
+	//
+	NetworkService()->BindL(this, MIp6Hook::BindHookAll());
+
+	// Install a hook to dump outbound packets. The calling
+	// order of this hook, relative to other hooks can be
+	// controlled through the tcpip.ini option in the [hook] section:
+	//
+	// hook_flow= *,exadump
+	//
+	// or even
+	//
+	// hook_flow= exadump,*,exadump
+	//
+	// which would give two dumps out of each packet. One before any other
+	// flow hooks, and another one after all of them.
+	//
+	NetworkService()->BindL(this, MIp6Hook::BindFlowHook());
+/** @endcode */
+	}
+
+
+//
+// MIp6Hook specifications
+
+MFlowHook *CProtocolExadump::OpenL(TPacketHead & /*aHead*/, CFlowContext * /*aFlow*/)
+	/**
+	* Decides whether to attach hook on flow or not.
+	*
+	* This example attaches every flow, but it does not require
+	* a separate context for each flow. Thus, the MFlowHook has been
+	* mixed into the CProtocolExadump class and it uses itself by
+	* simply returning this pointer.
+	*
+	* @return	'this' as MFlowHook (always non-NULL)
+	*/
+	{
+/** @code */
+	Open();			// Increment reference count!
+	return this;
+/** @endcode */
+	}
+
+TInt CProtocolExadump::ApplyL(RMBufHookPacket& aPacket, RMBufRecvInfo & aInfo)
+	/**
+	* Dumps the packet.
+	*
+	* This is called for each incoming packet. The return is always
+	* KIp6Hook_PASS, because this does not try to modify or otherwise
+	* change the normal packet processing.
+	*
+	* @param aPacket	The packet data
+	* @param aInfo		The packet information
+	*
+	* @return KIp6Hook_PASS
+	*/
+	{
+/** @code */
+	DoPacket(aPacket, aInfo);
+	return KIp6Hook_PASS;
+/** @endcode */
+	}
+
+
+//
+// MFlowHook methods, because MFlowHook is mixed in
+
+void CProtocolExadump::Open()
+	/**
+	* Routes MFlowHook::Open to CProtocolPosthook::Open
+	*/
+	{
+/** @code */
+	CProtocolPosthook::Open();
+/** @endcode */
+	}
+
+void CProtocolExadump::Close()
+	/**
+	* Routes MFlowHook::Close to CProtocolPosthook::Close
+	*/
+	{
+/** @code */
+	CProtocolPosthook::Close();
+/** @endcode */
+	}
+
+TInt CProtocolExadump::ReadyL(TPacketHead & /*aHead*/)
+	/**
+	* Tests if flow is ready.
+	*
+	* In this example there is nothing that would make the flow
+	* blocked, and always return KErrNone.
+	*
+	* @return KErrNone.
+	*/
+	{
+	return KErrNone;
+	}
+
+TInt CProtocolExadump::ApplyL(RMBufSendPacket &aPacket, RMBufSendInfo &aInfo)
+	/**
+	* Dumps the packet.
+	*
+	* This is called for each outgoing packet. The return is always
+	* KErrNone, because this does not try to modify or otherwise
+	* change the normal packet processing.
+	*
+	* @param aPacket	The packet data
+	* @param aInfo		The packet information
+	*
+	* @return KErrNone
+	*/
+	{
+/** @code */
+	DoPacket(aPacket, aInfo);
+	return KErrNone;
+/** @endcode */
+	}
+
+//
+// Own private functions
+
+/**
+* @name Some minimal definitions lifted from the PCAP headers.
+*
+* {@
+*/
+#include <sys/time.h>
+#define PCAP_VERSION_MAJOR 2
+#define PCAP_VERSION_MINOR 4
+#define TCPDUMP_MAGIC 0xa1b2c3d4
+#define DLT_RAW		12	/* raw IP */
+
+struct pcap_file_header
+	/** PCAP dump file header */
+	{
+	TUint32 magic;
+	TUint16 version_major;
+	TUint16 version_minor;
+	TUint32 thiszone;	/* gmt to local correction */
+	TUint32 sigfigs;	/* accuracy of timestamps */
+	TUint32 snaplen;	/* max length saved portion of each pkt */
+	TUint32 linktype;	/* data link type (LINKTYPE_*) */
+	};
+
+struct pcap_pkthdr
+	/** PCAP dump file packet header */
+	{
+	struct timeval ts;	/* time stamp */
+	TUint32 caplen;		/* length of portion present */
+	TUint32 len;		/* length this packet (off wire) */
+	};
+/** @} */
+
+void CProtocolExadump::DoPacket(const RMBufPacketBase &aPacket, const RMBufPktInfo &aInfo)
+	/**
+	* Dump the packet.
+	*
+	* This is called for both incoming and outgoing packets, from the
+	* respective ApplyL methods.
+	*
+	* @param aPacket	The packet data
+	* @param aInfo		The packet inforrmation
+	*/
+	{
+/** @code */
+	// Open the dump file, if not already opened (or attempted).
+	if (iOpen == 0)
+		DoOpen(1500);
+	if (iOpen < 0)
+		return;	// cannot open output file.
+
+	//
+	// Build PCAP frame into iBuffer (pcap_pkthdr + snapped portion of the packet)
+	//
+	TPtr8 buf = iBuffer->Des();
+	struct pcap_pkthdr *const hdr = (struct pcap_pkthdr *)buf.Ptr();
+	TPtr8 ptr((TUint8 *)buf.Ptr() + sizeof(*hdr), buf.MaxLength() - sizeof(*hdr));
+
+	const TInt snap = aInfo.iLength > ptr.MaxLength() ? ptr.MaxLength() : aInfo.iLength;
+	ptr.SetLength(snap);
+	aPacket.CopyOut(ptr);
+
+	hdr->caplen = snap;
+	hdr->len = aInfo.iLength;
+
+	TTime stamp;
+	stamp.UniversalTime();
+	const TTimeIntervalMicroSeconds elapsed = stamp.MicroSecondsFrom(iBase);
+#ifdef I64INT
+	hdr->ts.tv_usec = I64INT(elapsed.Int64() % 1000000);
+	hdr->ts.tv_sec = I64INT(elapsed.Int64() / 1000000);
+#else
+	hdr->ts.tv_usec = (elapsed.Int64() % 1000000).GetTInt();
+	hdr->ts.tv_sec = (elapsed.Int64() / 1000000).GetTInt();
+#endif
+	//
+	// Write frame out.
+	//
+	iDumpFile.Write(buf, snap+sizeof(*hdr));
+/** @endcode */
+	}
+
+
+void CProtocolExadump::DoOpen(TInt aSnaplen)
+	/**
+	* Try opening the dump file.
+	*
+	* Opens the dump file and writes the file header to it.
+	*
+	* @param aSnaplen The snap length
+	*/
+	{
+/** @code */
+	// Just close the previous, if called with open file.
+	if (iOpen > 0)
+		{
+		iDumpFile.Close();
+		iFS.Close();
+		}
+
+	// Allocate a working buffer for the packet frames
+	// (include packet header and snaplen).
+	delete iBuffer;
+	iBuffer = HBufC8::NewMax(aSnaplen + sizeof(struct pcap_file_header));
+	if (iBuffer == NULL)
+		{
+		iOpen = KErrNoMemory;
+		return;
+		}
+
+	_LIT(KDumpFile, "exedump.dat");	// the name of the dump file.
+
+	iOpen = iFS.Connect();
+	if (iOpen != KErrNone)
+		return;
+	iOpen = iDumpFile.Replace(iFS, KDumpFile, EFileWrite);
+	if (iOpen != KErrNone)
+		{
+		iFS.Close();
+		return;
+		}
+
+	// Write the header
+	TPckgBuf<struct pcap_file_header> hdr;
+
+	hdr().magic = TCPDUMP_MAGIC;
+	hdr().version_major = PCAP_VERSION_MAJOR;
+	hdr().version_minor = PCAP_VERSION_MINOR;
+
+	hdr().thiszone = 0;
+	hdr().snaplen = aSnaplen;
+	hdr().sigfigs = 0;
+	hdr().linktype = DLT_RAW;
+	iDumpFile.Write(hdr, hdr.Length());
+	iOpen = 1;
+	return;
+/** @endcode */
+	}