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