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