diff -r 000000000000 -r af10295192d8 linklayerprotocols/ethernetnif/log/eth_log.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/linklayerprotocols/ethernetnif/log/eth_log.cpp Tue Jan 26 15:23:49 2010 +0200 @@ -0,0 +1,169 @@ +// Copyright (c) 2003-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: +// Ethernet libcap format logging +// +// + +/** + @file + @internalComponent +*/ + +#include "eth_log.h" + +#ifdef TCPDUMP_LOGGING + +CEthLog::CEthLog() : + iUnixTimeBase(KUnixTimeBaseDes) +{ +} + +CEthLog::~CEthLog() +{ + __FLOG_CLOSE; +} + +CEthLog* CEthLog::NewL() +{ + CEthLog* self = new (ELeave) CEthLog; + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); // self + return self; +} + +void CEthLog::ConstructL() +{ + iEthTcpDumpLogFileName = KEthTcpDump; + __FLOG_OPEN(KEthTcpDumpFirstTag,KEthTcpDump); +} + +/** +Dumps a packet in a pcap format (see www.ethereal.com) +For each record the format is: +struct timeval - time packet received +number of octects in packet +number of octects from packet in file - ie. the number that we captured. For this purpose, this will be all of them. +Byte ordering of the header is little endian +Byte ordering of the packet is network byte order (big endian) +@param aCaptureTime The time that the packet was captured +@param RMBufChain& aBuffer Buffer to dump +*/ +void CEthLog::DumpFrame(TTime aCaptureTime, RMBufChain& aPdu) +{ + TBuf8<16> recordHeader; // one TInt64 for time, one TUint32 for observed packet length, one TUint32 for captured packet length + recordHeader.SetLength(recordHeader.MaxLength()); + + TInt err; + // Build the header for this frame + TTimeIntervalSeconds captureTimeSecs; + + err = aCaptureTime.SecondsFrom(iUnixTimeBase, captureTimeSecs); + if(err) // if there's an overflow, then stick all zeros in - not good, but at least we got the data + captureTimeSecs = 0; + + TInt captureTimeMicroSecs; + captureTimeMicroSecs = I64LOW(aCaptureTime.Int64()); + captureTimeMicroSecs = captureTimeMicroSecs % 1000000; // get microseconds component + + recordHeader[0]= static_cast((captureTimeSecs.Int() & 0x000000ff)); + recordHeader[1]= static_cast((captureTimeSecs.Int() & 0x0000ff00) >> 8); + recordHeader[2]= static_cast((captureTimeSecs.Int() & 0x00ff0000) >> 16); + recordHeader[3]= static_cast((captureTimeSecs.Int() & 0xff000000) >> 24); + recordHeader[4]= static_cast((captureTimeMicroSecs & 0x000000ff)); + recordHeader[5]= static_cast((captureTimeMicroSecs & 0x0000ff00) >> 8); + recordHeader[6]= static_cast((captureTimeMicroSecs & 0x00ff0000) >> 16); + recordHeader[7]= static_cast((captureTimeMicroSecs & 0xff000000) >> 24); + + TInt32 dataBytes = aPdu.Length(); + + recordHeader[8]= static_cast((dataBytes & 0x000000ff)); // first entry shows the length of the packet + recordHeader[9]= static_cast((dataBytes & 0x0000ff00) >> 8); + recordHeader[10]= static_cast((dataBytes & 0x00ff0000) >> 16); + recordHeader[11]= static_cast((dataBytes & 0xff000000) >> 24); + + recordHeader[12]=recordHeader[8]; // second shows how much of it we've written to the file + recordHeader[13]=recordHeader[9]; + recordHeader[14]=recordHeader[10]; + recordHeader[15]=recordHeader[11]; + + // create a temporary buffer to hold the pdu (flogger needs a descriptor, so we have to un-mbuf the data) + // could put this on the heap, but start by trying it on the stack because we don't have to do memory allocations that way + // might be worth having a permanent ~1500 byte HBufC on the heap to reuse here + TBuf8 pdu; + pdu.SetMax(); + aPdu.CopyOut(pdu); + + __FLOG_BINARY((recordHeader)); + __FLOG_BINARY((pdu)); +} + +/** +Dump file header to show that this is a pcap capture file in pcap format +Format is (from winpcap savefile.c): +hdr.magic = TCPDUMP_MAGIC; +hdr.version_major = PCAP_VERSION_MAJOR; +hdr.version_minor = PCAP_VERSION_MINOR; +hdr.thiszone = thiszone; +hdr.snaplen = snaplen; +hdr.sigfigs = 0; +hdr.linktype = linktype; +@see http://www.ethereal.com/lists/ethereal-dev/199909/msg00124.html for more details +*/ +void CEthLog::DumpTcpDumpFileHeader() +{ + const TUint headerSize = 24; // header is 24 bytes long + + TBuf8 fileHeader; + fileHeader.SetLength(fileHeader.MaxLength()); + + fileHeader[0] = 0xd4; // first four bytes - pcap magic number, indicates this is a pcap format file + fileHeader[1] = 0xc3; + fileHeader[2] = 0xb2; + fileHeader[3] = 0xa1; + + fileHeader[4] = 0x02; // two bytes of major version number + fileHeader[5] = 0x00; + + fileHeader[6] = 0x04; // two bytes of minor version number + fileHeader[7] = 0x00; + + // find the offset from UTC of this device + TLocale locale; + TInt32 offset = locale.UniversalTimeOffset().Int(); + + fileHeader[8] = static_cast(((offset & 0xff000000) >> 24)); // four bytes of offset from UTC in seconds + fileHeader[9] = static_cast(((offset & 0x00ff0000) >> 16)); + fileHeader[10] = static_cast(((offset & 0x0000ff00) >> 8)); + fileHeader[11] = static_cast((offset & 0x000000ff)); + + fileHeader[12] = 0x00; // four bytes of timestamp accuracy (not sure of units) - just set to zero, no-one seems to use them + fileHeader[13] = 0x00; + fileHeader[14] = 0x00; + fileHeader[15] = 0x00; + + fileHeader[16] = 0xFF; // four bytes of maximum snapshot length - we're just going set it to something big + fileHeader[17] = 0xFF; + fileHeader[18] = 0x00; + fileHeader[19] = 0x00; + + fileHeader[20] = 0x01; // four bytes of packet capture type (0x01 for 10Mb ethernet (and other speeds, I suspect!)) + fileHeader[21] = 0x00; + fileHeader[22] = 0x00; + fileHeader[23] = 0x00; + + __FLOG_BINARY((fileHeader)); +} + +#endif