6 * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #include "file_wrappers.h"
33 #include "pcap-common.h"
34 #include "pcap-encap.h"
37 /* See source to the "libpcap" library for information on the "libpcap"
41 * Private per-wtap_t data needed to read a file.
50 gboolean byte_swapped;
51 swapped_type_t lengths_swapped;
52 guint16 version_major;
53 guint16 version_minor;
56 /* On some systems, the FDDI MAC addresses are bit-swapped. */
57 #if !defined(ultrix) && !defined(__alpha) && !defined(__bsdi__)
58 #define BIT_SWAPPED_MAC_ADDRS
61 /* Try to read the first two records of the capture file. */
63 THIS_FORMAT, /* the reads succeeded, assume it's this format */
64 BAD_READ, /* the file is probably not valid */
65 OTHER_FORMAT /* the file may be valid, but not in this format */
67 static libpcap_try_t libpcap_try(wtap *wth, int *err);
69 static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info,
71 static gboolean libpcap_seek_read(wtap *wth, gint64 seek_off,
72 union wtap_pseudo_header *pseudo_header, guint8 *pd, int length,
73 int *err, gchar **err_info);
74 static int libpcap_read_header(wtap *wth, int *err, gchar **err_info,
75 struct pcaprec_ss990915_hdr *hdr);
76 static void adjust_header(wtap *wth, struct pcaprec_hdr *hdr);
77 static gboolean libpcap_read_rec_data(FILE_T fh, guint8 *pd, int length,
78 int *err, gchar **err_info);
79 static gboolean libpcap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
80 const union wtap_pseudo_header *pseudo_header, const guint8 *pd, int *err);
82 int libpcap_open(wtap *wth, int *err, gchar **err_info)
87 gboolean byte_swapped;
93 /* Read in the number that should be at the start of a "libpcap" file */
94 errno = WTAP_ERR_CANT_READ;
95 bytes_read = file_read(&magic, sizeof magic, wth->fh);
96 if (bytes_read != sizeof magic) {
97 *err = file_error(wth->fh, err_info);
102 wth->data_offset += sizeof magic;
107 /* Host that wrote it has our byte order, and was running
108 a program using either standard or ss990417 libpcap. */
109 byte_swapped = FALSE;
111 wth->tsprecision = WTAP_FILE_TSPREC_USEC;
114 case PCAP_MODIFIED_MAGIC:
115 /* Host that wrote it has our byte order, and was running
116 a program using either ss990915 or ss991029 libpcap. */
117 byte_swapped = FALSE;
119 wth->tsprecision = WTAP_FILE_TSPREC_USEC;
122 case PCAP_SWAPPED_MAGIC:
123 /* Host that wrote it has a byte order opposite to ours,
124 and was running a program using either standard or
128 wth->tsprecision = WTAP_FILE_TSPREC_USEC;
131 case PCAP_SWAPPED_MODIFIED_MAGIC:
132 /* Host that wrote it out has a byte order opposite to
133 ours, and was running a program using either ss990915
134 or ss991029 libpcap. */
137 wth->tsprecision = WTAP_FILE_TSPREC_USEC;
140 case PCAP_NSEC_MAGIC:
141 /* Host that wrote it has our byte order, and was writing
142 the file in a format similar to standard libpcap
143 except that the time stamps have nanosecond resolution. */
144 byte_swapped = FALSE;
146 wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
149 case PCAP_SWAPPED_NSEC_MAGIC:
150 /* Host that wrote it out has a byte order opposite to
151 ours, and was writing the file in a format similar to
152 standard libpcap except that the time stamps have
153 nanosecond resolution. */
156 wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
160 /* Not a "libpcap" type we know about. */
164 /* Read the rest of the header. */
165 errno = WTAP_ERR_CANT_READ;
166 bytes_read = file_read(&hdr, sizeof hdr, wth->fh);
167 if (bytes_read != sizeof hdr) {
168 *err = file_error(wth->fh, err_info);
173 wth->data_offset += sizeof hdr;
176 /* Byte-swap the header fields about which we care. */
177 hdr.version_major = BSWAP16(hdr.version_major);
178 hdr.version_minor = BSWAP16(hdr.version_minor);
179 hdr.snaplen = BSWAP32(hdr.snaplen);
180 hdr.network = BSWAP32(hdr.network);
182 if (hdr.version_major < 2) {
183 /* We only support version 2.0 and later. */
184 *err = WTAP_ERR_UNSUPPORTED;
185 *err_info = g_strdup_printf("pcap: major version %u unsupported",
191 * AIX's non-standard tcpdump uses a minor version number of 2.
192 * Unfortunately, older versions of libpcap might have used
195 * The AIX libpcap uses RFC 1573 ifType values rather than
196 * DLT_ values in the header; the ifType values for LAN devices
203 * which correspond to DLT_IEEE802 (used for Token Ring),
204 * DLT_PPP, and DLT_SLIP_BSDOS, respectively. The ifType value
205 * for a loopback interface is 24, which currently isn't
206 * used by any version of libpcap I know about (and, as
207 * tcpdump.org are assigning DLT_ values above 100, and
208 * NetBSD started assigning values starting at 50, and
209 * the values chosen by other libpcaps appear to stop at
210 * 19, it's probably not going to be used by any libpcap
213 * We shall assume that if the minor version number is 2, and
214 * the network type is 6, 9, 15, or 24, that it's AIX libpcap.
216 * I'm assuming those older versions of libpcap didn't
217 * use DLT_IEEE802 for Token Ring, and didn't use DLT_SLIP_BSDOS
218 * as that came later. It may have used DLT_PPP, however, in
219 * which case we're out of luck; we assume it's Token Ring
220 * in AIX libpcap rather than PPP in standard libpcap, as
221 * you're probably more likely to be handing an AIX libpcap
222 * token-ring capture than an old (pre-libpcap 0.4) PPP capture
225 aix = FALSE; /* assume it's not AIX */
226 if (hdr.version_major == 2 && hdr.version_minor == 2) {
227 switch (hdr.network) {
230 hdr.network = 1; /* DLT_EN10MB, Ethernet */
235 hdr.network = 6; /* DLT_IEEE802, Token Ring */
240 hdr.network = 10; /* DLT_FDDI, FDDI */
245 hdr.network = 0; /* DLT_NULL, loopback */
251 file_encap = wtap_pcap_encap_to_wtap_encap(hdr.network);
252 if (file_encap == WTAP_ENCAP_UNKNOWN) {
253 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
254 *err_info = g_strdup_printf("pcap: network type %u unknown or unsupported",
259 /* This is a libpcap file */
260 libpcap = (libpcap_t *)g_malloc(sizeof(libpcap_t));;
261 libpcap->byte_swapped = byte_swapped;
262 libpcap->version_major = hdr.version_major;
263 libpcap->version_minor = hdr.version_minor;
264 wth->priv = (void *)libpcap;
265 wth->subtype_read = libpcap_read;
266 wth->subtype_seek_read = libpcap_seek_read;
267 wth->file_encap = file_encap;
268 wth->snapshot_length = hdr.snaplen;
270 /* In file format version 2.3, the order of the "incl_len" and
271 "orig_len" fields in the per-packet header was reversed,
272 in order to match the BPF header layout.
274 Therefore, in files with versions prior to that, we must swap
277 Unfortunately, some files were, according to a comment in the
278 "libpcap" source, written with version 2.3 in their headers
279 but without the interchanged fields, so if "incl_len" is
280 greater than "orig_len" - which would make no sense - we
281 assume that we need to swap them in version 2.3 files
284 In addition, DG/UX's tcpdump uses version 543.0, and writes
285 the two fields in the pre-2.3 order. */
286 switch (hdr.version_major) {
289 if (hdr.version_minor < 3)
290 libpcap->lengths_swapped = SWAPPED;
291 else if (hdr.version_minor == 3)
292 libpcap->lengths_swapped = MAYBE_SWAPPED;
294 libpcap->lengths_swapped = NOT_SWAPPED;
298 libpcap->lengths_swapped = SWAPPED;
302 libpcap->lengths_swapped = NOT_SWAPPED;
307 * Is this AIX format?
311 * Yes. Skip all the tests for other mutant formats,
312 * and set the precision to nanosecond precision.
314 wth->file_type = WTAP_FILE_PCAP_AIX;
315 wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
320 * No. Let's look at the header for the first record,
321 * and see if, interpreting it as a standard header (if the
322 * magic number was standard) or a modified header (if the
323 * magic number was modified), the position where it says the
324 * header for the *second* record is contains a corrupted header.
328 * If this file had the standard magic number, it may be
329 * an ss990417 capture file - in that version of Alexey's
330 * patch, the packet header format was changed but the
331 * magic number wasn't, and, alas, Red Hat appear to have
332 * picked up that version of the patch for RH 6.1, meaning
333 * RH 6.1 has a tcpdump that writes out files that can't
334 * be read by any software that expects non-modified headers
335 * if the magic number isn't the modified magic number (e.g.,
336 * any normal version of tcpdump, and Wireshark if we don't
337 * do this gross heuristic).
339 * If this file had the modified magic number, it may be
340 * an ss990915 capture file - in that version of Alexey's
341 * patch, the magic number was changed, but the record
342 * header had some extra fields, and, alas, SuSE appear
343 * to have picked up that version of the patch for SuSE
344 * 6.3, meaning that programs expecting the standard per-
345 * packet header in captures with the modified magic number
346 * can't read dumps from its tcpdump.
348 * Oh, and if it has the standard magic number, it might, instead,
349 * be a Nokia libpcap file, so we may need to try that if
350 * neither normal nor ss990417 headers work.
354 * Well, we have the magic number from Alexey's
357 * Try ss991029, the last of his patches, first.
359 wth->file_type = WTAP_FILE_PCAP_SS991029;
360 switch (libpcap_try(wth, err)) {
364 * Well, we couldn't even read it.
372 * Well, it looks as if it might be 991029.
373 * Put the seek pointer back, and return success.
375 if (file_seek(wth->fh, wth->data_offset, SEEK_SET, err) == -1) {
383 * Try the next format.
389 * Well, it's not completely unreadable,
390 * but it's not ss991029. Try ss990915;
391 * there are no other types to try after that,
392 * so we put the seek pointer back and treat
395 wth->file_type = WTAP_FILE_PCAP_SS990915;
396 if (file_seek(wth->fh, wth->data_offset, SEEK_SET, err) == -1) {
402 * Well, we have the standard magic number.
404 * Try the standard format first.
406 if(wth->tsprecision == WTAP_FILE_TSPREC_NSEC) {
407 wth->file_type = WTAP_FILE_PCAP_NSEC;
409 wth->file_type = WTAP_FILE_PCAP;
411 switch (libpcap_try(wth, err)) {
415 * Well, we couldn't even read it.
423 * Well, it looks as if it might be a standard
425 * Put the seek pointer back, and return success.
427 if (file_seek(wth->fh, wth->data_offset, SEEK_SET, err) == -1) {
435 * Try the next format.
441 * Well, it's not completely unreadable, but it's not
442 * a standard file. Put the seek pointer back and try
445 wth->file_type = WTAP_FILE_PCAP_SS990417;
446 if (file_seek(wth->fh, wth->data_offset, SEEK_SET, err) == -1) {
450 switch (libpcap_try(wth, err)) {
454 * Well, we couldn't even read it.
462 * Well, it looks as if it might be ss990417.
463 * Put the seek pointer back, and return success.
465 if (file_seek(wth->fh, wth->data_offset, SEEK_SET, err) == -1) {
473 * Try the next format.
479 * Well, it's not completely unreadable,
480 * but it's not a standard file *nor* is it ss990417.
481 * Try it as a Nokia file; there are no other types
482 * to try after that, so we put the seek pointer back
483 * and treat it as a Nokia file.
485 wth->file_type = WTAP_FILE_PCAP_NOKIA;
486 if (file_seek(wth->fh, wth->data_offset, SEEK_SET, err) == -1) {
493 * We treat a DLT_ value of 13 specially - it appears that in
494 * Nokia libpcap format, it's some form of ATM with what I
495 * suspect is a pseudo-header (even though Nokia's IPSO is
496 * based on FreeBSD, which #defines DLT_SLIP_BSDOS as 13).
498 * If this is a Nokia capture, treat 13 as WTAP_ENCAP_ATM_PDUS,
499 * rather than as what we normally treat it.
501 if (wth->file_type == WTAP_FILE_PCAP_NOKIA && hdr.network == 13)
502 wth->file_encap = WTAP_ENCAP_ATM_PDUS;
507 /* Try to read the first two records of the capture file. */
508 static libpcap_try_t libpcap_try(wtap *wth, int *err)
511 * pcaprec_ss990915_hdr is the largest header type.
513 struct pcaprec_ss990915_hdr first_rec_hdr, second_rec_hdr;
517 * Attempt to read the first record's header.
519 if (libpcap_read_header(wth, err, NULL, &first_rec_hdr) == -1) {
520 if (*err == 0 || *err == WTAP_ERR_SHORT_READ) {
522 * EOF or short read - assume the file is in this
524 * When our client tries to read the first packet
525 * they will presumably get the same EOF or short
531 if (*err == WTAP_ERR_BAD_FILE) {
533 * The first record is bogus, so this is probably
534 * a corrupt file. Assume the file is in this
535 * format. When our client tries to read the
536 * first packet they will presumably get the
543 * Some other error, e.g. an I/O error; just give up.
549 * Now skip over the first record's data, under the assumption
550 * that the header is sane.
552 if (file_seek(wth->fh, first_rec_hdr.hdr.incl_len, SEEK_CUR, err) == -1)
556 * Now attempt to read the second record's header.
558 if (libpcap_read_header(wth, err, NULL, &second_rec_hdr) == -1) {
559 if (*err == 0 || *err == WTAP_ERR_SHORT_READ) {
561 * EOF or short read - assume the file is in this
563 * When our client tries to read the second packet
564 * they will presumably get the same EOF or short
570 if (*err == WTAP_ERR_BAD_FILE) {
572 * The second record is bogus; maybe it's a
573 * Capture File From Hell, and what looks like
574 * the "header" of the next packet is actually
575 * random junk from the middle of a packet.
576 * Try the next format; if we run out of formats,
577 * it probably *is* a corrupt file.
583 * Some other error, e.g. an I/O error; just give up.
589 * OK, the first two records look OK; assume this is the
595 /* Read the next packet */
596 static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info,
599 struct pcaprec_ss990915_hdr hdr;
603 guint8 fddi_padding[3];
607 bytes_read = libpcap_read_header(wth, err, err_info, &hdr);
608 if (bytes_read == -1) {
610 * We failed to read the header.
615 wth->data_offset += bytes_read;
616 packet_size = hdr.hdr.incl_len;
617 orig_size = hdr.hdr.orig_len;
620 * AIX appears to put 3 bytes of padding in front of FDDI
621 * frames; strip that crap off.
623 if (wth->file_type == WTAP_FILE_PCAP_AIX &&
624 (wth->file_encap == WTAP_ENCAP_FDDI ||
625 wth->file_encap == WTAP_ENCAP_FDDI_BITSWAPPED)) {
627 * The packet size is really a record size and includes
632 wth->data_offset += 3;
637 if (!libpcap_read_rec_data(wth->fh, fddi_padding, 3, err,
639 return FALSE; /* Read error */
642 *data_offset = wth->data_offset;
644 libpcap = (libpcap_t *)wth->priv;
645 phdr_len = pcap_process_pseudo_header(wth->fh, wth->file_type,
646 wth->file_encap, packet_size, TRUE, &wth->phdr,
647 &wth->pseudo_header, err, err_info);
649 return FALSE; /* error */
652 * Don't count any pseudo-header as part of the packet.
654 orig_size -= phdr_len;
655 packet_size -= phdr_len;
656 wth->data_offset += phdr_len;
658 buffer_assure_space(wth->frame_buffer, packet_size);
659 if (!libpcap_read_rec_data(wth->fh, buffer_start_ptr(wth->frame_buffer),
660 packet_size, err, err_info))
661 return FALSE; /* Read error */
662 wth->data_offset += packet_size;
664 /* Update the Timestamp, if not already done */
665 if (wth->file_encap != WTAP_ENCAP_ERF) {
666 wth->phdr.ts.secs = hdr.hdr.ts_sec;
667 if(wth->tsprecision == WTAP_FILE_TSPREC_NSEC) {
668 wth->phdr.ts.nsecs = hdr.hdr.ts_usec;
670 wth->phdr.ts.nsecs = hdr.hdr.ts_usec * 1000;
673 wth->phdr.caplen = packet_size;
674 wth->phdr.len = orig_size;
676 pcap_read_post_process(wth->file_type, wth->file_encap,
677 &wth->pseudo_header, buffer_start_ptr(wth->frame_buffer),
678 wth->phdr.caplen, libpcap->byte_swapped, -1);
683 libpcap_seek_read(wtap *wth, gint64 seek_off,
684 union wtap_pseudo_header *pseudo_header, guint8 *pd, int length,
685 int *err, gchar **err_info)
690 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
693 libpcap = (libpcap_t *)wth->priv;
694 phdr_len = pcap_process_pseudo_header(wth->random_fh, wth->file_type,
695 wth->file_encap, length, FALSE, NULL, pseudo_header, err, err_info);
697 return FALSE; /* error */
700 * Read the packet data.
702 if (!libpcap_read_rec_data(wth->random_fh, pd, length, err, err_info))
703 return FALSE; /* failed */
705 pcap_read_post_process(wth->file_type, wth->file_encap,
706 pseudo_header, pd, length, libpcap->byte_swapped, -1);
710 /* Read the header of the next packet.
712 Return -1 on an error, or the number of bytes of header read on success. */
713 static int libpcap_read_header(wtap *wth, int *err, gchar **err_info,
714 struct pcaprec_ss990915_hdr *hdr)
716 int bytes_to_read, bytes_read;
718 /* Read record header. */
719 errno = WTAP_ERR_CANT_READ;
720 switch (wth->file_type) {
723 case WTAP_FILE_PCAP_AIX:
724 case WTAP_FILE_PCAP_NSEC:
725 bytes_to_read = sizeof (struct pcaprec_hdr);
728 case WTAP_FILE_PCAP_SS990417:
729 case WTAP_FILE_PCAP_SS991029:
730 bytes_to_read = sizeof (struct pcaprec_modified_hdr);
733 case WTAP_FILE_PCAP_SS990915:
734 bytes_to_read = sizeof (struct pcaprec_ss990915_hdr);
737 case WTAP_FILE_PCAP_NOKIA:
738 bytes_to_read = sizeof (struct pcaprec_nokia_hdr);
742 g_assert_not_reached();
745 bytes_read = file_read(hdr, bytes_to_read, wth->fh);
746 if (bytes_read != bytes_to_read) {
747 *err = file_error(wth->fh, err_info);
748 if (*err == 0 && bytes_read != 0) {
749 *err = WTAP_ERR_SHORT_READ;
754 adjust_header(wth, &hdr->hdr);
756 if (hdr->hdr.incl_len > WTAP_MAX_PACKET_SIZE) {
758 * Probably a corrupt capture file; return an error,
759 * so that our caller doesn't blow up trying to allocate
760 * space for an immensely-large packet, and so that
761 * the code to try to guess what type of libpcap file
762 * this is can tell when it's not the type we're guessing
765 *err = WTAP_ERR_BAD_FILE;
766 if (err_info != NULL) {
767 *err_info = g_strdup_printf("pcap: File has %u-byte packet, bigger than maximum of %u",
768 hdr->hdr.incl_len, WTAP_MAX_PACKET_SIZE);
773 if (hdr->hdr.orig_len > WTAP_MAX_PACKET_SIZE) {
775 * Probably a corrupt capture file; return an error,
776 * so that our caller doesn't blow up trying to
777 * cope with a huge "real" packet length, and so that
778 * the code to try to guess what type of libpcap file
779 * this is can tell when it's not the type we're guessing
782 *err = WTAP_ERR_BAD_FILE;
783 if (err_info != NULL) {
784 *err_info = g_strdup_printf("pcap: File has %u-byte packet, bigger than maximum of %u",
785 hdr->hdr.orig_len, WTAP_MAX_PACKET_SIZE);
794 adjust_header(wtap *wth, struct pcaprec_hdr *hdr)
799 libpcap = (libpcap_t *)wth->priv;
800 if (libpcap->byte_swapped) {
801 /* Byte-swap the record header fields. */
802 hdr->ts_sec = BSWAP32(hdr->ts_sec);
803 hdr->ts_usec = BSWAP32(hdr->ts_usec);
804 hdr->incl_len = BSWAP32(hdr->incl_len);
805 hdr->orig_len = BSWAP32(hdr->orig_len);
808 /* Swap the "incl_len" and "orig_len" fields, if necessary. */
809 switch (libpcap->lengths_swapped) {
815 if (hdr->incl_len <= hdr->orig_len) {
817 * The captured length is <= the actual length,
818 * so presumably they weren't swapped.
825 temp = hdr->orig_len;
826 hdr->orig_len = hdr->incl_len;
827 hdr->incl_len = temp;
833 libpcap_read_rec_data(FILE_T fh, guint8 *pd, int length, int *err,
838 errno = WTAP_ERR_CANT_READ;
839 bytes_read = file_read(pd, length, fh);
841 if (bytes_read != length) {
842 *err = file_error(fh, err_info);
844 *err = WTAP_ERR_SHORT_READ;
850 /* Returns 0 if we could write the specified encapsulation type,
851 an error indication otherwise. */
852 int libpcap_dump_can_write_encap(int encap)
854 /* Per-packet encapsulations aren't supported. */
855 if (encap == WTAP_ENCAP_PER_PACKET)
856 return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED;
858 if (wtap_wtap_encap_to_pcap_encap(encap) == -1)
859 return WTAP_ERR_UNSUPPORTED_ENCAP;
864 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
866 gboolean libpcap_dump_open(wtap_dumper *wdh, int *err)
869 struct pcap_hdr file_hdr;
871 /* This is a libpcap file */
872 wdh->subtype_write = libpcap_dump;
873 wdh->subtype_close = NULL;
875 /* Write the file header. */
876 switch (wdh->file_type) {
879 case WTAP_FILE_PCAP_SS990417: /* modified, but with the old magic, sigh */
880 case WTAP_FILE_PCAP_NOKIA: /* Nokia libpcap of some sort */
882 wdh->tsprecision = WTAP_FILE_TSPREC_USEC;
885 case WTAP_FILE_PCAP_SS990915: /* new magic, extra crap */
886 case WTAP_FILE_PCAP_SS991029:
887 magic = PCAP_MODIFIED_MAGIC;
888 wdh->tsprecision = WTAP_FILE_TSPREC_USEC;
891 case WTAP_FILE_PCAP_NSEC: /* same as WTAP_FILE_PCAP, but nsec precision */
892 magic = PCAP_NSEC_MAGIC;
893 wdh->tsprecision = WTAP_FILE_TSPREC_NSEC;
897 /* We should never get here - our open routine
898 should only get called for the types above. */
899 *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
903 if (!wtap_dump_file_write(wdh, &magic, sizeof magic, err))
905 wdh->bytes_dumped += sizeof magic;
907 /* current "libpcap" format is 2.4 */
908 file_hdr.version_major = 2;
909 file_hdr.version_minor = 4;
910 file_hdr.thiszone = 0; /* XXX - current offset? */
911 file_hdr.sigfigs = 0; /* unknown, but also apparently unused */
913 * Tcpdump cannot handle capture files with a snapshot length of 0,
914 * as BPF filters return either 0 if they fail or the snapshot length
915 * if they succeed, and a snapshot length of 0 means success is
916 * indistinguishable from failure and the filter expression would
917 * reject all packets.
919 * A snapshot length of 0, inside Wiretap, means "snapshot length
920 * unknown"; if the snapshot length supplied to us is 0, we make
921 * the snapshot length in the header file WTAP_MAX_PACKET_SIZE.
923 file_hdr.snaplen = (wdh->snaplen != 0) ? wdh->snaplen :
924 WTAP_MAX_PACKET_SIZE;
925 file_hdr.network = wtap_wtap_encap_to_pcap_encap(wdh->encap);
926 if (!wtap_dump_file_write(wdh, &file_hdr, sizeof file_hdr, err))
928 wdh->bytes_dumped += sizeof file_hdr;
933 /* Write a record for a packet to a dump file.
934 Returns TRUE on success, FALSE on failure. */
935 static gboolean libpcap_dump(wtap_dumper *wdh,
936 const struct wtap_pkthdr *phdr,
937 const union wtap_pseudo_header *pseudo_header,
938 const guint8 *pd, int *err)
940 struct pcaprec_ss990915_hdr rec_hdr;
944 phdrsize = pcap_get_phdr_size(wdh->encap, pseudo_header);
946 rec_hdr.hdr.ts_sec = (guint32) phdr->ts.secs;
947 if(wdh->tsprecision == WTAP_FILE_TSPREC_NSEC) {
948 rec_hdr.hdr.ts_usec = phdr->ts.nsecs;
950 rec_hdr.hdr.ts_usec = phdr->ts.nsecs / 1000;
952 rec_hdr.hdr.incl_len = phdr->caplen + phdrsize;
953 rec_hdr.hdr.orig_len = phdr->len + phdrsize;
955 if (rec_hdr.hdr.incl_len > WTAP_MAX_PACKET_SIZE || rec_hdr.hdr.orig_len > WTAP_MAX_PACKET_SIZE) {
956 *err = WTAP_ERR_BAD_FILE;
960 switch (wdh->file_type) {
963 case WTAP_FILE_PCAP_NSEC:
964 hdr_size = sizeof (struct pcaprec_hdr);
967 case WTAP_FILE_PCAP_SS990417: /* modified, but with the old magic, sigh */
968 case WTAP_FILE_PCAP_SS991029:
969 /* XXX - what should we supply here?
971 Alexey's "libpcap" looks up the interface in the system's
972 interface list if "ifindex" is non-zero, and prints
973 the interface name. It ignores "protocol", and uses
974 "pkt_type" to tag the packet as "host", "broadcast",
975 "multicast", "other host", "outgoing", or "none of the
976 above", but that's it.
978 If the capture we're writing isn't a modified or
979 RH 6.1 capture, we'd have to do some work to
980 generate the packet type and interface index - and
981 we can't generate the interface index unless we
982 just did the capture ourselves in any case.
984 I'm inclined to continue to punt; systems other than
985 those with the older patch can read standard "libpcap"
986 files, and systems with the older patch, e.g. RH 6.1,
987 will just have to live with this. */
989 rec_hdr.protocol = 0;
990 rec_hdr.pkt_type = 0;
991 hdr_size = sizeof (struct pcaprec_modified_hdr);
994 case WTAP_FILE_PCAP_SS990915: /* new magic, extra crap at the end */
996 rec_hdr.protocol = 0;
997 rec_hdr.pkt_type = 0;
1000 hdr_size = sizeof (struct pcaprec_ss990915_hdr);
1003 case WTAP_FILE_PCAP_NOKIA: /* old magic, extra crap at the end */
1004 rec_hdr.ifindex = 0;
1005 rec_hdr.protocol = 0;
1006 rec_hdr.pkt_type = 0;
1009 hdr_size = sizeof (struct pcaprec_nokia_hdr);
1013 /* We should never get here - our open routine
1014 should only get called for the types above. */
1015 g_assert_not_reached();
1016 *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
1020 if (!wtap_dump_file_write(wdh, &rec_hdr, hdr_size, err))
1022 wdh->bytes_dumped += hdr_size;
1024 if (!pcap_write_phdr(wdh, wdh->encap, pseudo_header, err))
1027 if (!wtap_dump_file_write(wdh, pd, phdr->caplen, err))
1029 wdh->bytes_dumped += phdr->caplen;