libpcap  1.10.1
About: libpcap is a packet filter library used by tools like tcpdump.
  Fossies Dox: libpcap-1.10.1.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

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