]> The Tcpdump Group git mirrors - libpcap/blob - sf-pcap.c
CI: Call print_so_deps() on rpcapd in remote enabled build
[libpcap] / sf-pcap.c
1 /*
2 * Copyright (c) 1993, 1994, 1995, 1996, 1997
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
16 * written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 * sf-pcap.c - libpcap-file-format-specific code from savefile.c
22 * Extraction/creation by Jeffrey Mogul, DECWRL
23 * Modified by Steve McCanne, LBL.
24 *
25 * Used to save the received packet headers, after filtering, to
26 * a file, and then read them later.
27 * The first record in the file contains saved values for the machine
28 * dependent values so we can print the dump file on any architecture.
29 */
30
31 #include <config.h>
32
33 #include <pcap-types.h>
34 #ifdef _WIN32
35 #include <io.h>
36 #include <fcntl.h>
37 #endif /* _WIN32 */
38
39 #include <errno.h>
40 #include <memory.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <limits.h> /* for INT_MAX */
45
46 #include "pcap-int.h"
47 #include "pcap-util.h"
48
49 #include "pcap-common.h"
50
51 #ifdef HAVE_OS_PROTO_H
52 #include "os-proto.h"
53 #endif
54
55 #include "sf-pcap.h"
56
57 /*
58 * Setting O_BINARY on Windows is a bit tricky.
59 */
60 #if defined(_WIN32)
61 #define SET_BINMODE(f) _setmode(_fileno(f), _O_BINARY)
62 #endif
63
64 /*
65 * Standard libpcap format.
66 *
67 * The same value is used in the rpcap protocol as an indication of
68 * the server byte order, to let the client know whether it needs to
69 * byte-swap some host-byte-order metadata.
70 */
71 #define TCPDUMP_MAGIC 0xa1b2c3d4
72
73 /*
74 * Alexey Kuznetzov's modified libpcap format.
75 */
76 #define KUZNETZOV_TCPDUMP_MAGIC 0xa1b2cd34
77
78 /*
79 * Reserved for Francisco Mesquita <francisco.mesquita@radiomovel.pt>
80 * for another modified format.
81 */
82 #define FMESQUITA_TCPDUMP_MAGIC 0xa1b234cd
83
84 /*
85 * Navtel Communications' format, with nanosecond timestamps,
86 * as per a request from Dumas Hwang <dumas.hwang@navtelcom.com>.
87 */
88 #define NAVTEL_TCPDUMP_MAGIC 0xa12b3c4d
89
90 /*
91 * Normal libpcap format, except for seconds/nanoseconds timestamps,
92 * as per a request by Ulf Lamping <ulf.lamping@web.de>
93 */
94 #define NSEC_TCPDUMP_MAGIC 0xa1b23c4d
95
96 /*
97 * Used for identification of cbpf-savefile(5).
98 */
99 #define CBPF_SAVEFILE_MAGIC 0xa1b2c3cb
100
101 /*
102 * This is a timeval as stored in a savefile.
103 * It has to use the same types everywhere, independent of the actual
104 * `struct timeval'; `struct timeval' has 32-bit tv_sec values on some
105 * platforms and 64-bit tv_sec values on other platforms, and writing
106 * out native `struct timeval' values would mean files could only be
107 * read on systems with the same tv_sec size as the system on which
108 * the file was written.
109 *
110 * The fields are unsigned, as that's what the pcap draft specification
111 * says they are. (That gives pcap a 68-year Y2.038K reprieve, although
112 * in 2106 it runs out for good. pcapng doesn't have that problem,
113 * unless you pick a *really* high time stamp precision.)
114 */
115
116 struct pcap_timeval {
117 bpf_u_int32 tv_sec; /* seconds */
118 bpf_u_int32 tv_usec; /* microseconds */
119 };
120
121 /*
122 * This is a `pcap_pkthdr' as actually stored in a savefile.
123 *
124 * Do not change the format of this structure, in any way (this includes
125 * changes that only affect the length of fields in this structure),
126 * and do not make the time stamp anything other than seconds and
127 * microseconds (e.g., seconds and nanoseconds). Instead:
128 *
129 * introduce a new structure for the new format;
130 *
131 * send mail to "tcpdump-workers@lists.tcpdump.org", requesting
132 * a new magic number for your new capture file format, and, when
133 * you get the new magic number, put it in "savefile.c";
134 *
135 * use that magic number for save files with the changed record
136 * header;
137 *
138 * make the code in "savefile.c" capable of reading files with
139 * the old record header as well as files with the new record header
140 * (using the magic number to determine the header format).
141 *
142 * Then supply the changes by forking the branch at
143 *
144 * https://github.com/the-tcpdump-group/libpcap/tree/master
145 *
146 * and issuing a pull request, so that future versions of libpcap and
147 * programs that use it (such as tcpdump) will be able to read your new
148 * capture file format.
149 */
150
151 struct pcap_sf_pkthdr {
152 struct pcap_timeval ts; /* time stamp */
153 bpf_u_int32 caplen; /* length of portion present */
154 bpf_u_int32 len; /* length of this packet (off wire) */
155 };
156
157 /*
158 * How a `pcap_pkthdr' is actually stored in savefiles written
159 * by some patched versions of libpcap (e.g. the ones in Red
160 * Hat Linux 6.1 and 6.2).
161 *
162 * Do not change the format of this structure, in any way (this includes
163 * changes that only affect the length of fields in this structure).
164 * Instead, introduce a new structure, as per the above.
165 */
166
167 struct pcap_sf_patched_pkthdr {
168 struct pcap_timeval ts; /* time stamp */
169 bpf_u_int32 caplen; /* length of portion present */
170 bpf_u_int32 len; /* length of this packet (off wire) */
171 int index;
172 unsigned short protocol;
173 unsigned char pkt_type;
174 };
175
176 static int pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **datap);
177
178 #ifdef _WIN32
179 /*
180 * This isn't exported on Windows, because it would only work if both
181 * libpcap and the code using it were using the same C runtime; otherwise they
182 * would be using different definitions of a FILE structure.
183 *
184 * Instead we define this as a macro in pcap/pcap.h that wraps the hopen
185 * version that we do export, passing it a raw OS HANDLE, as defined by the
186 * Win32 / Win64 ABI, obtained from the _fileno() and _get_osfhandle()
187 * functions of the appropriate CRT.
188 */
189 static pcap_dumper_t *pcap_dump_fopen(pcap_t *p, FILE *f);
190 #endif /* _WIN32 */
191
192 /*
193 * Private data for reading pcap savefiles.
194 */
195 typedef enum {
196 NOT_SWAPPED,
197 SWAPPED,
198 MAYBE_SWAPPED
199 } swapped_type_t;
200
201 typedef enum {
202 PASS_THROUGH,
203 SCALE_UP,
204 SCALE_DOWN
205 } tstamp_scale_type_t;
206
207 struct pcap_sf {
208 size_t hdrsize;
209 swapped_type_t lengths_swapped;
210 tstamp_scale_type_t scale_type;
211 };
212
213 /*
214 * Check whether this is a pcap savefile and, if it is, extract the
215 * relevant information from the header.
216 */
217 pcap_t *
218 pcap_check_header(const uint8_t *magic, FILE *fp, u_int precision, char *errbuf,
219 int *err)
220 {
221 bpf_u_int32 magic_int;
222 struct pcap_file_header hdr;
223 size_t amt_read;
224 pcap_t *p;
225 int swapped = 0;
226 struct pcap_sf *ps;
227
228 /*
229 * Assume no read errors.
230 */
231 *err = 0;
232
233 /*
234 * Check whether the first 4 bytes of the file are the magic
235 * number for a pcap savefile, or for a byte-swapped pcap
236 * savefile.
237 */
238 memcpy(&magic_int, magic, sizeof(magic_int));
239 if (magic_int != TCPDUMP_MAGIC &&
240 magic_int != KUZNETZOV_TCPDUMP_MAGIC &&
241 magic_int != NSEC_TCPDUMP_MAGIC) {
242 magic_int = SWAPLONG(magic_int);
243 if (magic_int != TCPDUMP_MAGIC &&
244 magic_int != KUZNETZOV_TCPDUMP_MAGIC &&
245 magic_int != NSEC_TCPDUMP_MAGIC)
246 return (NULL); /* nope */
247 swapped = 1;
248 }
249
250 /*
251 * They are. Put the magic number in the header, and read
252 * the rest of the header.
253 */
254 hdr.magic = magic_int;
255 amt_read = fread(((char *)&hdr) + sizeof hdr.magic, 1,
256 sizeof(hdr) - sizeof(hdr.magic), fp);
257 if (amt_read != sizeof(hdr) - sizeof(hdr.magic)) {
258 if (ferror(fp)) {
259 pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
260 errno, "error reading dump file");
261 } else {
262 snprintf(errbuf, PCAP_ERRBUF_SIZE,
263 "truncated dump file; tried to read %zu file header bytes, only got %zu",
264 sizeof(hdr), amt_read);
265 }
266 *err = 1;
267 return (NULL);
268 }
269
270 /*
271 * If it's a byte-swapped capture file, byte-swap the header.
272 */
273 if (swapped) {
274 hdr.version_major = SWAPSHORT(hdr.version_major);
275 hdr.version_minor = SWAPSHORT(hdr.version_minor);
276 hdr.thiszone = SWAPLONG(hdr.thiszone);
277 hdr.sigfigs = SWAPLONG(hdr.sigfigs);
278 hdr.snaplen = SWAPLONG(hdr.snaplen);
279 hdr.linktype = SWAPLONG(hdr.linktype);
280 }
281
282 if (hdr.version_major < PCAP_VERSION_MAJOR) {
283 snprintf(errbuf, PCAP_ERRBUF_SIZE,
284 "archaic pcap savefile format");
285 *err = 1;
286 return (NULL);
287 }
288
289 /*
290 * currently only versions 2.[0-4] are supported with
291 * the exception of 543.0 for DG/UX tcpdump.
292 */
293 if (! ((hdr.version_major == PCAP_VERSION_MAJOR &&
294 hdr.version_minor <= PCAP_VERSION_MINOR) ||
295 (hdr.version_major == 543 &&
296 hdr.version_minor == 0))) {
297 snprintf(errbuf, PCAP_ERRBUF_SIZE,
298 "unsupported pcap savefile version %u.%u",
299 hdr.version_major, hdr.version_minor);
300 *err = 1;
301 return NULL;
302 }
303
304 /*
305 * Check the main reserved field.
306 */
307 if (LT_RESERVED1(hdr.linktype) != 0) {
308 snprintf(errbuf, PCAP_ERRBUF_SIZE,
309 "savefile linktype reserved field not zero (0x%08x)",
310 LT_RESERVED1(hdr.linktype));
311 *err = 1;
312 return NULL;
313 }
314
315 /*
316 * OK, this is a good pcap file.
317 * Allocate a pcap_t for it.
318 */
319 p = PCAP_OPEN_OFFLINE_COMMON(errbuf, struct pcap_sf);
320 if (p == NULL) {
321 /* Allocation failed. */
322 *err = 1;
323 return (NULL);
324 }
325 p->swapped = swapped;
326 p->version_major = hdr.version_major;
327 p->version_minor = hdr.version_minor;
328 p->linktype = linktype_to_dlt(LT_LINKTYPE(hdr.linktype));
329 p->linktype_ext = LT_LINKTYPE_EXT(hdr.linktype);
330 p->snapshot = pcapint_adjust_snapshot(p->linktype, hdr.snaplen);
331
332 p->next_packet_op = pcap_next_packet;
333
334 ps = p->priv;
335
336 p->opt.tstamp_precision = precision;
337
338 /*
339 * Will we need to scale the timestamps to match what the
340 * user wants?
341 */
342 switch (precision) {
343
344 case PCAP_TSTAMP_PRECISION_MICRO:
345 if (magic_int == NSEC_TCPDUMP_MAGIC) {
346 /*
347 * The file has nanoseconds, the user
348 * wants microseconds; scale the
349 * precision down.
350 */
351 ps->scale_type = SCALE_DOWN;
352 } else {
353 /*
354 * The file has microseconds, the
355 * user wants microseconds; nothing to do.
356 */
357 ps->scale_type = PASS_THROUGH;
358 }
359 break;
360
361 case PCAP_TSTAMP_PRECISION_NANO:
362 if (magic_int == NSEC_TCPDUMP_MAGIC) {
363 /*
364 * The file has nanoseconds, the
365 * user wants nanoseconds; nothing to do.
366 */
367 ps->scale_type = PASS_THROUGH;
368 } else {
369 /*
370 * The file has microseconds, the user
371 * wants nanoseconds; scale the
372 * precision up.
373 */
374 ps->scale_type = SCALE_UP;
375 }
376 break;
377
378 default:
379 snprintf(errbuf, PCAP_ERRBUF_SIZE,
380 "unknown time stamp resolution %u", precision);
381 free(p);
382 *err = 1;
383 return (NULL);
384 }
385
386 /*
387 * We interchanged the caplen and len fields at version 2.3,
388 * in order to match the bpf header layout. But unfortunately
389 * some files were written with version 2.3 in their headers
390 * but without the interchanged fields.
391 *
392 * In addition, DG/UX tcpdump writes out files with a version
393 * number of 543.0, and with the caplen and len fields in the
394 * pre-2.3 order.
395 */
396 switch (hdr.version_major) {
397
398 case 2:
399 if (hdr.version_minor < 3)
400 ps->lengths_swapped = SWAPPED;
401 else if (hdr.version_minor == 3)
402 ps->lengths_swapped = MAYBE_SWAPPED;
403 else
404 ps->lengths_swapped = NOT_SWAPPED;
405 break;
406
407 case 543:
408 ps->lengths_swapped = SWAPPED;
409 break;
410
411 default:
412 ps->lengths_swapped = NOT_SWAPPED;
413 break;
414 }
415
416 if (magic_int == KUZNETZOV_TCPDUMP_MAGIC) {
417 /*
418 * XXX - the patch that's in some versions of libpcap
419 * changes the packet header but not the magic number,
420 * and some other versions with this magic number have
421 * some extra debugging information in the packet header;
422 * we'd have to use some hacks^H^H^H^H^Hheuristics to
423 * detect those variants.
424 *
425 * Ethereal does that, but it does so by trying to read
426 * the first two packets of the file with each of the
427 * record header formats. That currently means it seeks
428 * backwards and retries the reads, which doesn't work
429 * on pipes. We want to be able to read from a pipe, so
430 * that strategy won't work; we'd have to buffer some
431 * data ourselves and read from that buffer in order to
432 * make that work.
433 */
434 ps->hdrsize = sizeof(struct pcap_sf_patched_pkthdr);
435
436 if (p->linktype == DLT_EN10MB) {
437 /*
438 * This capture might have been done in raw mode
439 * or cooked mode.
440 *
441 * If it was done in cooked mode, p->snapshot was
442 * passed to recvfrom() as the buffer size, meaning
443 * that the most packet data that would be copied
444 * would be p->snapshot. However, a faked Ethernet
445 * header would then have been added to it, so the
446 * most data that would be in a packet in the file
447 * would be p->snapshot + 14.
448 *
449 * We can't easily tell whether the capture was done
450 * in raw mode or cooked mode, so we'll assume it was
451 * cooked mode, and add 14 to the snapshot length.
452 * That means that, for a raw capture, the snapshot
453 * length will be misleading if you use it to figure
454 * out why a capture doesn't have all the packet data,
455 * but there's not much we can do to avoid that.
456 *
457 * But don't grow the snapshot length past the
458 * maximum value of an int.
459 */
460 if (p->snapshot <= INT_MAX - 14)
461 p->snapshot += 14;
462 else
463 p->snapshot = INT_MAX;
464 }
465 } else
466 ps->hdrsize = sizeof(struct pcap_sf_pkthdr);
467
468 /*
469 * Allocate a buffer for the packet data.
470 * Choose the minimum of the file's snapshot length and 2K bytes;
471 * that should be enough for most network packets - we'll grow it
472 * if necessary. That way, we don't allocate a huge chunk of
473 * memory just because there's a huge snapshot length, as the
474 * snapshot length might be larger than the size of the largest
475 * packet.
476 */
477 p->bufsize = p->snapshot;
478 if (p->bufsize > 2048)
479 p->bufsize = 2048;
480 p->buffer = malloc(p->bufsize);
481 if (p->buffer == NULL) {
482 snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory");
483 free(p);
484 *err = 1;
485 return (NULL);
486 }
487
488 p->cleanup_op = pcapint_sf_cleanup;
489
490 return (p);
491 }
492
493 /*
494 * Grow the packet buffer to the specified size.
495 */
496 static int
497 grow_buffer(pcap_t *p, u_int bufsize)
498 {
499 void *bigger_buffer;
500
501 bigger_buffer = realloc(p->buffer, bufsize);
502 if (bigger_buffer == NULL) {
503 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "out of memory");
504 return (0);
505 }
506 p->buffer = bigger_buffer;
507 p->bufsize = bufsize;
508 return (1);
509 }
510
511 /*
512 * Read and return the next packet from the savefile. Return the header
513 * in hdr and a pointer to the contents in data. Return 1 on success, 0
514 * if there were no more packets, and -1 on an error.
515 */
516 static int
517 pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
518 {
519 struct pcap_sf *ps = p->priv;
520 struct pcap_sf_patched_pkthdr sf_hdr;
521 FILE *fp = p->rfile;
522 size_t amt_read;
523 bpf_u_int32 t;
524
525 /*
526 * Read the packet header; the structure we use as a buffer
527 * is the longer structure for files generated by the patched
528 * libpcap, but if the file has the magic number for an
529 * unpatched libpcap we only read as many bytes as the regular
530 * header has.
531 */
532 amt_read = fread(&sf_hdr, 1, ps->hdrsize, fp);
533 if (amt_read != ps->hdrsize) {
534 if (ferror(fp)) {
535 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
536 errno, "error reading dump file");
537 return (-1);
538 } else {
539 if (amt_read != 0) {
540 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
541 "truncated dump file; tried to read %zu header bytes, only got %zu",
542 ps->hdrsize, amt_read);
543 return (-1);
544 }
545 /* EOF */
546 return (0);
547 }
548 }
549
550 if (p->swapped) {
551 /* these were written in opposite byte order */
552 hdr->caplen = SWAPLONG(sf_hdr.caplen);
553 hdr->len = SWAPLONG(sf_hdr.len);
554 hdr->ts.tv_sec = SWAPLONG(sf_hdr.ts.tv_sec);
555 hdr->ts.tv_usec = SWAPLONG(sf_hdr.ts.tv_usec);
556 } else {
557 hdr->caplen = sf_hdr.caplen;
558 hdr->len = sf_hdr.len;
559 hdr->ts.tv_sec = sf_hdr.ts.tv_sec;
560 hdr->ts.tv_usec = sf_hdr.ts.tv_usec;
561 }
562
563 switch (ps->scale_type) {
564
565 case PASS_THROUGH:
566 /*
567 * Just pass the time stamp through.
568 */
569 break;
570
571 case SCALE_UP:
572 /*
573 * File has microseconds, user wants nanoseconds; convert
574 * it.
575 */
576 hdr->ts.tv_usec = hdr->ts.tv_usec * 1000;
577 break;
578
579 case SCALE_DOWN:
580 /*
581 * File has nanoseconds, user wants microseconds; convert
582 * it.
583 */
584 hdr->ts.tv_usec = hdr->ts.tv_usec / 1000;
585 break;
586 }
587
588 /* Swap the caplen and len fields, if necessary. */
589 switch (ps->lengths_swapped) {
590
591 case NOT_SWAPPED:
592 break;
593
594 case MAYBE_SWAPPED:
595 if (hdr->caplen <= hdr->len) {
596 /*
597 * The captured length is <= the actual length,
598 * so presumably they weren't swapped.
599 */
600 break;
601 }
602 /* FALLTHROUGH */
603
604 case SWAPPED:
605 t = hdr->caplen;
606 hdr->caplen = hdr->len;
607 hdr->len = t;
608 break;
609 }
610
611 /*
612 * Is the packet bigger than we consider sane?
613 */
614 if (hdr->caplen > max_snaplen_for_dlt(p->linktype)) {
615 /*
616 * Yes. This may be a damaged or fuzzed file.
617 *
618 * Is it bigger than the snapshot length?
619 * (We don't treat that as an error if it's not
620 * bigger than the maximum we consider sane; see
621 * below.)
622 */
623 if (hdr->caplen > (bpf_u_int32)p->snapshot) {
624 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
625 "invalid packet capture length %u, bigger than "
626 "snaplen of %d", hdr->caplen, p->snapshot);
627 } else {
628 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
629 "invalid packet capture length %u, bigger than "
630 "maximum of %u", hdr->caplen,
631 max_snaplen_for_dlt(p->linktype));
632 }
633 return (-1);
634 }
635
636 if (hdr->caplen > (bpf_u_int32)p->snapshot) {
637 /*
638 * The packet is bigger than the snapshot length
639 * for this file.
640 *
641 * This can happen due to Solaris 2.3 systems tripping
642 * over the BUFMOD problem and not setting the snapshot
643 * length correctly in the savefile header.
644 *
645 * libpcap 0.4 and later on Solaris 2.3 should set the
646 * snapshot length correctly in the pcap file header,
647 * even though they don't set a snapshot length in bufmod
648 * (the buggy bufmod chops off the *beginning* of the
649 * packet if a snapshot length is specified); they should
650 * also reduce the captured length, as supplied to the
651 * per-packet callback, to the snapshot length if it's
652 * greater than the snapshot length, so the code using
653 * libpcap should see the packet cut off at the snapshot
654 * length, even though the full packet is copied up to
655 * userland.
656 *
657 * However, perhaps some versions of libpcap failed to
658 * set the snapshot length correctly in the file header
659 * or the per-packet header, or perhaps this is a
660 * corrupted savefile or a savefile built/modified by a
661 * fuzz tester, so we check anyway. We grow the buffer
662 * to be big enough for the snapshot length, read up
663 * to the snapshot length, discard the rest of the
664 * packet, and report the snapshot length as the captured
665 * length; we don't want to hand our caller a packet
666 * bigger than the snapshot length, because they might
667 * be assuming they'll never be handed such a packet,
668 * and might copy the packet into a snapshot-length-
669 * sized buffer, assuming it'll fit.
670 */
671 size_t bytes_to_discard;
672 size_t bytes_to_read, bytes_read;
673 char discard_buf[4096];
674
675 if (hdr->caplen > p->bufsize) {
676 /*
677 * Grow the buffer to the snapshot length.
678 */
679 if (!grow_buffer(p, p->snapshot))
680 return (-1);
681 }
682
683 /*
684 * Read the first p->snapshot bytes into the buffer.
685 */
686 amt_read = fread(p->buffer, 1, p->snapshot, fp);
687 if (amt_read != (bpf_u_int32)p->snapshot) {
688 if (ferror(fp)) {
689 pcapint_fmt_errmsg_for_errno(p->errbuf,
690 PCAP_ERRBUF_SIZE, errno,
691 "error reading dump file");
692 } else {
693 /*
694 * Yes, this uses hdr->caplen; technically,
695 * it's true, because we would try to read
696 * and discard the rest of those bytes, and
697 * that would fail because we got EOF before
698 * the read finished.
699 */
700 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
701 "truncated dump file; tried to read %d captured bytes, only got %zu",
702 p->snapshot, amt_read);
703 }
704 return (-1);
705 }
706
707 /*
708 * Now read and discard what's left.
709 */
710 bytes_to_discard = hdr->caplen - p->snapshot;
711 bytes_read = amt_read;
712 while (bytes_to_discard != 0) {
713 bytes_to_read = bytes_to_discard;
714 if (bytes_to_read > sizeof (discard_buf))
715 bytes_to_read = sizeof (discard_buf);
716 amt_read = fread(discard_buf, 1, bytes_to_read, fp);
717 bytes_read += amt_read;
718 if (amt_read != bytes_to_read) {
719 if (ferror(fp)) {
720 pcapint_fmt_errmsg_for_errno(p->errbuf,
721 PCAP_ERRBUF_SIZE, errno,
722 "error reading dump file");
723 } else {
724 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
725 "truncated dump file; tried to read %u captured bytes, only got %zu",
726 hdr->caplen, bytes_read);
727 }
728 return (-1);
729 }
730 bytes_to_discard -= amt_read;
731 }
732
733 /*
734 * Adjust caplen accordingly, so we don't get confused later
735 * as to how many bytes we have to play with.
736 */
737 hdr->caplen = p->snapshot;
738 } else {
739 /*
740 * The packet is within the snapshot length for this file.
741 */
742 if (hdr->caplen > p->bufsize) {
743 /*
744 * Grow the buffer to the next power of 2, or
745 * the snaplen, whichever is lower.
746 */
747 u_int new_bufsize;
748
749 new_bufsize = hdr->caplen;
750 /*
751 * https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
752 */
753 new_bufsize--;
754 new_bufsize |= new_bufsize >> 1;
755 new_bufsize |= new_bufsize >> 2;
756 new_bufsize |= new_bufsize >> 4;
757 new_bufsize |= new_bufsize >> 8;
758 new_bufsize |= new_bufsize >> 16;
759 new_bufsize++;
760
761 if (new_bufsize > (u_int)p->snapshot)
762 new_bufsize = p->snapshot;
763
764 if (!grow_buffer(p, new_bufsize))
765 return (-1);
766 }
767
768 /* read the packet itself */
769 amt_read = fread(p->buffer, 1, hdr->caplen, fp);
770 if (amt_read != hdr->caplen) {
771 if (ferror(fp)) {
772 pcapint_fmt_errmsg_for_errno(p->errbuf,
773 PCAP_ERRBUF_SIZE, errno,
774 "error reading dump file");
775 } else {
776 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
777 "truncated dump file; tried to read %u captured bytes, only got %zu",
778 hdr->caplen, amt_read);
779 }
780 return (-1);
781 }
782 }
783 *data = p->buffer;
784
785 pcapint_post_process(p->linktype, p->swapped, hdr, *data);
786
787 return (1);
788 }
789
790 static int
791 sf_write_header(pcap_t *p, FILE *fp, int linktype, int snaplen)
792 {
793 struct pcap_file_header hdr;
794
795 hdr.magic = p->opt.tstamp_precision == PCAP_TSTAMP_PRECISION_NANO ? NSEC_TCPDUMP_MAGIC : TCPDUMP_MAGIC;
796 hdr.version_major = PCAP_VERSION_MAJOR;
797 hdr.version_minor = PCAP_VERSION_MINOR;
798
799 /*
800 * https://www.tcpdump.org/manpages/pcap-savefile.5.txt states:
801 * thiszone (Reserved1): 4-byte not used - SHOULD be filled with 0
802 * sigfigs (Reserved2): 4-byte not used - SHOULD be filled with 0
803 */
804 hdr.thiszone = 0;
805 hdr.sigfigs = 0;
806 hdr.snaplen = snaplen;
807 hdr.linktype = linktype;
808
809 if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1)
810 return (-1);
811
812 return (0);
813 }
814
815 /*
816 * Output a packet to the initialized dump file.
817 */
818 void
819 pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
820 {
821 register FILE *f;
822 struct pcap_sf_pkthdr sf_hdr;
823
824 f = (FILE *)user;
825 /*
826 * If the output file handle is in an error state, don't write
827 * anything.
828 *
829 * While in principle a file handle can return from an error state
830 * to a normal state (for example if a disk that is full has space
831 * freed), we have possibly left a broken file already, and won't
832 * be able to clean it up. The safest option is to do nothing.
833 *
834 * Note that if we could guarantee that fwrite() was atomic we
835 * might be able to insure that we don't produce a corrupted file,
836 * but the standard defines fwrite() as a series of fputc() calls,
837 * so we really have no insurance that things are not fubared.
838 *
839 * http://pubs.opengroup.org/onlinepubs/009695399/functions/fwrite.html
840 */
841 if (ferror(f))
842 return;
843 /*
844 * Better not try writing pcap files after
845 * 2106-02-07 06:28:15 UTC; switch to pcapng.
846 * (And better not try writing pcap files with time stamps
847 * that predate 1970-01-01 00:00:00 UTC; that's not supported.
848 * You could try using pcapng with the if_tsoffset field in
849 * the IDB for the interface(s) with packets with those time
850 * stamps, but you may also have to get a link-layer type for
851 * IBM Bisync or whatever link layer even older forms
852 * of computer communication used.)
853 */
854 sf_hdr.ts.tv_sec = (bpf_u_int32)h->ts.tv_sec;
855 sf_hdr.ts.tv_usec = (bpf_u_int32)h->ts.tv_usec;
856 sf_hdr.caplen = h->caplen;
857 sf_hdr.len = h->len;
858 /*
859 * We only write the packet if we can write the header properly.
860 *
861 * This doesn't prevent us from having corrupted output, and if we
862 * for some reason don't get a complete write we don't have any
863 * way to set ferror() to prevent future writes from being
864 * attempted, but it is better than nothing.
865 */
866 if (fwrite(&sf_hdr, sizeof(sf_hdr), 1, f) == 1) {
867 (void)fwrite(sp, h->caplen, 1, f);
868 }
869 }
870
871 static pcap_dumper_t *
872 pcap_setup_dump(pcap_t *p, int linktype, FILE *f, const char *fname)
873 {
874
875 #if defined(_WIN32)
876 /*
877 * If we're writing to the standard output, put it in binary
878 * mode, as savefiles are binary files.
879 *
880 * Otherwise, we turn off buffering.
881 * XXX - why? And why not on the standard output?
882 */
883 if (f == stdout)
884 SET_BINMODE(f);
885 else
886 setvbuf(f, NULL, _IONBF, 0);
887 #endif
888 if (sf_write_header(p, f, linktype, p->snapshot) == -1) {
889 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
890 errno, "Can't write to %s", fname);
891 if (f != stdout)
892 (void)fclose(f);
893 return (NULL);
894 }
895 return ((pcap_dumper_t *)f);
896 }
897
898 /*
899 * Initialize so that sf_write() will output to the file named 'fname'.
900 */
901 pcap_dumper_t *
902 pcap_dump_open(pcap_t *p, const char *fname)
903 {
904 FILE *f;
905 int linktype;
906
907 /*
908 * If this pcap_t hasn't been activated, it doesn't have a
909 * link-layer type, so we can't use it.
910 */
911 if (!p->activated) {
912 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
913 "%s: not-yet-activated pcap_t passed to pcap_dump_open",
914 fname);
915 return (NULL);
916 }
917 linktype = dlt_to_linktype(p->linktype);
918 if (linktype == -1) {
919 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
920 "%s: link-layer type %d isn't supported in savefiles",
921 fname, p->linktype);
922 return (NULL);
923 }
924 linktype |= p->linktype_ext;
925
926 if (fname == NULL) {
927 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
928 "A null pointer was supplied as the file name");
929 return NULL;
930 }
931 if (fname[0] == '-' && fname[1] == '\0') {
932 f = stdout;
933 fname = "standard output";
934 } else {
935 /*
936 * "b" is supported as of C90, so *all* UN*Xes should
937 * support it, even though it does nothing. It's
938 * required on Windows, as the file is a binary file
939 * and must be written in binary mode.
940 */
941 f = pcapint_charset_fopen(fname, "wb");
942 if (f == NULL) {
943 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
944 errno, "%s", fname);
945 return (NULL);
946 }
947 }
948 return (pcap_setup_dump(p, linktype, f, fname));
949 }
950
951 #ifdef _WIN32
952 /*
953 * Initialize so that sf_write() will output to a stream wrapping the given raw
954 * OS file HANDLE.
955 */
956 pcap_dumper_t *
957 pcap_dump_hopen(pcap_t *p, intptr_t osfd)
958 {
959 int fd;
960 FILE *file;
961
962 fd = _open_osfhandle(osfd, _O_APPEND);
963 if (fd < 0) {
964 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
965 errno, "_open_osfhandle");
966 return NULL;
967 }
968
969 file = _fdopen(fd, "wb");
970 if (file == NULL) {
971 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
972 errno, "_fdopen");
973 _close(fd);
974 return NULL;
975 }
976
977 return pcap_dump_fopen(p, file);
978 }
979 #endif /* _WIN32 */
980
981 /*
982 * Initialize so that sf_write() will output to the given stream.
983 */
984 #ifdef _WIN32
985 static
986 #endif /* _WIN32 */
987 pcap_dumper_t *
988 pcap_dump_fopen(pcap_t *p, FILE *f)
989 {
990 int linktype;
991
992 linktype = dlt_to_linktype(p->linktype);
993 if (linktype == -1) {
994 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
995 "stream: link-layer type %d isn't supported in savefiles",
996 p->linktype);
997 return (NULL);
998 }
999 linktype |= p->linktype_ext;
1000
1001 return (pcap_setup_dump(p, linktype, f, "stream"));
1002 }
1003
1004 pcap_dumper_t *
1005 pcap_dump_open_append(pcap_t *p, const char *fname)
1006 {
1007 FILE *f;
1008 int linktype;
1009 size_t amt_read;
1010 struct pcap_file_header ph;
1011
1012 linktype = dlt_to_linktype(p->linktype);
1013 if (linktype == -1) {
1014 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1015 "%s: link-layer type %d isn't supported in savefiles",
1016 fname, linktype);
1017 return (NULL);
1018 }
1019
1020 if (fname == NULL) {
1021 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1022 "A null pointer was supplied as the file name");
1023 return NULL;
1024 }
1025 if (fname[0] == '-' && fname[1] == '\0')
1026 return (pcap_setup_dump(p, linktype, stdout, "standard output"));
1027
1028 /*
1029 * "a" will cause the file *not* to be truncated if it exists
1030 * but will cause it to be created if it doesn't. It will
1031 * also cause all writes to be done at the end of the file,
1032 * but will allow reads to be done anywhere in the file. This
1033 * is what we need, because we need to read from the beginning
1034 * of the file to see if it already has a header and packets
1035 * or if it doesn't.
1036 *
1037 * "b" is supported as of C90, so *all* UN*Xes should support it,
1038 * even though it does nothing. It's required on Windows, as the
1039 * file is a binary file and must be read in binary mode.
1040 */
1041 f = pcapint_charset_fopen(fname, "ab+");
1042 if (f == NULL) {
1043 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
1044 errno, "%s", fname);
1045 return (NULL);
1046 }
1047
1048 /*
1049 * Try to read a pcap header.
1050 *
1051 * We do not assume that the file will be positioned at the
1052 * beginning immediately after we've opened it - we seek to
1053 * the beginning. ISO C says it's implementation-defined
1054 * whether the file position indicator is at the beginning
1055 * or the end of the file after an append-mode open, and
1056 * it wasn't obvious from the Single UNIX Specification
1057 * or the Microsoft documentation how that works on SUS-
1058 * compliant systems or on Windows.
1059 */
1060 if (fseek(f, 0, SEEK_SET) == -1) {
1061 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
1062 errno, "Can't seek to the beginning of %s", fname);
1063 (void)fclose(f);
1064 return (NULL);
1065 }
1066 amt_read = fread(&ph, 1, sizeof (ph), f);
1067 if (amt_read != sizeof (ph)) {
1068 if (ferror(f)) {
1069 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
1070 errno, "%s", fname);
1071 (void)fclose(f);
1072 return (NULL);
1073 } else if (feof(f) && amt_read > 0) {
1074 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1075 "%s: truncated pcap file header", fname);
1076 (void)fclose(f);
1077 return (NULL);
1078 }
1079 }
1080
1081 #if defined(_WIN32)
1082 /*
1083 * We turn off buffering.
1084 * XXX - why? And why not on the standard output?
1085 */
1086 setvbuf(f, NULL, _IONBF, 0);
1087 #endif
1088
1089 /*
1090 * If a header is already present and:
1091 *
1092 * it's not for a pcap file of the appropriate resolution
1093 * and the right byte order for this machine;
1094 *
1095 * the link-layer header types don't match;
1096 *
1097 * the snapshot lengths don't match;
1098 *
1099 * return an error.
1100 */
1101 if (amt_read > 0) {
1102 /*
1103 * A header is already present.
1104 * Do the checks.
1105 */
1106 switch (ph.magic) {
1107
1108 case TCPDUMP_MAGIC:
1109 if (p->opt.tstamp_precision != PCAP_TSTAMP_PRECISION_MICRO) {
1110 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1111 "%s: different time stamp precision, cannot append to file", fname);
1112 (void)fclose(f);
1113 return (NULL);
1114 }
1115 break;
1116
1117 case NSEC_TCPDUMP_MAGIC:
1118 if (p->opt.tstamp_precision != PCAP_TSTAMP_PRECISION_NANO) {
1119 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1120 "%s: different time stamp precision, cannot append to file", fname);
1121 (void)fclose(f);
1122 return (NULL);
1123 }
1124 break;
1125
1126 case SWAPLONG(TCPDUMP_MAGIC):
1127 case SWAPLONG(NSEC_TCPDUMP_MAGIC):
1128 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1129 "%s: different byte order, cannot append to file", fname);
1130 (void)fclose(f);
1131 return (NULL);
1132
1133 case KUZNETZOV_TCPDUMP_MAGIC:
1134 case SWAPLONG(KUZNETZOV_TCPDUMP_MAGIC):
1135 case NAVTEL_TCPDUMP_MAGIC:
1136 case SWAPLONG(NAVTEL_TCPDUMP_MAGIC):
1137 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1138 "%s: not a pcap file to which we can append", fname);
1139 (void)fclose(f);
1140 return (NULL);
1141
1142 default:
1143 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1144 "%s: not a pcap file", fname);
1145 (void)fclose(f);
1146 return (NULL);
1147 }
1148
1149 /*
1150 * Good version?
1151 */
1152 if (ph.version_major != PCAP_VERSION_MAJOR ||
1153 ph.version_minor != PCAP_VERSION_MINOR) {
1154 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1155 "%s: version is %u.%u, cannot append to file", fname,
1156 ph.version_major, ph.version_minor);
1157 (void)fclose(f);
1158 return (NULL);
1159 }
1160 if ((bpf_u_int32)linktype != ph.linktype) {
1161 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1162 "%s: different linktype, cannot append to file", fname);
1163 (void)fclose(f);
1164 return (NULL);
1165 }
1166 if ((bpf_u_int32)p->snapshot != ph.snaplen) {
1167 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
1168 "%s: different snaplen, cannot append to file", fname);
1169 (void)fclose(f);
1170 return (NULL);
1171 }
1172 } else {
1173 /*
1174 * A header isn't present; attempt to write it.
1175 */
1176 if (sf_write_header(p, f, linktype, p->snapshot) == -1) {
1177 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
1178 errno, "Can't write to %s", fname);
1179 (void)fclose(f);
1180 return (NULL);
1181 }
1182 }
1183
1184 /*
1185 * Start writing at the end of the file.
1186 *
1187 * XXX - this shouldn't be necessary, given that we're opening
1188 * the file in append mode, and ISO C specifies that all writes
1189 * are done at the end of the file in that mode.
1190 */
1191 if (fseek(f, 0, SEEK_END) == -1) {
1192 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
1193 errno, "Can't seek to the end of %s", fname);
1194 (void)fclose(f);
1195 return (NULL);
1196 }
1197 return ((pcap_dumper_t *)f);
1198 }
1199
1200 FILE *
1201 pcap_dump_file(pcap_dumper_t *p)
1202 {
1203 return ((FILE *)p);
1204 }
1205
1206 long
1207 pcap_dump_ftell(pcap_dumper_t *p)
1208 {
1209 return (ftell((FILE *)p));
1210 }
1211
1212 #if defined(HAVE_FSEEKO)
1213 /*
1214 * We have fseeko(), so we have ftello().
1215 * If we have large file support (files larger than 2^31-1 bytes),
1216 * ftello() will give us a current file position with more than 32
1217 * bits.
1218 */
1219 int64_t
1220 pcap_dump_ftell64(pcap_dumper_t *p)
1221 {
1222 return (ftello((FILE *)p));
1223 }
1224 #elif defined(_MSC_VER)
1225 /*
1226 * We have Visual Studio; we support only 2015 and later, so we have
1227 * _ftelli64().
1228 */
1229 int64_t
1230 pcap_dump_ftell64(pcap_dumper_t *p)
1231 {
1232 return (_ftelli64((FILE *)p));
1233 }
1234 #else
1235 /*
1236 * We don't have ftello() or _ftelli64(), so fall back on ftell().
1237 * Either long is 64 bits, in which case ftell() should suffice,
1238 * or this is probably an older 32-bit UN*X without large file
1239 * support, which means you'll probably get errors trying to
1240 * write files > 2^31-1, so it won't matter anyway.
1241 *
1242 * XXX - what about MinGW?
1243 */
1244 int64_t
1245 pcap_dump_ftell64(pcap_dumper_t *p)
1246 {
1247 return (ftell((FILE *)p));
1248 }
1249 #endif
1250
1251 int
1252 pcap_dump_flush(pcap_dumper_t *p)
1253 {
1254
1255 if (fflush((FILE *)p) == EOF)
1256 return (-1);
1257 else
1258 return (0);
1259 }
1260
1261 void
1262 pcap_dump_close(pcap_dumper_t *p)
1263 {
1264 FILE *fp = (FILE *)p;
1265
1266 #ifdef notyet
1267 if (ferror(fp))
1268 return-an-error;
1269 /* XXX should check return from fflush()/fclose() too */
1270 #endif
1271 /* Don't close the standard output, but *do* flush it */
1272 if (fp == stdout)
1273 (void)fflush(fp);
1274 else
1275 (void)fclose(fp);
1276 }