savefile.c revision 1.7 1 1.7 christos /* $NetBSD: savefile.c,v 1.7 2023/08/17 15:18:12 christos Exp $ */
2 1.2 christos
3 1.1 christos /*
4 1.1 christos * Copyright (c) 1993, 1994, 1995, 1996, 1997
5 1.1 christos * The Regents of the University of California. All rights reserved.
6 1.1 christos *
7 1.1 christos * Redistribution and use in source and binary forms, with or without
8 1.1 christos * modification, are permitted provided that: (1) source code distributions
9 1.1 christos * retain the above copyright notice and this paragraph in its entirety, (2)
10 1.1 christos * distributions including binary code include the above copyright notice and
11 1.1 christos * this paragraph in its entirety in the documentation or other materials
12 1.1 christos * provided with the distribution, and (3) all advertising materials mentioning
13 1.1 christos * features or use of this software display the following acknowledgement:
14 1.1 christos * ``This product includes software developed by the University of California,
15 1.1 christos * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16 1.1 christos * the University nor the names of its contributors may be used to endorse
17 1.1 christos * or promote products derived from this software without specific prior
18 1.1 christos * written permission.
19 1.1 christos * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20 1.1 christos * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21 1.1 christos * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 1.1 christos *
23 1.1 christos * savefile.c - supports offline use of tcpdump
24 1.1 christos * Extraction/creation by Jeffrey Mogul, DECWRL
25 1.1 christos * Modified by Steve McCanne, LBL.
26 1.1 christos *
27 1.1 christos * Used to save the received packet headers, after filtering, to
28 1.1 christos * a file, and then read them later.
29 1.1 christos * The first record in the file contains saved values for the machine
30 1.1 christos * dependent values so we can print the dump file on any architecture.
31 1.1 christos */
32 1.1 christos
33 1.2 christos #include <sys/cdefs.h>
34 1.7 christos __RCSID("$NetBSD: savefile.c,v 1.7 2023/08/17 15:18:12 christos Exp $");
35 1.1 christos
36 1.1 christos #ifdef HAVE_CONFIG_H
37 1.5 christos #include <config.h>
38 1.1 christos #endif
39 1.1 christos
40 1.5 christos #include <pcap-types.h>
41 1.4 christos #ifdef _WIN32
42 1.5 christos #include <io.h>
43 1.5 christos #include <fcntl.h>
44 1.4 christos #endif /* _WIN32 */
45 1.1 christos
46 1.1 christos #include <errno.h>
47 1.1 christos #include <memory.h>
48 1.1 christos #include <stdio.h>
49 1.1 christos #include <stdlib.h>
50 1.1 christos #include <string.h>
51 1.6 christos #include <limits.h> /* for INT_MAX */
52 1.1 christos
53 1.1 christos #include "pcap-int.h"
54 1.1 christos
55 1.1 christos #ifdef HAVE_OS_PROTO_H
56 1.1 christos #include "os-proto.h"
57 1.1 christos #endif
58 1.1 christos
59 1.1 christos #include "sf-pcap.h"
60 1.5 christos #include "sf-pcapng.h"
61 1.6 christos #include "pcap-common.h"
62 1.7 christos #include "charconv.h"
63 1.1 christos
64 1.4 christos #ifdef _WIN32
65 1.4 christos /*
66 1.7 christos * This isn't exported on Windows, because it would only work if both
67 1.6 christos * WinPcap/Npcap and the code using it were to use the Universal CRT; otherwise,
68 1.6 christos * a FILE structure in WinPcap/Npcap and a FILE structure in the code using it
69 1.4 christos * could be different if they're using different versions of the C runtime.
70 1.4 christos *
71 1.7 christos * Instead, pcap/pcap.h defines it as a macro that wraps the hopen version,
72 1.7 christos * with the wrapper calling _fileno() and _get_osfhandle() themselves,
73 1.7 christos * so that it convert the appropriate CRT version's FILE structure to
74 1.4 christos * a HANDLE (which is OS-defined, not CRT-defined, and is part of the Win32
75 1.4 christos * and Win64 ABIs).
76 1.4 christos */
77 1.4 christos static pcap_t *pcap_fopen_offline_with_tstamp_precision(FILE *, u_int, char *);
78 1.4 christos #endif
79 1.4 christos
80 1.1 christos /*
81 1.1 christos * Setting O_BINARY on DOS/Windows is a bit tricky
82 1.1 christos */
83 1.4 christos #if defined(_WIN32)
84 1.1 christos #define SET_BINMODE(f) _setmode(_fileno(f), _O_BINARY)
85 1.1 christos #elif defined(MSDOS)
86 1.1 christos #if defined(__HIGHC__)
87 1.1 christos #define SET_BINMODE(f) setmode(f, O_BINARY)
88 1.1 christos #else
89 1.1 christos #define SET_BINMODE(f) setmode(fileno(f), O_BINARY)
90 1.1 christos #endif
91 1.1 christos #endif
92 1.1 christos
93 1.1 christos static int
94 1.5 christos sf_getnonblock(pcap_t *p _U_)
95 1.1 christos {
96 1.1 christos /*
97 1.1 christos * This is a savefile, not a live capture file, so never say
98 1.1 christos * it's in non-blocking mode.
99 1.1 christos */
100 1.1 christos return (0);
101 1.1 christos }
102 1.1 christos
103 1.1 christos static int
104 1.5 christos sf_setnonblock(pcap_t *p, int nonblock _U_)
105 1.1 christos {
106 1.1 christos /*
107 1.2 christos * This is a savefile, not a live capture file, so reject
108 1.2 christos * requests to put it in non-blocking mode. (If it's a
109 1.2 christos * pipe, it could be put in non-blocking mode, but that
110 1.2 christos * would significantly complicate the code to read packets,
111 1.2 christos * as it would have to handle reading partial packets and
112 1.2 christos * keeping the state of the read.)
113 1.1 christos */
114 1.7 christos snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
115 1.2 christos "Savefiles cannot be put into non-blocking mode");
116 1.2 christos return (-1);
117 1.1 christos }
118 1.1 christos
119 1.1 christos static int
120 1.7 christos sf_cant_set_rfmon(pcap_t *p _U_)
121 1.7 christos {
122 1.7 christos /*
123 1.7 christos * This is a savefile, not a device on which you can capture,
124 1.7 christos * so never say it supports being put into monitor mode.
125 1.7 christos */
126 1.7 christos return (0);
127 1.7 christos }
128 1.7 christos
129 1.7 christos static int
130 1.5 christos sf_stats(pcap_t *p, struct pcap_stat *ps _U_)
131 1.1 christos {
132 1.7 christos snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
133 1.1 christos "Statistics aren't available from savefiles");
134 1.1 christos return (-1);
135 1.1 christos }
136 1.1 christos
137 1.4 christos #ifdef _WIN32
138 1.4 christos static struct pcap_stat *
139 1.7 christos sf_stats_ex(pcap_t *p, int *size _U_)
140 1.4 christos {
141 1.7 christos snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
142 1.4 christos "Statistics aren't available from savefiles");
143 1.4 christos return (NULL);
144 1.4 christos }
145 1.4 christos
146 1.1 christos static int
147 1.7 christos sf_setbuff(pcap_t *p, int dim _U_)
148 1.1 christos {
149 1.7 christos snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
150 1.1 christos "The kernel buffer size cannot be set while reading from a file");
151 1.1 christos return (-1);
152 1.1 christos }
153 1.1 christos
154 1.1 christos static int
155 1.7 christos sf_setmode(pcap_t *p, int mode _U_)
156 1.1 christos {
157 1.7 christos snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
158 1.1 christos "impossible to set mode while reading from a file");
159 1.1 christos return (-1);
160 1.1 christos }
161 1.1 christos
162 1.1 christos static int
163 1.7 christos sf_setmintocopy(pcap_t *p, int size _U_)
164 1.1 christos {
165 1.7 christos snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
166 1.1 christos "The mintocopy parameter cannot be set while reading from a file");
167 1.1 christos return (-1);
168 1.1 christos }
169 1.4 christos
170 1.4 christos static HANDLE
171 1.4 christos sf_getevent(pcap_t *pcap)
172 1.4 christos {
173 1.7 christos (void)snprintf(pcap->errbuf, sizeof(pcap->errbuf),
174 1.4 christos "The read event cannot be retrieved while reading from a file");
175 1.4 christos return (INVALID_HANDLE_VALUE);
176 1.4 christos }
177 1.4 christos
178 1.4 christos static int
179 1.4 christos sf_oid_get_request(pcap_t *p, bpf_u_int32 oid _U_, void *data _U_,
180 1.4 christos size_t *lenp _U_)
181 1.4 christos {
182 1.7 christos snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
183 1.4 christos "An OID get request cannot be performed on a file");
184 1.4 christos return (PCAP_ERROR);
185 1.4 christos }
186 1.4 christos
187 1.4 christos static int
188 1.4 christos sf_oid_set_request(pcap_t *p, bpf_u_int32 oid _U_, const void *data _U_,
189 1.4 christos size_t *lenp _U_)
190 1.4 christos {
191 1.7 christos snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
192 1.4 christos "An OID set request cannot be performed on a file");
193 1.4 christos return (PCAP_ERROR);
194 1.4 christos }
195 1.4 christos
196 1.4 christos static u_int
197 1.7 christos sf_sendqueue_transmit(pcap_t *p, pcap_send_queue *queue _U_, int sync _U_)
198 1.4 christos {
199 1.6 christos pcap_strlcpy(p->errbuf, "Sending packets isn't supported on savefiles",
200 1.4 christos PCAP_ERRBUF_SIZE);
201 1.4 christos return (0);
202 1.4 christos }
203 1.4 christos
204 1.4 christos static int
205 1.7 christos sf_setuserbuffer(pcap_t *p, int size _U_)
206 1.4 christos {
207 1.7 christos snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
208 1.4 christos "The user buffer cannot be set when reading from a file");
209 1.4 christos return (-1);
210 1.4 christos }
211 1.4 christos
212 1.4 christos static int
213 1.7 christos sf_live_dump(pcap_t *p, char *filename _U_, int maxsize _U_, int maxpacks _U_)
214 1.4 christos {
215 1.7 christos snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
216 1.4 christos "Live packet dumping cannot be performed when reading from a file");
217 1.4 christos return (-1);
218 1.4 christos }
219 1.4 christos
220 1.4 christos static int
221 1.7 christos sf_live_dump_ended(pcap_t *p, int sync _U_)
222 1.4 christos {
223 1.7 christos snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
224 1.4 christos "Live packet dumping cannot be performed on a pcap_open_dead pcap_t");
225 1.4 christos return (-1);
226 1.4 christos }
227 1.4 christos
228 1.4 christos static PAirpcapHandle
229 1.7 christos sf_get_airpcap_handle(pcap_t *pcap _U_)
230 1.4 christos {
231 1.4 christos return (NULL);
232 1.4 christos }
233 1.1 christos #endif
234 1.1 christos
235 1.1 christos static int
236 1.1 christos sf_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
237 1.1 christos {
238 1.6 christos pcap_strlcpy(p->errbuf, "Sending packets isn't supported on savefiles",
239 1.1 christos PCAP_ERRBUF_SIZE);
240 1.1 christos return (-1);
241 1.1 christos }
242 1.1 christos
243 1.1 christos /*
244 1.1 christos * Set direction flag: Which packets do we accept on a forwarding
245 1.1 christos * single device? IN, OUT or both?
246 1.1 christos */
247 1.1 christos static int
248 1.5 christos sf_setdirection(pcap_t *p, pcap_direction_t d _U_)
249 1.1 christos {
250 1.7 christos snprintf(p->errbuf, sizeof(p->errbuf),
251 1.1 christos "Setting direction is not supported on savefiles");
252 1.1 christos return (-1);
253 1.1 christos }
254 1.1 christos
255 1.2 christos void
256 1.1 christos sf_cleanup(pcap_t *p)
257 1.1 christos {
258 1.2 christos if (p->rfile != stdin)
259 1.2 christos (void)fclose(p->rfile);
260 1.1 christos if (p->buffer != NULL)
261 1.1 christos free(p->buffer);
262 1.2 christos pcap_freecode(&p->fcode);
263 1.1 christos }
264 1.1 christos
265 1.7 christos #ifdef _WIN32
266 1.7 christos /*
267 1.7 christos * Wrapper for fopen() and _wfopen().
268 1.7 christos *
269 1.7 christos * If we're in UTF-8 mode, map the pathname from UTF-8 to UTF-16LE and
270 1.7 christos * call _wfopen().
271 1.7 christos *
272 1.7 christos * If we're not, just use fopen(); that'll treat it as being in the
273 1.7 christos * local code page.
274 1.7 christos */
275 1.7 christos FILE *
276 1.7 christos charset_fopen(const char *path, const char *mode)
277 1.7 christos {
278 1.7 christos wchar_t *utf16_path;
279 1.7 christos #define MAX_MODE_LEN 16
280 1.7 christos wchar_t utf16_mode[MAX_MODE_LEN+1];
281 1.7 christos int i;
282 1.7 christos char c;
283 1.7 christos FILE *fp;
284 1.7 christos int save_errno;
285 1.7 christos
286 1.7 christos if (pcap_utf_8_mode) {
287 1.7 christos /*
288 1.7 christos * Map from UTF-8 to UTF-16LE.
289 1.7 christos * Fail if there are invalid characters in the input
290 1.7 christos * string, rather than converting them to REPLACEMENT
291 1.7 christos * CHARACTER; the latter is appropriate for strings
292 1.7 christos * to be displayed to the user, but for file names
293 1.7 christos * you just want the attempt to open the file to fail.
294 1.7 christos */
295 1.7 christos utf16_path = cp_to_utf_16le(CP_UTF8, path,
296 1.7 christos MB_ERR_INVALID_CHARS);
297 1.7 christos if (utf16_path == NULL) {
298 1.7 christos /*
299 1.7 christos * Error. Assume errno has been set.
300 1.7 christos *
301 1.7 christos * XXX - what about Windows errors?
302 1.7 christos */
303 1.7 christos return (NULL);
304 1.7 christos }
305 1.7 christos
306 1.7 christos /*
307 1.7 christos * Now convert the mode to UTF-16LE as well.
308 1.7 christos * We assume the mode is ASCII, and that
309 1.7 christos * it's short, so that's easy.
310 1.7 christos */
311 1.7 christos for (i = 0; (c = *mode) != '\0'; i++, mode++) {
312 1.7 christos if (c > 0x7F) {
313 1.7 christos /* Not an ASCII character; fail with EINVAL. */
314 1.7 christos free(utf16_path);
315 1.7 christos errno = EINVAL;
316 1.7 christos return (NULL);
317 1.7 christos }
318 1.7 christos if (i >= MAX_MODE_LEN) {
319 1.7 christos /* The mode string is longer than we allow. */
320 1.7 christos free(utf16_path);
321 1.7 christos errno = EINVAL;
322 1.7 christos return (NULL);
323 1.7 christos }
324 1.7 christos utf16_mode[i] = c;
325 1.7 christos }
326 1.7 christos utf16_mode[i] = '\0';
327 1.7 christos
328 1.7 christos /*
329 1.7 christos * OK, we have UTF-16LE strings; hand them to
330 1.7 christos * _wfopen().
331 1.7 christos */
332 1.7 christos fp = _wfopen(utf16_path, utf16_mode);
333 1.7 christos
334 1.7 christos /*
335 1.7 christos * Make sure freeing the UTF-16LE string doesn't
336 1.7 christos * overwrite the error code we got from _wfopen().
337 1.7 christos */
338 1.7 christos save_errno = errno;
339 1.7 christos free(utf16_path);
340 1.7 christos errno = save_errno;
341 1.7 christos
342 1.7 christos return (fp);
343 1.7 christos } else {
344 1.7 christos /*
345 1.7 christos * This takes strings in the local code page as an
346 1.7 christos * argument.
347 1.7 christos */
348 1.7 christos return (fopen(path, mode));
349 1.7 christos }
350 1.7 christos }
351 1.7 christos #endif
352 1.7 christos
353 1.1 christos pcap_t *
354 1.2 christos pcap_open_offline_with_tstamp_precision(const char *fname, u_int precision,
355 1.4 christos char *errbuf)
356 1.1 christos {
357 1.1 christos FILE *fp;
358 1.1 christos pcap_t *p;
359 1.1 christos
360 1.4 christos if (fname == NULL) {
361 1.7 christos snprintf(errbuf, PCAP_ERRBUF_SIZE,
362 1.4 christos "A null pointer was supplied as the file name");
363 1.4 christos return (NULL);
364 1.4 christos }
365 1.1 christos if (fname[0] == '-' && fname[1] == '\0')
366 1.1 christos {
367 1.1 christos fp = stdin;
368 1.7 christos if (fp == NULL) {
369 1.7 christos snprintf(errbuf, PCAP_ERRBUF_SIZE,
370 1.7 christos "The standard input is not open");
371 1.7 christos return (NULL);
372 1.7 christos }
373 1.4 christos #if defined(_WIN32) || defined(MSDOS)
374 1.1 christos /*
375 1.1 christos * We're reading from the standard input, so put it in binary
376 1.1 christos * mode, as savefiles are binary files.
377 1.1 christos */
378 1.1 christos SET_BINMODE(fp);
379 1.1 christos #endif
380 1.1 christos }
381 1.1 christos else {
382 1.5 christos /*
383 1.7 christos * Use charset_fopen(); on Windows, it tests whether we're
384 1.7 christos * in "local code page" or "UTF-8" mode, and treats the
385 1.7 christos * pathname appropriately, and on other platforms, it just
386 1.7 christos * wraps fopen().
387 1.7 christos *
388 1.5 christos * "b" is supported as of C90, so *all* UN*Xes should
389 1.7 christos * support it, even though it does nothing. For MS-DOS,
390 1.7 christos * we again need it.
391 1.5 christos */
392 1.7 christos fp = charset_fopen(fname, "rb");
393 1.1 christos if (fp == NULL) {
394 1.5 christos pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
395 1.5 christos errno, "%s", fname);
396 1.1 christos return (NULL);
397 1.1 christos }
398 1.1 christos }
399 1.2 christos p = pcap_fopen_offline_with_tstamp_precision(fp, precision, errbuf);
400 1.1 christos if (p == NULL) {
401 1.1 christos if (fp != stdin)
402 1.1 christos fclose(fp);
403 1.1 christos }
404 1.1 christos return (p);
405 1.1 christos }
406 1.1 christos
407 1.2 christos pcap_t *
408 1.2 christos pcap_open_offline(const char *fname, char *errbuf)
409 1.2 christos {
410 1.2 christos return (pcap_open_offline_with_tstamp_precision(fname,
411 1.2 christos PCAP_TSTAMP_PRECISION_MICRO, errbuf));
412 1.2 christos }
413 1.2 christos
414 1.4 christos #ifdef _WIN32
415 1.2 christos pcap_t* pcap_hopen_offline_with_tstamp_precision(intptr_t osfd, u_int precision,
416 1.2 christos char *errbuf)
417 1.1 christos {
418 1.1 christos int fd;
419 1.1 christos FILE *file;
420 1.1 christos
421 1.1 christos fd = _open_osfhandle(osfd, _O_RDONLY);
422 1.3 christos if ( fd < 0 )
423 1.1 christos {
424 1.5 christos pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
425 1.5 christos errno, "_open_osfhandle");
426 1.1 christos return NULL;
427 1.1 christos }
428 1.1 christos
429 1.1 christos file = _fdopen(fd, "rb");
430 1.3 christos if ( file == NULL )
431 1.1 christos {
432 1.5 christos pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
433 1.5 christos errno, "_fdopen");
434 1.6 christos _close(fd);
435 1.1 christos return NULL;
436 1.1 christos }
437 1.1 christos
438 1.2 christos return pcap_fopen_offline_with_tstamp_precision(file, precision,
439 1.2 christos errbuf);
440 1.2 christos }
441 1.2 christos
442 1.2 christos pcap_t* pcap_hopen_offline(intptr_t osfd, char *errbuf)
443 1.2 christos {
444 1.2 christos return pcap_hopen_offline_with_tstamp_precision(osfd,
445 1.2 christos PCAP_TSTAMP_PRECISION_MICRO, errbuf);
446 1.1 christos }
447 1.1 christos #endif
448 1.1 christos
449 1.6 christos /*
450 1.6 christos * Given a link-layer header type and snapshot length, return a
451 1.6 christos * snapshot length to use when reading the file; it's guaranteed
452 1.6 christos * to be > 0 and <= INT_MAX.
453 1.6 christos *
454 1.6 christos * XXX - the only reason why we limit it to <= INT_MAX is so that
455 1.6 christos * it fits in p->snapshot, and the only reason that p->snapshot is
456 1.6 christos * signed is that pcap_snapshot() returns an int, not an unsigned int.
457 1.6 christos */
458 1.6 christos bpf_u_int32
459 1.6 christos pcap_adjust_snapshot(bpf_u_int32 linktype, bpf_u_int32 snaplen)
460 1.6 christos {
461 1.6 christos if (snaplen == 0 || snaplen > INT_MAX) {
462 1.6 christos /*
463 1.6 christos * Bogus snapshot length; use the maximum for this
464 1.6 christos * link-layer type as a fallback.
465 1.6 christos *
466 1.6 christos * XXX - we don't clamp snapshot lengths that are
467 1.6 christos * <= INT_MAX but > max_snaplen_for_dlt(linktype),
468 1.6 christos * so a capture file could cause us to allocate
469 1.6 christos * a Really Big Buffer.
470 1.6 christos */
471 1.6 christos snaplen = max_snaplen_for_dlt(linktype);
472 1.6 christos }
473 1.6 christos return snaplen;
474 1.6 christos }
475 1.6 christos
476 1.6 christos static pcap_t *(*check_headers[])(const uint8_t *, FILE *, u_int, char *, int *) = {
477 1.1 christos pcap_check_header,
478 1.1 christos pcap_ng_check_header
479 1.1 christos };
480 1.1 christos
481 1.1 christos #define N_FILE_TYPES (sizeof check_headers / sizeof check_headers[0])
482 1.1 christos
483 1.4 christos #ifdef _WIN32
484 1.1 christos static
485 1.1 christos #endif
486 1.1 christos pcap_t *
487 1.2 christos pcap_fopen_offline_with_tstamp_precision(FILE *fp, u_int precision,
488 1.2 christos char *errbuf)
489 1.1 christos {
490 1.1 christos register pcap_t *p;
491 1.6 christos uint8_t magic[4];
492 1.1 christos size_t amt_read;
493 1.1 christos u_int i;
494 1.2 christos int err;
495 1.1 christos
496 1.1 christos /*
497 1.7 christos * Fail if we were passed a NULL fp.
498 1.7 christos *
499 1.7 christos * That shouldn't happen if we're opening with a path name, but
500 1.7 christos * it could happen if buggy code is opening with a FILE * and
501 1.7 christos * didn't bother to make sure the FILE * isn't null.
502 1.7 christos */
503 1.7 christos if (fp == NULL) {
504 1.7 christos snprintf(errbuf, PCAP_ERRBUF_SIZE,
505 1.7 christos "Null FILE * pointer provided to savefile open routine");
506 1.7 christos return (NULL);
507 1.7 christos }
508 1.7 christos
509 1.7 christos /*
510 1.1 christos * Read the first 4 bytes of the file; the network analyzer dump
511 1.5 christos * file formats we support (pcap and pcapng), and several other
512 1.1 christos * formats we might support in the future (such as snoop, DOS and
513 1.1 christos * Windows Sniffer, and Microsoft Network Monitor) all have magic
514 1.1 christos * numbers that are unique in their first 4 bytes.
515 1.1 christos */
516 1.6 christos amt_read = fread(&magic, 1, sizeof(magic), fp);
517 1.1 christos if (amt_read != sizeof(magic)) {
518 1.1 christos if (ferror(fp)) {
519 1.5 christos pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
520 1.5 christos errno, "error reading dump file");
521 1.1 christos } else {
522 1.7 christos snprintf(errbuf, PCAP_ERRBUF_SIZE,
523 1.7 christos "truncated dump file; tried to read %zu file header bytes, only got %zu",
524 1.6 christos sizeof(magic), amt_read);
525 1.1 christos }
526 1.2 christos return (NULL);
527 1.1 christos }
528 1.1 christos
529 1.1 christos /*
530 1.1 christos * Try all file types.
531 1.1 christos */
532 1.1 christos for (i = 0; i < N_FILE_TYPES; i++) {
533 1.2 christos p = (*check_headers[i])(magic, fp, precision, errbuf, &err);
534 1.2 christos if (p != NULL) {
535 1.2 christos /* Yup, that's it. */
536 1.2 christos goto found;
537 1.2 christos }
538 1.2 christos if (err) {
539 1.1 christos /*
540 1.1 christos * Error trying to read the header.
541 1.1 christos */
542 1.2 christos return (NULL);
543 1.1 christos }
544 1.1 christos }
545 1.1 christos
546 1.1 christos /*
547 1.1 christos * Well, who knows what this mess is....
548 1.1 christos */
549 1.7 christos snprintf(errbuf, PCAP_ERRBUF_SIZE, "unknown file format");
550 1.2 christos return (NULL);
551 1.1 christos
552 1.1 christos found:
553 1.2 christos p->rfile = fp;
554 1.1 christos
555 1.1 christos /* Padding only needed for live capture fcode */
556 1.1 christos p->fddipad = 0;
557 1.1 christos
558 1.4 christos #if !defined(_WIN32) && !defined(MSDOS)
559 1.1 christos /*
560 1.1 christos * You can do "select()" and "poll()" on plain files on most
561 1.1 christos * platforms, and should be able to do so on pipes.
562 1.1 christos *
563 1.1 christos * You can't do "select()" on anything other than sockets in
564 1.1 christos * Windows, so, on Win32 systems, we don't have "selectable_fd".
565 1.1 christos */
566 1.1 christos p->selectable_fd = fileno(fp);
567 1.1 christos #endif
568 1.1 christos
569 1.7 christos p->can_set_rfmon_op = sf_cant_set_rfmon;
570 1.1 christos p->read_op = pcap_offline_read;
571 1.1 christos p->inject_op = sf_inject;
572 1.1 christos p->setfilter_op = install_bpf_program;
573 1.1 christos p->setdirection_op = sf_setdirection;
574 1.1 christos p->set_datalink_op = NULL; /* we don't support munging link-layer headers */
575 1.1 christos p->getnonblock_op = sf_getnonblock;
576 1.1 christos p->setnonblock_op = sf_setnonblock;
577 1.1 christos p->stats_op = sf_stats;
578 1.4 christos #ifdef _WIN32
579 1.4 christos p->stats_ex_op = sf_stats_ex;
580 1.1 christos p->setbuff_op = sf_setbuff;
581 1.1 christos p->setmode_op = sf_setmode;
582 1.1 christos p->setmintocopy_op = sf_setmintocopy;
583 1.4 christos p->getevent_op = sf_getevent;
584 1.4 christos p->oid_get_request_op = sf_oid_get_request;
585 1.4 christos p->oid_set_request_op = sf_oid_set_request;
586 1.4 christos p->sendqueue_transmit_op = sf_sendqueue_transmit;
587 1.4 christos p->setuserbuffer_op = sf_setuserbuffer;
588 1.4 christos p->live_dump_op = sf_live_dump;
589 1.4 christos p->live_dump_ended_op = sf_live_dump_ended;
590 1.4 christos p->get_airpcap_handle_op = sf_get_airpcap_handle;
591 1.1 christos #endif
592 1.2 christos
593 1.2 christos /*
594 1.2 christos * For offline captures, the standard one-shot callback can
595 1.2 christos * be used for pcap_next()/pcap_next_ex().
596 1.2 christos */
597 1.2 christos p->oneshot_callback = pcap_oneshot;
598 1.2 christos
599 1.3 christos /*
600 1.7 christos * Default breakloop operation.
601 1.7 christos */
602 1.7 christos p->breakloop_op = pcap_breakloop_common;
603 1.7 christos
604 1.7 christos /*
605 1.3 christos * Savefiles never require special BPF code generation.
606 1.3 christos */
607 1.3 christos p->bpf_codegen_flags = 0;
608 1.3 christos
609 1.1 christos p->activated = 1;
610 1.1 christos
611 1.1 christos return (p);
612 1.2 christos }
613 1.2 christos
614 1.7 christos /*
615 1.7 christos * This isn't needed on Windows; we #define pcap_fopen_offline() as
616 1.7 christos * a wrapper around pcap_hopen_offline(), and we don't call it from
617 1.7 christos * inside this file, so it's unused.
618 1.7 christos */
619 1.7 christos #ifndef _WIN32
620 1.2 christos pcap_t *
621 1.2 christos pcap_fopen_offline(FILE *fp, char *errbuf)
622 1.2 christos {
623 1.2 christos return (pcap_fopen_offline_with_tstamp_precision(fp,
624 1.2 christos PCAP_TSTAMP_PRECISION_MICRO, errbuf));
625 1.1 christos }
626 1.7 christos #endif
627 1.1 christos
628 1.1 christos /*
629 1.1 christos * Read packets from a capture file, and call the callback for each
630 1.1 christos * packet.
631 1.1 christos * If cnt > 0, return after 'cnt' packets, otherwise continue until eof.
632 1.1 christos */
633 1.1 christos int
634 1.1 christos pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
635 1.1 christos {
636 1.1 christos struct bpf_insn *fcode;
637 1.1 christos int n = 0;
638 1.1 christos u_char *data;
639 1.1 christos
640 1.7 christos /*
641 1.7 christos * This can conceivably process more than INT_MAX packets,
642 1.7 christos * which would overflow the packet count, causing it either
643 1.7 christos * to look like a negative number, and thus cause us to
644 1.7 christos * return a value that looks like an error, or overflow
645 1.7 christos * back into positive territory, and thus cause us to
646 1.7 christos * return a too-low count.
647 1.7 christos *
648 1.7 christos * Therefore, if the packet count is unlimited, we clip
649 1.7 christos * it at INT_MAX; this routine is not expected to
650 1.7 christos * process packets indefinitely, so that's not an issue.
651 1.7 christos */
652 1.7 christos if (PACKET_COUNT_IS_UNLIMITED(cnt))
653 1.7 christos cnt = INT_MAX;
654 1.7 christos
655 1.7 christos for (;;) {
656 1.1 christos struct pcap_pkthdr h;
657 1.7 christos int status;
658 1.1 christos
659 1.1 christos /*
660 1.1 christos * Has "pcap_breakloop()" been called?
661 1.1 christos * If so, return immediately - if we haven't read any
662 1.1 christos * packets, clear the flag and return -2 to indicate
663 1.1 christos * that we were told to break out of the loop, otherwise
664 1.1 christos * leave the flag set, so that the *next* call will break
665 1.1 christos * out of the loop without having read any packets, and
666 1.1 christos * return the number of packets we've processed so far.
667 1.1 christos */
668 1.1 christos if (p->break_loop) {
669 1.1 christos if (n == 0) {
670 1.1 christos p->break_loop = 0;
671 1.1 christos return (-2);
672 1.1 christos } else
673 1.1 christos return (n);
674 1.1 christos }
675 1.1 christos
676 1.2 christos status = p->next_packet_op(p, &h, &data);
677 1.7 christos if (status < 0) {
678 1.7 christos /*
679 1.7 christos * Error. Pass it back to the caller.
680 1.7 christos */
681 1.1 christos return (status);
682 1.1 christos }
683 1.7 christos if (status == 0) {
684 1.7 christos /*
685 1.7 christos * EOF. Nothing more to process;
686 1.7 christos */
687 1.7 christos break;
688 1.7 christos }
689 1.1 christos
690 1.7 christos /*
691 1.7 christos * OK, we've read a packet; run it through the filter
692 1.7 christos * and, if it passes, process it.
693 1.7 christos */
694 1.1 christos if ((fcode = p->fcode.bf_insns) == NULL ||
695 1.7 christos pcap_filter(fcode, data, h.len, h.caplen)) {
696 1.1 christos (*callback)(user, &h, data);
697 1.7 christos n++; /* count the packet */
698 1.7 christos if (n >= cnt)
699 1.1 christos break;
700 1.1 christos }
701 1.1 christos }
702 1.1 christos /*XXX this breaks semantics tcpslice expects */
703 1.1 christos return (n);
704 1.1 christos }
705