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