|
1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // Ethernet libcap format logging |
|
15 // |
|
16 // |
|
17 |
|
18 /** |
|
19 @file |
|
20 @internalComponent |
|
21 */ |
|
22 |
|
23 #include "eth_log.h" |
|
24 |
|
25 #ifdef TCPDUMP_LOGGING |
|
26 |
|
27 CEthLog::CEthLog() : |
|
28 iUnixTimeBase(KUnixTimeBaseDes) |
|
29 { |
|
30 } |
|
31 |
|
32 CEthLog::~CEthLog() |
|
33 { |
|
34 __FLOG_CLOSE; |
|
35 } |
|
36 |
|
37 CEthLog* CEthLog::NewL() |
|
38 { |
|
39 CEthLog* self = new (ELeave) CEthLog; |
|
40 CleanupStack::PushL(self); |
|
41 self->ConstructL(); |
|
42 CleanupStack::Pop(); // self |
|
43 return self; |
|
44 } |
|
45 |
|
46 void CEthLog::ConstructL() |
|
47 { |
|
48 iEthTcpDumpLogFileName = KEthTcpDump; |
|
49 __FLOG_OPEN(KEthTcpDumpFirstTag,KEthTcpDump); |
|
50 } |
|
51 |
|
52 /** |
|
53 Dumps a packet in a pcap format (see www.ethereal.com) |
|
54 For each record the format is: |
|
55 struct timeval - time packet received |
|
56 number of octects in packet |
|
57 number of octects from packet in file - ie. the number that we captured. For this purpose, this will be all of them. |
|
58 Byte ordering of the header is little endian |
|
59 Byte ordering of the packet is network byte order (big endian) |
|
60 @param aCaptureTime The time that the packet was captured |
|
61 @param RMBufChain& aBuffer Buffer to dump |
|
62 */ |
|
63 void CEthLog::DumpFrame(TTime aCaptureTime, RMBufChain& aPdu) |
|
64 { |
|
65 TBuf8<16> recordHeader; // one TInt64 for time, one TUint32 for observed packet length, one TUint32 for captured packet length |
|
66 recordHeader.SetLength(recordHeader.MaxLength()); |
|
67 |
|
68 TInt err; |
|
69 // Build the header for this frame |
|
70 TTimeIntervalSeconds captureTimeSecs; |
|
71 |
|
72 err = aCaptureTime.SecondsFrom(iUnixTimeBase, captureTimeSecs); |
|
73 if(err) // if there's an overflow, then stick all zeros in - not good, but at least we got the data |
|
74 captureTimeSecs = 0; |
|
75 |
|
76 TInt captureTimeMicroSecs; |
|
77 captureTimeMicroSecs = I64LOW(aCaptureTime.Int64()); |
|
78 captureTimeMicroSecs = captureTimeMicroSecs % 1000000; // get microseconds component |
|
79 |
|
80 recordHeader[0]= static_cast<TUint8>((captureTimeSecs.Int() & 0x000000ff)); |
|
81 recordHeader[1]= static_cast<TUint8>((captureTimeSecs.Int() & 0x0000ff00) >> 8); |
|
82 recordHeader[2]= static_cast<TUint8>((captureTimeSecs.Int() & 0x00ff0000) >> 16); |
|
83 recordHeader[3]= static_cast<TUint8>((captureTimeSecs.Int() & 0xff000000) >> 24); |
|
84 recordHeader[4]= static_cast<TUint8>((captureTimeMicroSecs & 0x000000ff)); |
|
85 recordHeader[5]= static_cast<TUint8>((captureTimeMicroSecs & 0x0000ff00) >> 8); |
|
86 recordHeader[6]= static_cast<TUint8>((captureTimeMicroSecs & 0x00ff0000) >> 16); |
|
87 recordHeader[7]= static_cast<TUint8>((captureTimeMicroSecs & 0xff000000) >> 24); |
|
88 |
|
89 TInt32 dataBytes = aPdu.Length(); |
|
90 |
|
91 recordHeader[8]= static_cast<TUint8>((dataBytes & 0x000000ff)); // first entry shows the length of the packet |
|
92 recordHeader[9]= static_cast<TUint8>((dataBytes & 0x0000ff00) >> 8); |
|
93 recordHeader[10]= static_cast<TUint8>((dataBytes & 0x00ff0000) >> 16); |
|
94 recordHeader[11]= static_cast<TUint8>((dataBytes & 0xff000000) >> 24); |
|
95 |
|
96 recordHeader[12]=recordHeader[8]; // second shows how much of it we've written to the file |
|
97 recordHeader[13]=recordHeader[9]; |
|
98 recordHeader[14]=recordHeader[10]; |
|
99 recordHeader[15]=recordHeader[11]; |
|
100 |
|
101 // create a temporary buffer to hold the pdu (flogger needs a descriptor, so we have to un-mbuf the data) |
|
102 // 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 |
|
103 // might be worth having a permanent ~1500 byte HBufC on the heap to reuse here |
|
104 TBuf8<KDefaultMtuSetting + KEtherLLCHeaderSize> pdu; |
|
105 pdu.SetMax(); |
|
106 aPdu.CopyOut(pdu); |
|
107 |
|
108 __FLOG_BINARY((recordHeader)); |
|
109 __FLOG_BINARY((pdu)); |
|
110 } |
|
111 |
|
112 /** |
|
113 Dump file header to show that this is a pcap capture file in pcap format |
|
114 Format is (from winpcap savefile.c): |
|
115 hdr.magic = TCPDUMP_MAGIC; |
|
116 hdr.version_major = PCAP_VERSION_MAJOR; |
|
117 hdr.version_minor = PCAP_VERSION_MINOR; |
|
118 hdr.thiszone = thiszone; |
|
119 hdr.snaplen = snaplen; |
|
120 hdr.sigfigs = 0; |
|
121 hdr.linktype = linktype; |
|
122 @see http://www.ethereal.com/lists/ethereal-dev/199909/msg00124.html for more details |
|
123 */ |
|
124 void CEthLog::DumpTcpDumpFileHeader() |
|
125 { |
|
126 const TUint headerSize = 24; // header is 24 bytes long |
|
127 |
|
128 TBuf8<headerSize> fileHeader; |
|
129 fileHeader.SetLength(fileHeader.MaxLength()); |
|
130 |
|
131 fileHeader[0] = 0xd4; // first four bytes - pcap magic number, indicates this is a pcap format file |
|
132 fileHeader[1] = 0xc3; |
|
133 fileHeader[2] = 0xb2; |
|
134 fileHeader[3] = 0xa1; |
|
135 |
|
136 fileHeader[4] = 0x02; // two bytes of major version number |
|
137 fileHeader[5] = 0x00; |
|
138 |
|
139 fileHeader[6] = 0x04; // two bytes of minor version number |
|
140 fileHeader[7] = 0x00; |
|
141 |
|
142 // find the offset from UTC of this device |
|
143 TLocale locale; |
|
144 TInt32 offset = locale.UniversalTimeOffset().Int(); |
|
145 |
|
146 fileHeader[8] = static_cast<TUint8>(((offset & 0xff000000) >> 24)); // four bytes of offset from UTC in seconds |
|
147 fileHeader[9] = static_cast<TUint8>(((offset & 0x00ff0000) >> 16)); |
|
148 fileHeader[10] = static_cast<TUint8>(((offset & 0x0000ff00) >> 8)); |
|
149 fileHeader[11] = static_cast<TUint8>((offset & 0x000000ff)); |
|
150 |
|
151 fileHeader[12] = 0x00; // four bytes of timestamp accuracy (not sure of units) - just set to zero, no-one seems to use them |
|
152 fileHeader[13] = 0x00; |
|
153 fileHeader[14] = 0x00; |
|
154 fileHeader[15] = 0x00; |
|
155 |
|
156 fileHeader[16] = 0xFF; // four bytes of maximum snapshot length - we're just going set it to something big |
|
157 fileHeader[17] = 0xFF; |
|
158 fileHeader[18] = 0x00; |
|
159 fileHeader[19] = 0x00; |
|
160 |
|
161 fileHeader[20] = 0x01; // four bytes of packet capture type (0x01 for 10Mb ethernet (and other speeds, I suspect!)) |
|
162 fileHeader[21] = 0x00; |
|
163 fileHeader[22] = 0x00; |
|
164 fileHeader[23] = 0x00; |
|
165 |
|
166 __FLOG_BINARY((fileHeader)); |
|
167 } |
|
168 |
|
169 #endif |