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