networkingtestandutils/ipprobe/src/prt.cpp
branchRCL_3
changeset 22 8d540f55e491
parent 21 abbed5a4b42a
equal deleted inserted replaced
21:abbed5a4b42a 22:8d540f55e491
     1 /*
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 * Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). 
     2 // All rights reserved.
     3 * All rights reserved.
     3 // This component and the accompanying materials are made available
     4 * This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 * under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 * which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 *
     8 // Initial Contributors:
     9 * Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 * Nokia Corporation - initial contribution.
    10 //
    11 *
    11 // Contributors:
    12 * Contributors:
    12 //
    13 *
    13 // Description:
    14 * Description: Packet probe hook
    14 // prt.cpp - Packet Probe Hook
    15 *
    15 //
    16 */
       
    17 
    16 
    18 #include <e32std.h>
    17 #include <e32std.h>
    19 #include <e32base.h>
    18 #include <e32base.h>
    20 #include <f32file.h>
       
    21 #include <e32svr.h>
       
    22 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
    19 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
    23 #include <es_prot_internal.h>
    20 #include <es_prot_internal.h>
    24 #endif
    21 #endif
    25 
       
    26 
    22 
    27 #include "family.h"
    23 #include "family.h"
    28 #include "prt.h"
    24 #include "prt.h"
    29 #include "sap.h"
    25 #include "sap.h"
    30 #include "inet6log.h"
    26 #include "inet6log.h"
    31 _LIT(KTcpDumpFolder, "tcpdump\\");
       
    32 _LIT(KProbeDumpFile, "probe.cap");
       
    33 _LIT(KLogFolder,     "c:\\logs\\");
       
    34 
    27 
    35 
    28 
    36 CProtocolProbe::CProtocolProbe(TUint aId) : 
    29 CProtocolProbe::CProtocolProbe(TUint aId) : iId(aId)
    37 iId(aId), 
       
    38 iDumpCb(CActive::EPriorityStandard),
       
    39 iFileServerOpen(EFalse),
       
    40 iFileOpen(EFalse),
       
    41 iBufCreated(EFalse)
       
    42 	{
    30 	{
    43 	LOG(Log::Printf(_L("Probe::CProtocolProbe()\r\n"));)
    31 	LOG(Log::Printf(_L("Probe::CProtocolProbe()\r\n"));)
    44 	iTimeOrigin.UniversalTime();
       
    45 
       
    46 	TCallBack cbFunc(DumpCb, this);
       
    47 	iDumpCb.Set(cbFunc);
       
    48 	}
    32 	}
    49 
    33 
    50 void CProtocolProbe::InitL(TDesC& aTag)
    34 void CProtocolProbe::InitL(TDesC& aTag)
    51 	{
    35 	{
    52 	LOG(Log::Printf(_L("Probe::InitL()\r\n"));)
    36 	LOG(Log::Printf(_L("Probe::InitL()\r\n"));)
    53 	CProtocolBase::InitL(aTag);
    37 	CProtocolBase::InitL(aTag);
    54 	}
    38 	}
    55 
    39 
       
    40 
    56 void CProtocolProbe::StartL()
    41 void CProtocolProbe::StartL()
    57 	{
    42 	{
    58 	//	__ASSERT_DEBUG(iProtocol != NULL, User::Leave(KErrGeneral));
    43 	//	__ASSERT_DEBUG(iProtocol != NULL, User::Leave(KErrGeneral));
    59 	}
    44 	}
    60 
    45 
    61 CProtocolProbe::~CProtocolProbe()
    46 CProtocolProbe::~CProtocolProbe()
    62 	{
    47 	{
    63 	LOG(Log::Printf(_L("Probe::~CProtocolProbe()\r\n"));)	
    48 	LOG(Log::Printf(_L("Probe::~CProtocolProbe()\r\n"));)
    64 	if(iFileOpen)
       
    65 	    {
       
    66 		iFile.Close();
       
    67 		iFileOpen = EFalse;
       
    68 	    }
       
    69 	if(iFileServerOpen)
       
    70 		{
       
    71 		iFs.Close();
       
    72 		iFileServerOpen = EFalse;
       
    73 		}	
       
    74     if(iBufCreated)
       
    75         {
       
    76         iBuf.Close();
       
    77         iBufCreated = EFalse;
       
    78         }
       
    79 	}
    49 	}
       
    50 
    80 
    51 
    81 CProtocolProbe *CProtocolProbe::NewL(TUint aId)
    52 CProtocolProbe *CProtocolProbe::NewL(TUint aId)
    82 	{
    53 	{
    83 
       
    84 	return new (ELeave) CProtocolProbe(aId);
    54 	return new (ELeave) CProtocolProbe(aId);
    85 	}
    55 	}
    86 
    56 
    87 void CProtocolProbe::FillIdentification(TServerProtocolDesc& anEntry, TUint aId)
    57 void CProtocolProbe::FillIdentification(TServerProtocolDesc& anEntry, TUint aId)
    88 	{
    58 	{
    89 
       
    90 	anEntry.iName=_S("probe");
    59 	anEntry.iName=_S("probe");
    91 	if (aId > 1)
    60 	if (aId > 1)
    92 		{
       
    93 		anEntry.iName.AppendNum(aId-1);
    61 		anEntry.iName.AppendNum(aId-1);
    94 		}
       
    95 
       
    96 	anEntry.iAddrFamily = KAfProbe;
    62 	anEntry.iAddrFamily = KAfProbe;
    97 	anEntry.iSockType = KSockDatagram;
    63 	anEntry.iSockType = KSockDatagram;
    98 	anEntry.iProtocol = aId;
    64 	anEntry.iProtocol = aId;
    99 	anEntry.iVersion = TVersion(1, 0, 0);
    65 	anEntry.iVersion = TVersion(1, 0, 0);
   100 	anEntry.iByteOrder = EBigEndian;
    66 	anEntry.iByteOrder = EBigEndian;
   115 CServProviderBase* CProtocolProbe::NewSAPL(TUint aProtocol)
    81 CServProviderBase* CProtocolProbe::NewSAPL(TUint aProtocol)
   116 	{
    82 	{
   117 	LOG(Log::Printf(_L("Probe::NewSAPL(%d)\r\n"), aProtocol);)
    83 	LOG(Log::Printf(_L("Probe::NewSAPL(%d)\r\n"), aProtocol);)
   118 
    84 
   119 	if (aProtocol != KSockDatagram)
    85 	if (aProtocol != KSockDatagram)
   120 		{
       
   121 		User::Leave(KErrNotSupported);
    86 		User::Leave(KErrNotSupported);
   122 		}
       
   123 
       
   124 	CProviderProbe* sap = new (ELeave) CProviderProbe(this);
    87 	CProviderProbe* sap = new (ELeave) CProviderProbe(this);
   125 	sap->iNext = iList;
    88 	sap->iNext = iList;
   126 	iList = sap;
    89 	iList = sap;
   127 	return sap;
    90 	return sap;
   128 	}
    91 	}
   132 // *************************
    95 // *************************
   133 // Disconnect SAP from the protocol
    96 // Disconnect SAP from the protocol
   134 //
    97 //
   135 void CProtocolProbe::CancelSAP(const CServProviderBase* aSAP)
    98 void CProtocolProbe::CancelSAP(const CServProviderBase* aSAP)
   136 	{
    99 	{
   137 	
       
   138 	CProviderProbe **h, *sap;
   100 	CProviderProbe **h, *sap;
   139 	for (h = &iList; (sap = *h) != NULL; h = &sap->iNext)
   101 	for (h = &iList; (sap = *h) != NULL; h = &sap->iNext)
   140 		if (sap == aSAP)
   102 		if (sap == aSAP)
   141 			{
   103 			{
   142 			*h = sap->iNext;
   104 			*h = sap->iNext;
   143 			break;
   105 			break;
   144 			}
   106 			}
   145 	}
   107 	}
   146 
   108 
       
   109 
   147 // CProtocolProbe::NetworkAttachedL
   110 // CProtocolProbe::NetworkAttachedL
   148 // ********************************
   111 // ********************************
   149 // When network becomes available, do the hooking!
   112 // When network becomes available, do the hooking!
   150 //
   113 //
   151 void CProtocolProbe::NetworkAttachedL()
   114 void CProtocolProbe::NetworkAttachedL()
   152 	{
   115 	{
   153 
       
   154 	NetworkService()->BindL(this, MIp6Hook::BindPostHook());
   116 	NetworkService()->BindL(this, MIp6Hook::BindPostHook());
   155 	NetworkService()->BindL(this, MIp6Hook::BindPostHook()+1);
   117 	NetworkService()->BindL(this, MIp6Hook::BindPostHook()+1);
   156 
       
   157 	// initialise dump file
       
   158 	if(iFileOpen)
       
   159 		{
       
   160 		iFile.Close();
       
   161 		iFileOpen = EFalse;
       
   162 		}
       
   163 	if(iFileServerOpen)
       
   164 		{
       
   165 		iFs.Close();
       
   166 		iFileServerOpen = EFalse;
       
   167 		}
       
   168 
       
   169 	User::LeaveIfError(iFs.Connect());
       
   170     iFileServerOpen = ETrue;
       
   171     TBuf<50> filename;
       
   172     filename.Append(KLogFolder);
       
   173     filename.Append(KTcpDumpFolder);
       
   174     filename.Append(KProbeDumpFile);
       
   175 	User::LeaveIfError(iFile.Replace(iFs, filename, EFileWrite));
       
   176     iFileOpen = ETrue;
       
   177 
       
   178     // allocate buffer
       
   179     if(!iBufCreated)
       
   180         {
       
   181 		const TInt KMaxBufferSize = 65535;
       
   182         iBuf.CreateL(KMaxBufferSize);
       
   183         iBufCreated = ETrue;
       
   184         }
       
   185     
       
   186 	LibcapDumpFileHeader();
       
   187 	}
   118 	}
   188 
   119 
   189 void CProtocolProbe::Queue(RMBufChain &aPacket)
       
   190 //
   120 //
   191 //  Takes a copy of aPacket, adds it to the queue and triggers the callback
   121 //	CProtocolProbe::Deliver
       
   122 //	***********************
       
   123 //	Generate a copy of the packet to every bound provider
   192 //
   124 //
       
   125 void CProtocolProbe::Deliver(RMBufChain &aPacket)
   193 	{
   126 	{
       
   127 	const RMBufPktInfo *const info = RMBufPacketBase::PeekInfoInChain(aPacket);
   194 
   128 
   195 	RMBufPacketBase copy;
   129 	for (CProviderProbe* sap = iList; sap != NULL; sap = sap->iNext)
   196 	TRAPD(err, copy.CopyPackedL(aPacket));
       
   197 	if (err == KErrNone)
       
   198 		{
   130 		{
   199 
   131 		if (sap->IsReceiving(*info))
   200 		//
   132 			{
   201 		// Calculate packet time-stamp
   133 			RMBufPacketBase copy;
   202 		//
   134 			TRAPD(err, copy.CopyPackedL(aPacket));
   203 		TTime newTime;
   135 			if (err == KErrNone)
   204 		newTime.UniversalTime();
   136 				sap->Process(copy, this);
   205 		TTimeIntervalMicroSeconds interval = newTime.MicroSecondsFrom(iTimeOrigin);
   137 			else
   206 
   138 				copy.Free();
   207 		const TInt KMicrosInASecond = 1000000;
   139 			}
   208 
       
   209 		//TUint32 micros = interval.Int64().Low();
       
   210 		TUint32 micros = I64LOW(interval.Int64());//.Low();  x.Low() -> I64LOW(x)
       
   211 		TUint32 secs = micros / KMicrosInASecond;
       
   212 		micros -= (secs * KMicrosInASecond);
       
   213 
       
   214 		//
       
   215 		// Reuse the protocol and flags fields of
       
   216 		// RMBufPktInfo to store the time-stamp
       
   217 		//
       
   218 		RMBufPktInfo* info = RMBufPacket::PeekInfoInChain(copy);
       
   219 		info->iProtocol = static_cast<TInt>(secs);
       
   220 		info->iFlags = static_cast<TUint>(micros);
       
   221 
       
   222 		iQueue.Append(copy);
       
   223 		iDumpCb.CallBack();
       
   224 		}
       
   225 	else
       
   226 		{
       
   227 		copy.Free();
       
   228 		}
   140 		}
   229 	}
   141 	}
   230 
   142 
   231 
   143 
   232 //
       
   233 //	CProtocolProbe::Dump
       
   234 //	***********************
       
   235 //	Log the packet to file
       
   236 //
       
   237 void CProtocolProbe::Dump(RMBufChain &aPacket)
       
   238 	{
       
   239 
       
   240 	RMBufPacket packet;
       
   241 	packet.Assign(aPacket);
       
   242 	RMBufPktInfo* info = packet.Unpack();
       
   243 
       
   244 	TUint32 secs = static_cast<TUint32>(info->iProtocol);
       
   245 	TUint32 micros = static_cast<TUint32>(info->iFlags);
       
   246 
       
   247     iBuf.SetMax();
       
   248     packet.CopyOut(iBuf, 0);
       
   249     if(iBuf.Length() != info->iLength)
       
   250         {
       
   251         iBuf.SetLength(info->iLength);
       
   252         }
       
   253 	LibcapDump(iBuf, secs, micros);
       
   254 	packet.Free();
       
   255 	}
       
   256 
       
   257 TInt CProtocolProbe::Send(RMBufChain &aPacket, CProtocolBase* aSrc)
   144 TInt CProtocolProbe::Send(RMBufChain &aPacket, CProtocolBase* aSrc)
   258 	{
   145 	{
   259 
   146 	Deliver(aPacket);
   260 	Queue(aPacket);
       
   261 	return CProtocolPosthook::Send(aPacket, aSrc);
   147 	return CProtocolPosthook::Send(aPacket, aSrc);
   262 	}
   148 	}
   263 
   149 
   264 void CProtocolProbe::Process(RMBufChain &aPacket, CProtocolBase* aSrc)
   150 void CProtocolProbe::Process(RMBufChain &aPacket, CProtocolBase* aSrc)
   265 	{
   151 	{
   266 
   152 	Deliver(aPacket);
   267 	Queue(aPacket);
       
   268 	CProtocolPosthook::Process(aPacket, aSrc);
   153 	CProtocolPosthook::Process(aPacket, aSrc);
   269 	}
   154 	}
   270 
       
   271 void CProtocolProbe::LibcapDumpFileHeader()
       
   272 //
       
   273 //  Dump file header in a format compatible with Libcap
       
   274 //
       
   275 //  Format is:
       
   276 //  
       
   277 //  struct FileHeader
       
   278 //      {
       
   279 //	    TUint32 magic; 
       
   280 //	    TUint16 version_major;
       
   281 //	    TUint16 version_minor;
       
   282 //	    TUint32 thiszone;	/* gmt to local correction */
       
   283 //	    TUint32 sigfigs;	/* accuracy of timestamps */
       
   284 //	    TUint32 snaplen;	/* max length saved portion of each pkt */
       
   285 //	    TUint32 linktype;	/* data link type (LINKTYPE_*) */
       
   286 //      };
       
   287 //
       
   288 //  Note LINKTYPE specified in libpcap/bpf/net/bpf.h (see www.tcpdump.org)
       
   289 //
       
   290 	{
       
   291 
       
   292 	TBuf8<sizeof(TUint32)*5+sizeof(TUint16)*2> fileHeader;
       
   293 	*((TUint32*) &(fileHeader.Ptr()[0])) = 0xa1b2c3d4;
       
   294 	*((TUint16*) &(fileHeader.Ptr()[4])) = 0x02; 
       
   295 	*((TUint16*) &(fileHeader.Ptr()[6])) = 0x04; 
       
   296 	*((TUint32*) &(fileHeader.Ptr()[8])) = 0x00;
       
   297 	*((TUint32*) &(fileHeader.Ptr()[12])) = 0x00;
       
   298 	*((TUint32*) &(fileHeader.Ptr()[16])) = 0xffff;
       
   299 	*((TUint32*) &(fileHeader.Ptr()[20])) = 12;       // DLT_RAW		12	/* raw IP */
       
   300 	fileHeader.SetLength(fileHeader.MaxLength());
       
   301 
       
   302 	iFile.Write(fileHeader);
       
   303 	}
       
   304 
       
   305 void CProtocolProbe::LibcapDump(const TDesC8& aBuffer, TUint32 aTimeStampSecs, TUint32 aTimeStampMicros)
       
   306 //
       
   307 //  Dumps a packet in a format compatbible with Libcap
       
   308 //
       
   309 //  For each record the format is:
       
   310 //
       
   311 //  struct record 
       
   312 //      {
       
   313 //      TUint32 sec;	/* time stamp - secs*/
       
   314 //      TUint32 usec;	/* time stamp - microsecs*/
       
   315 //      TUint32 captureLen;	/* length packet captured */
       
   316 //      TUint32 packetLen;	/* total length of packet*/
       
   317 //      };
       
   318 //
       
   319 //  Byte ordering of the header is little endian
       
   320 //  Byte ordering of the packet is network byte order (big endian)
       
   321 //
       
   322 	{
       
   323 	
       
   324 	TBuf8<sizeof(TUint32)*4> recordHeader;
       
   325 	recordHeader.FillZ();
       
   326 
       
   327 	*((TUint32*) &(recordHeader.Ptr()[0])) = aTimeStampSecs;
       
   328 	*((TUint32*) &(recordHeader.Ptr()[4])) = aTimeStampMicros;
       
   329 	*((TUint32*) &(recordHeader.Ptr()[8])) = aBuffer.Length();
       
   330 	*((TUint32*) &(recordHeader.Ptr()[12])) = aBuffer.Length();
       
   331 	recordHeader.SetLength(recordHeader.MaxLength());
       
   332 
       
   333 	iFile.Write(recordHeader);
       
   334 	iFile.Write(aBuffer);
       
   335 	}
       
   336 
       
   337 
       
   338 
       
   339 TInt CProtocolProbe::DumpCb(TAny* aThisPtr)
       
   340 //
       
   341 //  Callback function - calls DumpQueuedPackets()
       
   342 //
       
   343 	{
       
   344 
       
   345 	CProtocolProbe* self = static_cast<CProtocolProbe*>(aThisPtr);
       
   346 	self->DumpQueuedPackets();
       
   347 	return KErrNone;
       
   348 	}
       
   349 
       
   350 void CProtocolProbe::DumpQueuedPackets()
       
   351 //
       
   352 //  Dumps all packets on the queue to the log file
       
   353 //
       
   354 	{
       
   355 
       
   356 	RMBufPacketBase packet;
       
   357 	while(iQueue.Remove(packet))
       
   358 		{
       
   359 		Dump(packet);
       
   360 		}
       
   361 	}