1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<title>WinPcap: Handling offline dump files</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<!-- Generated by Doxygen 1.6.1 -->
<div class="navigation" id="top">
<div class="tabs">
<ul>
<li><a href="main.html"><span>Main Page</span></a></li>
<li><a href="pages.html"><span>Related Pages</span></a></li>
<li><a href="modules.html"><span>Modules</span></a></li>
<li><a href="annotated.html"><span>Data Structures</span></a></li>
<li><a href="files.html"><span>Files</span></a></li>
</ul>
</div>
</div>
<div class="contents">
<h1>Handling offline dump files</h1><table border="0" cellpadding="0" cellspacing="0">
</table>
<p>In this lession we are going to learn how to handle packet capture to a file (dump to file). WinPcap offers a wide range of functions to save the network traffic to a file and to read the content of dumps -- this lesson will teach how to use all of these functions. We'll see also how to use the kernel dump feature of WinPcap to obtain high-performance dumps (<b>NOTE:</b> At the moment, due to some problems with the new kernel buffer, this feature has been disabled).</p>
<p>The format for dump files is the libpcap one. This format contains the data of the captured packets in binary form and is a standard used by many network tools including WinDump, Ethereal and Snort.</p>
<p><b>Saving packets to a dump file</b></p>
<p>First of all, let's see how to write packets in libpcap format.</p>
<p>The following example captures the packets from the selected interface and saves them on a file whose name is provided by the user.</p>
<div class="fragment"><pre class="fragment"><span class="preprocessor">#include "pcap.h"</span>
<span class="comment">/* prototype of the packet handler */</span>
<span class="keywordtype">void</span> packet_handler(u_char *param, <span class="keyword">const</span> <span class="keyword">struct</span> <a class="code" href="structpcap__pkthdr.html" title="Header of a packet in the dump file.">pcap_pkthdr</a> *header, <span class="keyword">const</span> u_char *pkt_data);
<span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> **argv)
{
<a class="code" href="structpcap__if.html" title="Item in a list of interfaces, used by pcap_findalldevs().">pcap_if_t</a> *alldevs;
<a class="code" href="structpcap__if.html" title="Item in a list of interfaces, used by pcap_findalldevs().">pcap_if_t</a> *d;
<span class="keywordtype">int</span> inum;
<span class="keywordtype">int</span> i=0;
<a class="code" href="group__wpcap__def.html#ga4711d025f83503ce692efa5e45ec60a7" title="Descriptor of an open capture instance. This structure is opaque to the user, that...">pcap_t</a> *adhandle;
<span class="keywordtype">char</span> errbuf[<a class="code" href="group__wpcap__def.html#gacd448353957d92c98fccc29e1fc8d927" title="Size to use when allocating the buffer that contains the libpcap errors.">PCAP_ERRBUF_SIZE</a>];
<a class="code" href="group__wpcap__def.html#gab8c7858aa3a7e3158d9d58cb113a2ae8" title="libpcap savefile descriptor.">pcap_dumper_t</a> *dumpfile;
<span class="comment">/* Check command line */</span>
<span class="keywordflow">if</span>(argc != 2)
{
printf(<span class="stringliteral">"usage: %s filename"</span>, argv[0]);
<span class="keywordflow">return</span> -1;
}
<span class="comment">/* Retrieve the device list on the local machine */</span>
<span class="keywordflow">if</span> (<a class="code" href="group__wpcapfunc.html#ga98f36e62c95c6ad81eaa8b2bbeb8f16e" title="Create a list of network devices that can be opened with pcap_open().">pcap_findalldevs_ex</a>(<a class="code" href="group__remote__source__string.html#ga6d7103b8a7e1eca8c325bd8f32c361c3" title="String that will be used to determine the type of source in use (file, remote/local...">PCAP_SRC_IF_STRING</a>, NULL, &alldevs, errbuf) == -1)
{
fprintf(stderr,<span class="stringliteral">"Error in pcap_findalldevs: %s\n"</span>, errbuf);
exit(1);
}
<span class="comment">/* Print the list */</span>
<span class="keywordflow">for</span>(d=alldevs; d; d=d-><a class="code" href="structpcap__if.html#a81508e6e4e41ca4235c8d6b51913c536" title="if not NULL, a pointer to the next element in the list; NULL for the last element...">next</a>)
{
printf(<span class="stringliteral">"%d. %s"</span>, ++i, d-><a class="code" href="structpcap__if.html#a5ac083a645d964373f022d03df4849c8" title="a pointer to a string giving a name for the device to pass to pcap_open_live()">name</a>);
<span class="keywordflow">if</span> (d-><a class="code" href="structpcap__if.html#a8444d6e0dfe2bbab0b5e7b24308f1559" title="if not NULL, a pointer to a string giving a human-readable description of the device...">description</a>)
printf(<span class="stringliteral">" (%s)\n"</span>, d-><a class="code" href="structpcap__if.html#a8444d6e0dfe2bbab0b5e7b24308f1559" title="if not NULL, a pointer to a string giving a human-readable description of the device...">description</a>);
<span class="keywordflow">else</span>
printf(<span class="stringliteral">" (No description available)\n"</span>);
}
<span class="keywordflow">if</span>(i==0)
{
printf(<span class="stringliteral">"\nNo interfaces found! Make sure WinPcap is installed.\n"</span>);
<span class="keywordflow">return</span> -1;
}
printf(<span class="stringliteral">"Enter the interface number (1-%d):"</span>,i);
scanf_s(<span class="stringliteral">"%d"</span>, &inum);
<span class="keywordflow">if</span>(inum < 1 || inum > i)
{
printf(<span class="stringliteral">"\nInterface number out of range.\n"</span>);
<span class="comment">/* Free the device list */</span>
<a class="code" href="group__wpcapfunc.html#ga346b4b0b7fd1cda4abb9a39f767dbeb1" title="Free an interface list returned by pcap_findalldevs().">pcap_freealldevs</a>(alldevs);
<span class="keywordflow">return</span> -1;
}
<span class="comment">/* Jump to the selected adapter */</span>
<span class="keywordflow">for</span>(d=alldevs, i=0; i< inum-1 ;d=d-><a class="code" href="structpcap__if.html#a81508e6e4e41ca4235c8d6b51913c536" title="if not NULL, a pointer to the next element in the list; NULL for the last element...">next</a>, i++);
<span class="comment">/* Open the device */</span>
<span class="keywordflow">if</span> ( (adhandle= <a class="code" href="group__wpcapfunc.html#ga2b64c7b6490090d1d37088794f1f1791" title="Open a generic source in order to capture / send (WinPcap only) traffic.">pcap_open</a>(d-><a class="code" href="structpcap__if.html#a5ac083a645d964373f022d03df4849c8" title="a pointer to a string giving a name for the device to pass to pcap_open_live()">name</a>, <span class="comment">// name of the device</span>
65536, <span class="comment">// portion of the packet to capture</span>
<span class="comment">// 65536 guarantees that the whole packet will be captured on all the link layers</span>
<a class="code" href="group__remote__open__flags.html#ga9134ce51a9a6a7d497c3dee5affdc3b9" title="Defines if the adapter has to go in promiscuous mode.">PCAP_OPENFLAG_PROMISCUOUS</a>, <span class="comment">// promiscuous mode</span>
1000, <span class="comment">// read timeout</span>
NULL, <span class="comment">// authentication on the remote machine</span>
errbuf <span class="comment">// error buffer</span>
) ) == NULL)
{
fprintf(stderr,<span class="stringliteral">"\nUnable to open the adapter. %s is not supported by WinPcap\n"</span>, d-><a class="code" href="structpcap__if.html#a5ac083a645d964373f022d03df4849c8" title="a pointer to a string giving a name for the device to pass to pcap_open_live()">name</a>);
<span class="comment">/* Free the device list */</span>
<a class="code" href="group__wpcapfunc.html#ga346b4b0b7fd1cda4abb9a39f767dbeb1" title="Free an interface list returned by pcap_findalldevs().">pcap_freealldevs</a>(alldevs);
<span class="keywordflow">return</span> -1;
}
<span class="comment">/* Open the dump file */</span>
dumpfile = <a class="code" href="group__wpcapfunc.html#ga9506c33d580fdb5e5c288dba0f8a085c" title="Open a file to write packets.">pcap_dump_open</a>(adhandle, argv[1]);
<span class="keywordflow">if</span>(dumpfile==NULL)
{
fprintf(stderr,<span class="stringliteral">"\nError opening output file\n"</span>);
<span class="keywordflow">return</span> -1;
}
printf(<span class="stringliteral">"\nlistening on %s... Press Ctrl+C to stop...\n"</span>, d-><a class="code" href="structpcap__if.html#a8444d6e0dfe2bbab0b5e7b24308f1559" title="if not NULL, a pointer to a string giving a human-readable description of the device...">description</a>);
<span class="comment">/* At this point, we no longer need the device list. Free it */</span>
<a class="code" href="group__wpcapfunc.html#ga346b4b0b7fd1cda4abb9a39f767dbeb1" title="Free an interface list returned by pcap_findalldevs().">pcap_freealldevs</a>(alldevs);
<span class="comment">/* start the capture */</span>
<a class="code" href="group__wpcapfunc.html#ga6bcb7c5c59d76ec16b8a699da136b5de" title="Collect a group of packets.">pcap_loop</a>(adhandle, 0, packet_handler, (<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *)dumpfile);
<span class="keywordflow">return</span> 0;
}
<span class="comment">/* Callback function invoked by libpcap for every incoming packet */</span>
<span class="keywordtype">void</span> packet_handler(u_char *dumpfile, <span class="keyword">const</span> <span class="keyword">struct</span> <a class="code" href="structpcap__pkthdr.html" title="Header of a packet in the dump file.">pcap_pkthdr</a> *header, <span class="keyword">const</span> u_char *pkt_data)
{
<span class="comment">/* save the packet on the dump file */</span>
<a class="code" href="group__wpcapfunc.html#ga659439bf5aa3988b5a92d31990fbf437" title="Save a packet to disk.">pcap_dump</a>(dumpfile, header, pkt_data);
}
</pre></div><p>As you can see, the structure of the program is very similar to the ones we have seen in the previous lessons. The differences are:</p>
<ul>
<li>a call to <a class="el" href="group__wpcapfunc.html#ga9506c33d580fdb5e5c288dba0f8a085c" title="Open a file to write packets.">pcap_dump_open()</a> is issued once the interface is opened. This call opens a dump file and associates it with the interface.</li>
<li>the packets are written to this file with a <a class="el" href="group__wpcapfunc.html#ga659439bf5aa3988b5a92d31990fbf437" title="Save a packet to disk.">pcap_dump()</a> from the packet_handler() callback. The parameters of <a class="el" href="group__wpcapfunc.html#ga659439bf5aa3988b5a92d31990fbf437" title="Save a packet to disk.">pcap_dump()</a> are in 1-1 correspondence with the parameters of <a class="el" href="group__wpcapfunc.html#gabcba231c099919ecd9300d7160b19878" title="Prototype of the callback function that receives the packets.">pcap_handler()</a>.</li>
</ul>
<p><b>Reading packets from a dump file</b></p>
<p>Now that we have a dump file available, we can try to read its content. The following code opens a WinPcap/libpcap dump file and displays every packet contained in the file. The file is opened with <a class="el" href="group__wpcapfunc.html#ga91078168a13de8848df2b7b83d1f5b69" title="Open a savefile in the tcpdump/libpcap format to read packets.">pcap_open_offline()</a>, then the usual <a class="el" href="group__wpcapfunc.html#ga6bcb7c5c59d76ec16b8a699da136b5de" title="Collect a group of packets.">pcap_loop()</a> is used to sequence through the packets. As you can see, reading packets from an offline capture is nearly identical to receiving them from a physical interface.</p>
<p>This example introduces another function: pcap_createsrcsrc(). This function is required to create a source string that begins with a marker used to tell WinPcap the type of the source, e.g. "rpcap://" if we are going to open an adapter, or "file://" if we are going to open a file. This step is not required when <a class="el" href="group__wpcapfunc.html#ga98f36e62c95c6ad81eaa8b2bbeb8f16e" title="Create a list of network devices that can be opened with pcap_open().">pcap_findalldevs_ex()</a> is used (the returned values already contain these strings). However, it is required in this example because the name of the file is read from the user input.</p>
<div class="fragment"><pre class="fragment"><span class="preprocessor">#include <stdio.h></span>
<span class="preprocessor">#include <pcap.h></span>
<span class="preprocessor">#define LINE_LEN 16</span>
<span class="preprocessor"></span>
<span class="keywordtype">void</span> dispatcher_handler(u_char *, <span class="keyword">const</span> <span class="keyword">struct</span> <a class="code" href="structpcap__pkthdr.html" title="Header of a packet in the dump file.">pcap_pkthdr</a> *, <span class="keyword">const</span> u_char *);
<span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> **argv)
{
<a class="code" href="group__wpcap__def.html#ga4711d025f83503ce692efa5e45ec60a7" title="Descriptor of an open capture instance. This structure is opaque to the user, that...">pcap_t</a> *fp;
<span class="keywordtype">char</span> errbuf[<a class="code" href="group__wpcap__def.html#gacd448353957d92c98fccc29e1fc8d927" title="Size to use when allocating the buffer that contains the libpcap errors.">PCAP_ERRBUF_SIZE</a>];
<span class="keywordtype">char</span> source[<a class="code" href="group__remote__struct.html#gacacb155b596f7511f714de129ae32c97" title="Defines the maximum buffer size in which address, port, interface names are kept...">PCAP_BUF_SIZE</a>];
<span class="keywordflow">if</span>(argc != 2){
printf(<span class="stringliteral">"usage: %s filename"</span>, argv[0]);
<span class="keywordflow">return</span> -1;
}
<span class="comment">/* Create the source string according to the new WinPcap syntax */</span>
<span class="keywordflow">if</span> ( <a class="code" href="group__wpcapfunc.html#gaa3111e10f930a9772a32a922b26948b0" title="Accept a set of strings (host name, port, ...), and it returns the complete source...">pcap_createsrcstr</a>( source, <span class="comment">// variable that will keep the source string</span>
<a class="code" href="group__remote__source__ID.html#ga9188ad0fc0d12fc51d1e9f5e78bf9440" title="Internal representation of the type of source in use (file, remote/local interface)...">PCAP_SRC_FILE</a>, <span class="comment">// we want to open a file</span>
NULL, <span class="comment">// remote host</span>
NULL, <span class="comment">// port on the remote host</span>
argv[1], <span class="comment">// name of the file we want to open</span>
errbuf <span class="comment">// error buffer</span>
) != 0)
{
fprintf(stderr,<span class="stringliteral">"\nError creating a source string\n"</span>);
<span class="keywordflow">return</span> -1;
}
<span class="comment">/* Open the capture file */</span>
<span class="keywordflow">if</span> ( (fp= <a class="code" href="group__wpcapfunc.html#ga2b64c7b6490090d1d37088794f1f1791" title="Open a generic source in order to capture / send (WinPcap only) traffic.">pcap_open</a>(source, <span class="comment">// name of the device</span>
65536, <span class="comment">// portion of the packet to capture</span>
<span class="comment">// 65536 guarantees that the whole packet will be captured on all the link layers</span>
<a class="code" href="group__remote__open__flags.html#ga9134ce51a9a6a7d497c3dee5affdc3b9" title="Defines if the adapter has to go in promiscuous mode.">PCAP_OPENFLAG_PROMISCUOUS</a>, <span class="comment">// promiscuous mode</span>
1000, <span class="comment">// read timeout</span>
NULL, <span class="comment">// authentication on the remote machine</span>
errbuf <span class="comment">// error buffer</span>
) ) == NULL)
{
fprintf(stderr,<span class="stringliteral">"\nUnable to open the file %s.\n"</span>, source);
<span class="keywordflow">return</span> -1;
}
<span class="comment">// read and dispatch packets until EOF is reached</span>
<a class="code" href="group__wpcapfunc.html#ga6bcb7c5c59d76ec16b8a699da136b5de" title="Collect a group of packets.">pcap_loop</a>(fp, 0, dispatcher_handler, NULL);
<span class="keywordflow">return</span> 0;
}
<span class="keywordtype">void</span> dispatcher_handler(u_char *temp1,
<span class="keyword">const</span> <span class="keyword">struct</span> <a class="code" href="structpcap__pkthdr.html" title="Header of a packet in the dump file.">pcap_pkthdr</a> *header, <span class="keyword">const</span> u_char *pkt_data)
{
u_int i=0;
<span class="comment">/*</span>
<span class="comment"> * Unused variable</span>
<span class="comment"> */</span>
(VOID)temp1;
<span class="comment">/* print pkt timestamp and pkt len */</span>
printf(<span class="stringliteral">"%ld:%ld (%ld)\n"</span>, header-><a class="code" href="structpcap__pkthdr.html#a21be78b2818c91cb205885b8a6f5aed8" title="time stamp">ts</a>.tv_sec, header-><a class="code" href="structpcap__pkthdr.html#a21be78b2818c91cb205885b8a6f5aed8" title="time stamp">ts</a>.tv_usec, header-><a class="code" href="structpcap__pkthdr.html#a728f264db4f5cc304742565a2bcdbeea" title="length this packet (off wire)">len</a>);
<span class="comment">/* Print the packet */</span>
<span class="keywordflow">for</span> (i=1; (i < header-><a class="code" href="structpcap__pkthdr.html#aac5771ed2efd92508bb4fe650f2ce7d7" title="length of portion present">caplen</a> + 1 ) ; i++)
{
printf(<span class="stringliteral">"%.2x "</span>, pkt_data[i-1]);
<span class="keywordflow">if</span> ( (i % LINE_LEN) == 0) printf(<span class="stringliteral">"\n"</span>);
}
printf(<span class="stringliteral">"\n\n"</span>);
}
</pre></div><p>The following example has the same purpose of the last one, but <a class="el" href="group__wpcapfunc.html#ga439439c2eae61161dc1efb1e03a81133" title="Read a packet from an interface or from an offline capture.">pcap_next_ex()</a> is used instead of the <a class="el" href="group__wpcapfunc.html#ga6bcb7c5c59d76ec16b8a699da136b5de" title="Collect a group of packets.">pcap_loop()</a> callback method.</p>
<div class="fragment"><pre class="fragment"><span class="preprocessor">#include <stdio.h></span>
<span class="preprocessor">#include <pcap.h></span>
<span class="preprocessor">#define LINE_LEN 16</span>
<span class="preprocessor"></span>
<span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> **argv)
{
<a class="code" href="group__wpcap__def.html#ga4711d025f83503ce692efa5e45ec60a7" title="Descriptor of an open capture instance. This structure is opaque to the user, that...">pcap_t</a> *fp;
<span class="keywordtype">char</span> errbuf[<a class="code" href="group__wpcap__def.html#gacd448353957d92c98fccc29e1fc8d927" title="Size to use when allocating the buffer that contains the libpcap errors.">PCAP_ERRBUF_SIZE</a>];
<span class="keywordtype">char</span> source[<a class="code" href="group__remote__struct.html#gacacb155b596f7511f714de129ae32c97" title="Defines the maximum buffer size in which address, port, interface names are kept...">PCAP_BUF_SIZE</a>];
<span class="keyword">struct </span><a class="code" href="structpcap__pkthdr.html" title="Header of a packet in the dump file.">pcap_pkthdr</a> *header;
<span class="keyword">const</span> u_char *pkt_data;
u_int i=0;
<span class="keywordtype">int</span> res;
<span class="keywordflow">if</span>(argc != 2)
{
printf(<span class="stringliteral">"usage: %s filename"</span>, argv[0]);
<span class="keywordflow">return</span> -1;
}
<span class="comment">/* Create the source string according to the new WinPcap syntax */</span>
<span class="keywordflow">if</span> ( <a class="code" href="group__wpcapfunc.html#gaa3111e10f930a9772a32a922b26948b0" title="Accept a set of strings (host name, port, ...), and it returns the complete source...">pcap_createsrcstr</a>( source, <span class="comment">// variable that will keep the source string</span>
<a class="code" href="group__remote__source__ID.html#ga9188ad0fc0d12fc51d1e9f5e78bf9440" title="Internal representation of the type of source in use (file, remote/local interface)...">PCAP_SRC_FILE</a>, <span class="comment">// we want to open a file</span>
NULL, <span class="comment">// remote host</span>
NULL, <span class="comment">// port on the remote host</span>
argv[1], <span class="comment">// name of the file we want to open</span>
errbuf <span class="comment">// error buffer</span>
) != 0)
{
fprintf(stderr,<span class="stringliteral">"\nError creating a source string\n"</span>);
<span class="keywordflow">return</span> -1;
}
<span class="comment">/* Open the capture file */</span>
<span class="keywordflow">if</span> ( (fp= <a class="code" href="group__wpcapfunc.html#ga2b64c7b6490090d1d37088794f1f1791" title="Open a generic source in order to capture / send (WinPcap only) traffic.">pcap_open</a>(source, <span class="comment">// name of the device</span>
65536, <span class="comment">// portion of the packet to capture</span>
<span class="comment">// 65536 guarantees that the whole packet will be captured on all the link layers</span>
<a class="code" href="group__remote__open__flags.html#ga9134ce51a9a6a7d497c3dee5affdc3b9" title="Defines if the adapter has to go in promiscuous mode.">PCAP_OPENFLAG_PROMISCUOUS</a>, <span class="comment">// promiscuous mode</span>
1000, <span class="comment">// read timeout</span>
NULL, <span class="comment">// authentication on the remote machine</span>
errbuf <span class="comment">// error buffer</span>
) ) == NULL)
{
fprintf(stderr,<span class="stringliteral">"\nUnable to open the file %s.\n"</span>, source);
<span class="keywordflow">return</span> -1;
}
<span class="comment">/* Retrieve the packets from the file */</span>
<span class="keywordflow">while</span>((res = <a class="code" href="group__wpcapfunc.html#ga439439c2eae61161dc1efb1e03a81133" title="Read a packet from an interface or from an offline capture.">pcap_next_ex</a>( fp, &header, &pkt_data)) >= 0)
{
<span class="comment">/* print pkt timestamp and pkt len */</span>
printf(<span class="stringliteral">"%ld:%ld (%ld)\n"</span>, header-><a class="code" href="structpcap__pkthdr.html#a21be78b2818c91cb205885b8a6f5aed8" title="time stamp">ts</a>.tv_sec, header-><a class="code" href="structpcap__pkthdr.html#a21be78b2818c91cb205885b8a6f5aed8" title="time stamp">ts</a>.tv_usec, header-><a class="code" href="structpcap__pkthdr.html#a728f264db4f5cc304742565a2bcdbeea" title="length this packet (off wire)">len</a>);
<span class="comment">/* Print the packet */</span>
<span class="keywordflow">for</span> (i=1; (i < header-><a class="code" href="structpcap__pkthdr.html#aac5771ed2efd92508bb4fe650f2ce7d7" title="length of portion present">caplen</a> + 1 ) ; i++)
{
printf(<span class="stringliteral">"%.2x "</span>, pkt_data[i-1]);
<span class="keywordflow">if</span> ( (i % LINE_LEN) == 0) printf(<span class="stringliteral">"\n"</span>);
}
printf(<span class="stringliteral">"\n\n"</span>);
}
<span class="keywordflow">if</span> (res == -1)
{
printf(<span class="stringliteral">"Error reading the packets: %s\n"</span>, <a class="code" href="group__wpcapfunc.html#ga81305cb154e4497e95bbb9b708631a3a" title="return the error text pertaining to the last pcap library error.">pcap_geterr</a>(fp));
}
<span class="keywordflow">return</span> 0;
}
</pre></div><p><b>Writing packets to a dump file with pcap_live_dump</b></p>
<p><b>NOTE:</b> At the moment, due to some problems with the new kernel buffer, this feature has been disabled.</p>
<p>Recent versions of WinPcap provide a further way to save network traffic to disk, the <a class="el" href="group__wpcapfunc.html#gaedef54159d918b22a7de8e75b8a3ef4d" title="Save a capture to file.">pcap_live_dump()</a> function. <a class="el" href="group__wpcapfunc.html#gaedef54159d918b22a7de8e75b8a3ef4d" title="Save a capture to file.">pcap_live_dump()</a> takes three parameters: a file name, the maximum size (in bytes) that this file is allowed to reach and the maximum amount of packets that the file is allowed to contain. Zero means no limit for both these values. Notice that the program can set a filter (with <a class="el" href="group__wpcapfunc.html#gaf5f9cfe85dad0967ff607e5159b1ba61" title="Associate a filter to a capture.">pcap_setfilter()</a>, see the tutorial <a class="el" href="group__wpcap__tut5.html">Filtering the traffic</a>) before calling <a class="el" href="group__wpcapfunc.html#gaedef54159d918b22a7de8e75b8a3ef4d" title="Save a capture to file.">pcap_live_dump()</a> to define the subset of the traffic that will be saved.</p>
<p><a class="el" href="group__wpcapfunc.html#gaedef54159d918b22a7de8e75b8a3ef4d" title="Save a capture to file.">pcap_live_dump()</a> is non-blocking, therefore it starts the dump and returns immediately: The dump process goes on asynchronously until the maximum file size or the maximum amount of packets has been reached.</p>
<p>The application can wait or check the end of the dump with <a class="el" href="group__wpcapfunc.html#gafe8a334f3a7ae2dc7f52e96523da39be" title="Return the status of the kernel dump process, i.e. tells if one of the limits defined...">pcap_live_dump_ended()</a>. <b>Beware</b> that if the <em>sync</em> parameter is nonzero, this function will block your application forever if the limits are both 0.</p>
<div class="fragment"><pre class="fragment"><span class="comment">/*</span>
<span class="comment"> * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)</span>
<span class="comment"> * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California)</span>
<span class="comment"> * All rights reserved.</span>
<span class="comment"> *</span>
<span class="comment"> * Redistribution and use in source and binary forms, with or without</span>
<span class="comment"> * modification, are permitted provided that the following conditions</span>
<span class="comment"> * are met:</span>
<span class="comment"> *</span>
<span class="comment"> * 1. Redistributions of source code must retain the above copyright</span>
<span class="comment"> * notice, this list of conditions and the following disclaimer.</span>
<span class="comment"> * 2. Redistributions in binary form must reproduce the above copyright</span>
<span class="comment"> * notice, this list of conditions and the following disclaimer in the</span>
<span class="comment"> * documentation and/or other materials provided with the distribution.</span>
<span class="comment"> * 3. Neither the name of the Politecnico di Torino, CACE Technologies </span>
<span class="comment"> * nor the names of its contributors may be used to endorse or promote </span>
<span class="comment"> * products derived from this software without specific prior written </span>
<span class="comment"> * permission.</span>
<span class="comment"> *</span>
<span class="comment"> * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS</span>
<span class="comment"> * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT</span>
<span class="comment"> * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR</span>
<span class="comment"> * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT</span>
<span class="comment"> * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,</span>
<span class="comment"> * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT</span>
<span class="comment"> * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,</span>
<span class="comment"> * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY</span>
<span class="comment"> * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT</span>
<span class="comment"> * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE</span>
<span class="comment"> * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</span>
<span class="comment"> *</span>
<span class="comment"> */</span>
<span class="preprocessor">#include <stdlib.h></span>
<span class="preprocessor">#include <stdio.h></span>
<span class="preprocessor">#include <pcap.h></span>
<span class="preprocessor">#error At the moment the kernel dump feature is not supported in the driver</span>
<span class="preprocessor"></span>
main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> **argv) {
<a class="code" href="structpcap__if.html" title="Item in a list of interfaces, used by pcap_findalldevs().">pcap_if_t</a> *alldevs, *d;
<a class="code" href="group__wpcap__def.html#ga4711d025f83503ce692efa5e45ec60a7" title="Descriptor of an open capture instance. This structure is opaque to the user, that...">pcap_t</a> *fp;
u_int inum, i=0;
<span class="keywordtype">char</span> errbuf[<a class="code" href="group__wpcap__def.html#gacd448353957d92c98fccc29e1fc8d927" title="Size to use when allocating the buffer that contains the libpcap errors.">PCAP_ERRBUF_SIZE</a>];
printf(<span class="stringliteral">"kdump: saves the network traffic to file using WinPcap kernel-level dump faeature.\n"</span>);
printf(<span class="stringliteral">"\t Usage: %s [adapter] | dump_file_name max_size max_packs\n"</span>, argv[0]);
printf(<span class="stringliteral">"\t Where: max_size is the maximum size that the dump file will reach (0 means no limit)\n"</span>);
printf(<span class="stringliteral">"\t Where: max_packs is the maximum number of packets that will be saved (0 means no limit)\n\n"</span>);
<span class="keywordflow">if</span>(argc < 5){
<span class="comment">/* The user didn't provide a packet source: Retrieve the device list */</span>
<span class="keywordflow">if</span> (<a class="code" href="group__wpcapfunc.html#ga7b128eaeef627b408f6a6e2a2f5eb45d" title="Construct a list of network devices that can be opened with pcap_open_live().">pcap_findalldevs</a>(&alldevs, errbuf) == -1)
{
fprintf(stderr,<span class="stringliteral">"Error in pcap_findalldevs: %s\n"</span>, errbuf);
exit(1);
}
<span class="comment">/* Print the list */</span>
<span class="keywordflow">for</span>(d=alldevs; d; d=d-><a class="code" href="structpcap__if.html#a81508e6e4e41ca4235c8d6b51913c536" title="if not NULL, a pointer to the next element in the list; NULL for the last element...">next</a>)
{
printf(<span class="stringliteral">"%d. %s"</span>, ++i, d-><a class="code" href="structpcap__if.html#a5ac083a645d964373f022d03df4849c8" title="a pointer to a string giving a name for the device to pass to pcap_open_live()">name</a>);
<span class="keywordflow">if</span> (d-><a class="code" href="structpcap__if.html#a8444d6e0dfe2bbab0b5e7b24308f1559" title="if not NULL, a pointer to a string giving a human-readable description of the device...">description</a>)
printf(<span class="stringliteral">" (%s)\n"</span>, d-><a class="code" href="structpcap__if.html#a8444d6e0dfe2bbab0b5e7b24308f1559" title="if not NULL, a pointer to a string giving a human-readable description of the device...">description</a>);
<span class="keywordflow">else</span>
printf(<span class="stringliteral">" (No description available)\n"</span>);
}
<span class="keywordflow">if</span>(i==0)
{
printf(<span class="stringliteral">"\nNo interfaces found! Make sure WinPcap is installed.\n"</span>);
<span class="keywordflow">return</span> -1;
}
printf(<span class="stringliteral">"Enter the interface number (1-%d):"</span>,i);
scanf(<span class="stringliteral">"%d"</span>, &inum);
<span class="keywordflow">if</span>(inum < 1 || inum > i)
{
printf(<span class="stringliteral">"\nInterface number out of range.\n"</span>);
<span class="comment">/* Free the device list */</span>
<span class="keywordflow">return</span> -1;
}
<span class="comment">/* Jump to the selected adapter */</span>
<span class="keywordflow">for</span>(d=alldevs, i=0; i< inum-1 ;d=d-><a class="code" href="structpcap__if.html#a81508e6e4e41ca4235c8d6b51913c536" title="if not NULL, a pointer to the next element in the list; NULL for the last element...">next</a>, i++);
<span class="comment">/* Open the device */</span>
<span class="keywordflow">if</span> ( (fp = <a class="code" href="group__wpcapfunc.html#gaae6abe06e15c87b803f69773822beca8" title="Open a live capture from the network.">pcap_open_live</a>(d-><a class="code" href="structpcap__if.html#a5ac083a645d964373f022d03df4849c8" title="a pointer to a string giving a name for the device to pass to pcap_open_live()">name</a>, 100, 1, 20, errbuf) ) == NULL)
{
fprintf(stderr,<span class="stringliteral">"\nError opening adapter\n"</span>);
<span class="keywordflow">return</span> -1;
}
<span class="comment">/* Free the device list */</span>
<a class="code" href="group__wpcapfunc.html#ga346b4b0b7fd1cda4abb9a39f767dbeb1" title="Free an interface list returned by pcap_findalldevs().">pcap_freealldevs</a>(alldevs);
<span class="comment">/* Start the dump */</span>
<span class="keywordflow">if</span>(<a class="code" href="group__wpcapfunc.html#gaedef54159d918b22a7de8e75b8a3ef4d" title="Save a capture to file.">pcap_live_dump</a>(fp, argv[1], atoi(argv[2]), atoi(argv[3]))==-1){
printf(<span class="stringliteral">"Unable to start the dump, %s\n"</span>, <a class="code" href="group__wpcapfunc.html#ga81305cb154e4497e95bbb9b708631a3a" title="return the error text pertaining to the last pcap library error.">pcap_geterr</a>(fp));
<span class="keywordflow">return</span> -1;
}
}
<span class="keywordflow">else</span>{
<span class="comment">/* Open the device */</span>
<span class="keywordflow">if</span> ( (fp= <a class="code" href="group__wpcapfunc.html#gaae6abe06e15c87b803f69773822beca8" title="Open a live capture from the network.">pcap_open_live</a>(argv[1], 100, 1, 20, errbuf) ) == NULL)
{
fprintf(stderr,<span class="stringliteral">"\nError opening adapter\n"</span>);
<span class="keywordflow">return</span> -1;
}
<span class="comment">/* Start the dump */</span>
<span class="keywordflow">if</span>(<a class="code" href="group__wpcapfunc.html#gaedef54159d918b22a7de8e75b8a3ef4d" title="Save a capture to file.">pcap_live_dump</a>(fp, argv[0], atoi(argv[1]), atoi(argv[2]))==-1){
printf(<span class="stringliteral">"Unable to start the dump, %s\n"</span>, <a class="code" href="group__wpcapfunc.html#ga81305cb154e4497e95bbb9b708631a3a" title="return the error text pertaining to the last pcap library error.">pcap_geterr</a>(fp));
<span class="keywordflow">return</span> -1;
}
}
<span class="comment">/* Wait until the dump finishes, i.e. when max_size or max_packs is reached*/</span>
<a class="code" href="group__wpcapfunc.html#gafe8a334f3a7ae2dc7f52e96523da39be" title="Return the status of the kernel dump process, i.e. tells if one of the limits defined...">pcap_live_dump_ended</a>(fp, TRUE);
<span class="comment">/* Close the adapter, so that the file is correctly flushed */</span>
<a class="code" href="group__wpcapfunc.html#gaa45a5e1a4ba9925bb3586dcbeec78560" title="close the files associated with p and deallocates resources.">pcap_close</a>(fp);
<span class="keywordflow">return</span> 0;
}
</pre></div><p>The difference between <a class="el" href="group__wpcapfunc.html#gaedef54159d918b22a7de8e75b8a3ef4d" title="Save a capture to file.">pcap_live_dump()</a> and <a class="el" href="group__wpcapfunc.html#ga659439bf5aa3988b5a92d31990fbf437" title="Save a packet to disk.">pcap_dump()</a>, apart from the possibility to set limits, is performance. <a class="el" href="group__wpcapfunc.html#gaedef54159d918b22a7de8e75b8a3ef4d" title="Save a capture to file.">pcap_live_dump()</a> exploits the ability of the WinPcap NPF driver (see <a class="el" href="group__NPF.html">NPF driver internals manual</a>) to write dumps from kernel level, minimizing the number of context switches and memory copies.</p>
<p>Obviously, since this feature is currently not available on other operating systems, <a class="el" href="group__wpcapfunc.html#gaedef54159d918b22a7de8e75b8a3ef4d" title="Save a capture to file.">pcap_live_dump()</a> is WinPcap specific and is present only under Win32.</p>
<p><a class="el" href="group__wpcap__tut6.html"><<< Previous</a> <a class="el" href="group__wpcap__tut8.html">Next >>></a> </p>
</div>
<hr>
<p align="right"><img border="0" src="winpcap_small.gif" align="absbottom" width="91" height="27">
documentation. Copyright (c) 2002-2005 Politecnico di Torino. Copyright (c) 2005-2009
CACE Technologies. All rights reserved.</p>
|