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"
34 #include "pcap-common.h"
37 /* See source to the "libpcap" library for information on the "libpcap"
40 /* On some systems, the FDDI MAC addresses are bit-swapped. */
41 #if !defined(ultrix) && !defined(__alpha) && !defined(__bsdi__)
42 #define BIT_SWAPPED_MAC_ADDRS
45 /* Try to read the first two records of the capture file. */
47 THIS_FORMAT, /* the reads succeeded, assume it's this format */
48 BAD_READ, /* the file is probably not valid */
49 OTHER_FORMAT /* the file may be valid, but not in this format */
51 static libpcap_try_t libpcap_try(wtap *wth, int *err);
53 static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info,
55 static gboolean libpcap_seek_read(wtap *wth, gint64 seek_off,
56 union wtap_pseudo_header *pseudo_header, guchar *pd, int length,
57 int *err, gchar **err_info);
58 static int libpcap_read_header(wtap *wth, int *err, gchar **err_info,
59 struct pcaprec_ss990915_hdr *hdr);
60 static void adjust_header(wtap *wth, struct pcaprec_hdr *hdr);
61 static gboolean libpcap_read_rec_data(FILE_T fh, guchar *pd, int length,
63 static void libpcap_close(wtap *wth);
64 static gboolean libpcap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
65 const union wtap_pseudo_header *pseudo_header, const guchar *pd, int *err);
67 int libpcap_open(wtap *wth, int *err, gchar **err_info)
72 gboolean byte_swapped;
77 /* Read in the number that should be at the start of a "libpcap" file */
78 errno = WTAP_ERR_CANT_READ;
79 bytes_read = file_read(&magic, 1, sizeof magic, wth->fh);
80 if (bytes_read != sizeof magic) {
81 *err = file_error(wth->fh);
86 wth->data_offset += sizeof magic;
91 /* Host that wrote it has our byte order, and was running
92 a program using either standard or ss990417 libpcap. */
95 wth->tsprecision = WTAP_FILE_TSPREC_USEC;
98 case PCAP_MODIFIED_MAGIC:
99 /* Host that wrote it has our byte order, and was running
100 a program using either ss990915 or ss991029 libpcap. */
101 byte_swapped = FALSE;
103 wth->tsprecision = WTAP_FILE_TSPREC_USEC;
106 case PCAP_SWAPPED_MAGIC:
107 /* Host that wrote it has a byte order opposite to ours,
108 and was running a program using either standard or
112 wth->tsprecision = WTAP_FILE_TSPREC_USEC;
115 case PCAP_SWAPPED_MODIFIED_MAGIC:
116 /* Host that wrote it out has a byte order opposite to
117 ours, and was running a program using either ss990915
118 or ss991029 libpcap. */
121 wth->tsprecision = WTAP_FILE_TSPREC_USEC;
124 case PCAP_NSEC_MAGIC:
125 /* Host that wrote it has our byte order, and was writing
126 the file in a format similar to standard libpcap
127 except that the time stamps have nanosecond resolution. */
128 byte_swapped = FALSE;
130 wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
133 case PCAP_SWAPPED_NSEC_MAGIC:
134 /* Host that wrote it out has a byte order opposite to
135 ours, and was writing the file in a format similar to
136 standard libpcap except that the time stamps have
137 nanosecond resolution. */
140 wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
144 /* Not a "libpcap" type we know about. */
148 /* Read the rest of the header. */
149 errno = WTAP_ERR_CANT_READ;
150 bytes_read = file_read(&hdr, 1, sizeof hdr, wth->fh);
151 if (bytes_read != sizeof hdr) {
152 *err = file_error(wth->fh);
157 wth->data_offset += sizeof hdr;
160 /* Byte-swap the header fields about which we care. */
161 hdr.version_major = BSWAP16(hdr.version_major);
162 hdr.version_minor = BSWAP16(hdr.version_minor);
163 hdr.snaplen = BSWAP32(hdr.snaplen);
164 hdr.network = BSWAP32(hdr.network);
166 if (hdr.version_major < 2) {
167 /* We only support version 2.0 and later. */
168 *err = WTAP_ERR_UNSUPPORTED;
169 *err_info = g_strdup_printf("pcap: major version %u unsupported",
175 * AIX's non-standard tcpdump uses a minor version number of 2.
176 * Unfortunately, older versions of libpcap might have used
179 * The AIX libpcap uses RFC 1573 ifType values rather than
180 * DLT_ values in the header; the ifType values for LAN devices
187 * which correspond to DLT_IEEE802 (used for Token Ring),
188 * DLT_PPP, and DLT_SLIP_BSDOS, respectively. The ifType value
189 * for a loopback interface is 24, which currently isn't
190 * used by any version of libpcap I know about (and, as
191 * tcpdump.org are assigning DLT_ values above 100, and
192 * NetBSD started assigning values starting at 50, and
193 * the values chosen by other libpcaps appear to stop at
194 * 19, it's probably not going to be used by any libpcap
197 * We shall assume that if the minor version number is 2, and
198 * the network type is 6, 9, 15, or 24, that it's AIX libpcap.
200 * I'm assuming those older versions of libpcap didn't
201 * use DLT_IEEE802 for Token Ring, and didn't use DLT_SLIP_BSDOS
202 * as that came later. It may have used DLT_PPP, however, in
203 * which case we're out of luck; we assume it's Token Ring
204 * in AIX libpcap rather than PPP in standard libpcap, as
205 * you're probably more likely to be handing an AIX libpcap
206 * token-ring capture than an old (pre-libpcap 0.4) PPP capture
209 aix = FALSE; /* assume it's not AIX */
210 if (hdr.version_major == 2 && hdr.version_minor == 2) {
211 switch (hdr.network) {
214 hdr.network = 1; /* DLT_EN10MB, Ethernet */
219 hdr.network = 6; /* DLT_IEEE802, Token Ring */
224 hdr.network = 10; /* DLT_FDDI, FDDI */
229 hdr.network = 0; /* DLT_NULL, loopback */
235 file_encap = wtap_pcap_encap_to_wtap_encap(hdr.network);
236 if (file_encap == WTAP_ENCAP_UNKNOWN) {
237 *err = WTAP_ERR_UNSUPPORTED_ENCAP;
238 *err_info = g_strdup_printf("pcap: network type %u unknown or unsupported",
243 /* This is a libpcap file */
244 wth->capture.pcap = g_malloc(sizeof(libpcap_t));
245 wth->capture.pcap->byte_swapped = byte_swapped;
246 wth->capture.pcap->version_major = hdr.version_major;
247 wth->capture.pcap->version_minor = hdr.version_minor;
248 wth->subtype_read = libpcap_read;
249 wth->subtype_seek_read = libpcap_seek_read;
250 wth->subtype_close = libpcap_close;
251 wth->file_encap = file_encap;
252 wth->snapshot_length = hdr.snaplen;
254 /* In file format version 2.3, the order of the "incl_len" and
255 "orig_len" fields in the per-packet header was reversed,
256 in order to match the BPF header layout.
258 Therefore, in files with versions prior to that, we must swap
261 Unfortunately, some files were, according to a comment in the
262 "libpcap" source, written with version 2.3 in their headers
263 but without the interchanged fields, so if "incl_len" is
264 greater than "orig_len" - which would make no sense - we
265 assume that we need to swap them in version 2.3 files
268 In addition, DG/UX's tcpdump uses version 543.0, and writes
269 the two fields in the pre-2.3 order. */
270 switch (hdr.version_major) {
273 if (hdr.version_minor < 3)
274 wth->capture.pcap->lengths_swapped = SWAPPED;
275 else if (hdr.version_minor == 3)
276 wth->capture.pcap->lengths_swapped = MAYBE_SWAPPED;
278 wth->capture.pcap->lengths_swapped = NOT_SWAPPED;
282 wth->capture.pcap->lengths_swapped = SWAPPED;
286 wth->capture.pcap->lengths_swapped = NOT_SWAPPED;
291 * Is this AIX format?
295 * Yes. Skip all the tests for other mutant formats,
296 * and set the precision to nanosecond precision.
298 wth->file_type = WTAP_FILE_PCAP_AIX;
299 wth->tsprecision = WTAP_FILE_TSPREC_NSEC;
304 * No. Let's look at the header for the first record,
305 * and see if, interpreting it as a standard header (if the
306 * magic number was standard) or a modified header (if the
307 * magic number was modified), the position where it says the
308 * header for the *second* record is contains a corrupted header.
312 * If this file had the standard magic number, it may be
313 * an ss990417 capture file - in that version of Alexey's
314 * patch, the packet header format was changed but the
315 * magic number wasn't, and, alas, Red Hat appear to have
316 * picked up that version of the patch for RH 6.1, meaning
317 * RH 6.1 has a tcpdump that writes out files that can't
318 * be read by any software that expects non-modified headers
319 * if the magic number isn't the modified magic number (e.g.,
320 * any normal version of tcpdump, and Wireshark if we don't
321 * do this gross heuristic).
323 * If this file had the modified magic number, it may be
324 * an ss990915 capture file - in that version of Alexey's
325 * patch, the magic number was changed, but the record
326 * header had some extra fields, and, alas, SuSE appear
327 * to have picked up that version of the patch for SuSE
328 * 6.3, meaning that programs expecting the standard per-
329 * packet header in captures with the modified magic number
330 * can't read dumps from its tcpdump.
332 * Oh, and if it has the standard magic number, it might, instead,
333 * be a Nokia libpcap file, so we may need to try that if
334 * neither normal nor ss990417 headers work.
338 * Well, we have the magic number from Alexey's
341 * Try ss991029, the last of his patches, first.
343 wth->file_type = WTAP_FILE_PCAP_SS991029;
344 switch (libpcap_try(wth, err)) {
348 * Well, we couldn't even read it.
351 g_free(wth->capture.pcap);
356 * Well, it looks as if it might be 991029.
357 * Put the seek pointer back, and return success.
359 if (file_seek(wth->fh, wth->data_offset, SEEK_SET, err) == -1) {
360 g_free(wth->capture.pcap);
367 * Try the next format.
373 * Well, it's not completely unreadable,
374 * but it's not ss991029. Try ss990915;
375 * there are no other types to try after that,
376 * so we put the seek pointer back and treat
379 wth->file_type = WTAP_FILE_PCAP_SS990915;
380 if (file_seek(wth->fh, wth->data_offset, SEEK_SET, err) == -1) {
381 g_free(wth->capture.pcap);
386 * Well, we have the standard magic number.
388 * Try the standard format first.
390 if(wth->tsprecision == WTAP_FILE_TSPREC_NSEC) {
391 wth->file_type = WTAP_FILE_PCAP_NSEC;
393 wth->file_type = WTAP_FILE_PCAP;
395 switch (libpcap_try(wth, err)) {
399 * Well, we couldn't even read it.
402 g_free(wth->capture.pcap);
407 * Well, it looks as if it might be a standard
409 * Put the seek pointer back, and return success.
411 if (file_seek(wth->fh, wth->data_offset, SEEK_SET, err) == -1) {
412 g_free(wth->capture.pcap);
419 * Try the next format.
425 * Well, it's not completely unreadable, but it's not
426 * a standard file. Put the seek pointer back and try
429 wth->file_type = WTAP_FILE_PCAP_SS990417;
430 if (file_seek(wth->fh, wth->data_offset, SEEK_SET, err) == -1) {
431 g_free(wth->capture.pcap);
434 switch (libpcap_try(wth, err)) {
438 * Well, we couldn't even read it.
441 g_free(wth->capture.pcap);
446 * Well, it looks as if it might be ss990417.
447 * Put the seek pointer back, and return success.
449 if (file_seek(wth->fh, wth->data_offset, SEEK_SET, err) == -1) {
450 g_free(wth->capture.pcap);
457 * Try the next format.
463 * Well, it's not completely unreadable,
464 * but it's not a standard file *nor* is it ss990417.
465 * Try it as a Nokia file; there are no other types
466 * to try after that, so we put the seek pointer back
467 * and treat it as a Nokia file.
469 wth->file_type = WTAP_FILE_PCAP_NOKIA;
470 if (file_seek(wth->fh, wth->data_offset, SEEK_SET, err) == -1) {
471 g_free(wth->capture.pcap);
477 * We treat a DLT_ value of 13 specially - it appears that in
478 * Nokia libpcap format, it's some form of ATM with what I
479 * suspect is a pseudo-header (even though Nokia's IPSO is
480 * based on FreeBSD, which #defines DLT_SLIP_BSDOS as 13).
482 * If this is a Nokia capture, treat 13 as WTAP_ENCAP_ATM_PDUS,
483 * rather than as what we normally treat it.
485 if (wth->file_type == WTAP_FILE_PCAP_NOKIA && hdr.network == 13)
486 wth->file_encap = WTAP_ENCAP_ATM_PDUS;
491 /* Try to read the first two records of the capture file. */
492 static libpcap_try_t libpcap_try(wtap *wth, int *err)
495 * pcaprec_ss990915_hdr is the largest header type.
497 struct pcaprec_ss990915_hdr first_rec_hdr, second_rec_hdr;
501 * Attempt to read the first record's header.
503 if (libpcap_read_header(wth, err, NULL, &first_rec_hdr) == -1) {
504 if (*err == 0 || *err == WTAP_ERR_SHORT_READ) {
506 * EOF or short read - assume the file is in this
508 * When our client tries to read the first packet
509 * they will presumably get the same EOF or short
515 if (*err == WTAP_ERR_BAD_RECORD) {
517 * The first record is bogus, so this is probably
518 * a corrupt file. Assume the file is in this
519 * format. When our client tries to read the
520 * first packet they will presumably get the
527 * Some other error, e.g. an I/O error; just give up.
533 * Now skip over the first record's data, under the assumption
534 * that the header is sane.
536 if (file_seek(wth->fh, first_rec_hdr.hdr.incl_len, SEEK_CUR, err) == -1)
540 * Now attempt to read the second record's header.
542 if (libpcap_read_header(wth, err, NULL, &second_rec_hdr) == -1) {
543 if (*err == 0 || *err == WTAP_ERR_SHORT_READ) {
545 * EOF or short read - assume the file is in this
547 * When our client tries to read the second packet
548 * they will presumably get the same EOF or short
554 if (*err == WTAP_ERR_BAD_RECORD) {
556 * The second record is bogus; maybe it's a
557 * Capture File From Hell, and what looks like
558 * the "header" of the next packet is actually
559 * random junk from the middle of a packet.
560 * Try the next format; if we run out of formats,
561 * it probably *is* a corrupt file.
567 * Some other error, e.g. an I/O error; just give up.
573 * OK, the first two records look OK; assume this is the
579 /* Read the next packet */
580 static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info,
583 struct pcaprec_ss990915_hdr hdr;
587 guchar fddi_padding[3];
590 bytes_read = libpcap_read_header(wth, err, err_info, &hdr);
591 if (bytes_read == -1) {
593 * We failed to read the header.
598 wth->data_offset += bytes_read;
599 packet_size = hdr.hdr.incl_len;
600 orig_size = hdr.hdr.orig_len;
603 * AIX appears to put 3 bytes of padding in front of FDDI
604 * frames; strip that crap off.
606 if (wth->file_type == WTAP_FILE_PCAP_AIX &&
607 (wth->file_encap == WTAP_ENCAP_FDDI ||
608 wth->file_encap == WTAP_ENCAP_FDDI_BITSWAPPED)) {
610 * The packet size is really a record size and includes
615 wth->data_offset += 3;
620 if (!libpcap_read_rec_data(wth->fh, fddi_padding, 3, err))
621 return FALSE; /* Read error */
624 *data_offset = wth->data_offset;
626 phdr_len = pcap_process_pseudo_header(wth->fh, wth->file_type, wth->file_encap, wth->capture.pcap->byte_swapped, packet_size,
627 TRUE, &wth->phdr, &wth->pseudo_header, err, err_info);
629 return FALSE; /* error */
632 * Don't count any pseudo-header as part of the packet.
634 orig_size -= phdr_len;
635 packet_size -= phdr_len;
636 wth->data_offset += phdr_len;
638 buffer_assure_space(wth->frame_buffer, packet_size);
639 if (!libpcap_read_rec_data(wth->fh, buffer_start_ptr(wth->frame_buffer),
641 return FALSE; /* Read error */
642 wth->data_offset += packet_size;
644 /* Update the Timestamp, if not already done */
645 if (wth->file_encap != WTAP_ENCAP_ERF) {
646 wth->phdr.ts.secs = hdr.hdr.ts_sec;
647 if(wth->tsprecision == WTAP_FILE_TSPREC_NSEC) {
648 wth->phdr.ts.nsecs = hdr.hdr.ts_usec;
650 wth->phdr.ts.nsecs = hdr.hdr.ts_usec * 1000;
653 wth->phdr.caplen = packet_size;
654 wth->phdr.len = orig_size;
656 if (wth->file_encap == WTAP_ENCAP_ATM_PDUS) {
657 if (wth->file_type == WTAP_FILE_PCAP_NOKIA) {
661 * Guess the traffic type based on the packet
664 atm_guess_traffic_type(buffer_start_ptr(wth->frame_buffer),
665 wth->phdr.caplen, &wth->pseudo_header);
670 * If this is ATM LANE traffic, try to guess what
671 * type of LANE traffic it is based on the packet
674 if (wth->pseudo_header.atm.type == TRAF_LANE) {
675 atm_guess_lane_type(buffer_start_ptr(wth->frame_buffer),
676 wth->phdr.caplen, &wth->pseudo_header);
685 libpcap_seek_read(wtap *wth, gint64 seek_off,
686 union wtap_pseudo_header *pseudo_header, guchar *pd, int length,
687 int *err, gchar **err_info)
691 if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
694 phdr_len = pcap_process_pseudo_header(wth->random_fh, wth->file_type, wth->file_encap, wth->capture.pcap->byte_swapped, length,
695 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))
703 return FALSE; /* failed */
705 if (wth->file_encap == WTAP_ENCAP_ATM_PDUS) {
706 if (wth->file_type == WTAP_FILE_PCAP_NOKIA) {
710 * Guess the traffic type based on the packet
713 atm_guess_traffic_type(pd, length, pseudo_header);
718 * If this is ATM LANE traffic, try to guess what
719 * type of LANE traffic it is based on the packet
722 if (pseudo_header->atm.type == TRAF_LANE)
723 atm_guess_lane_type(pd, length, pseudo_header);
729 /* Read the header of the next packet.
731 Return -1 on an error, or the number of bytes of header read on success. */
732 static int libpcap_read_header(wtap *wth, int *err, gchar **err_info,
733 struct pcaprec_ss990915_hdr *hdr)
735 int bytes_to_read, bytes_read;
737 /* Read record header. */
738 errno = WTAP_ERR_CANT_READ;
739 switch (wth->file_type) {
742 case WTAP_FILE_PCAP_AIX:
743 case WTAP_FILE_PCAP_NSEC:
744 bytes_to_read = sizeof (struct pcaprec_hdr);
747 case WTAP_FILE_PCAP_SS990417:
748 case WTAP_FILE_PCAP_SS991029:
749 bytes_to_read = sizeof (struct pcaprec_modified_hdr);
752 case WTAP_FILE_PCAP_SS990915:
753 bytes_to_read = sizeof (struct pcaprec_ss990915_hdr);
756 case WTAP_FILE_PCAP_NOKIA:
757 bytes_to_read = sizeof (struct pcaprec_nokia_hdr);
761 g_assert_not_reached();
764 bytes_read = file_read(hdr, 1, bytes_to_read, wth->fh);
765 if (bytes_read != bytes_to_read) {
766 *err = file_error(wth->fh);
767 if (*err == 0 && bytes_read != 0) {
768 *err = WTAP_ERR_SHORT_READ;
773 adjust_header(wth, &hdr->hdr);
775 if (hdr->hdr.incl_len > WTAP_MAX_PACKET_SIZE) {
777 * Probably a corrupt capture file; return an error,
778 * so that our caller doesn't blow up trying to allocate
779 * space for an immensely-large packet, and so that
780 * the code to try to guess what type of libpcap file
781 * this is can tell when it's not the type we're guessing
784 *err = WTAP_ERR_BAD_RECORD;
785 if (err_info != NULL) {
786 *err_info = g_strdup_printf("pcap: File has %u-byte packet, bigger than maximum of %u",
787 hdr->hdr.incl_len, WTAP_MAX_PACKET_SIZE);
792 if (hdr->hdr.orig_len > WTAP_MAX_PACKET_SIZE) {
794 * Probably a corrupt capture file; return an error,
795 * so that our caller doesn't blow up trying to
796 * cope with a huge "real" packet length, and so that
797 * the code to try to guess what type of libpcap file
798 * this is can tell when it's not the type we're guessing
801 *err = WTAP_ERR_BAD_RECORD;
802 if (err_info != NULL) {
803 *err_info = g_strdup_printf("pcap: File has %u-byte packet, bigger than maximum of %u",
804 hdr->hdr.orig_len, WTAP_MAX_PACKET_SIZE);
813 adjust_header(wtap *wth, struct pcaprec_hdr *hdr)
817 if (wth->capture.pcap->byte_swapped) {
818 /* Byte-swap the record header fields. */
819 hdr->ts_sec = BSWAP32(hdr->ts_sec);
820 hdr->ts_usec = BSWAP32(hdr->ts_usec);
821 hdr->incl_len = BSWAP32(hdr->incl_len);
822 hdr->orig_len = BSWAP32(hdr->orig_len);
825 /* Swap the "incl_len" and "orig_len" fields, if necessary. */
826 switch (wth->capture.pcap->lengths_swapped) {
832 if (hdr->incl_len <= hdr->orig_len) {
834 * The captured length is <= the actual length,
835 * so presumably they weren't swapped.
842 temp = hdr->orig_len;
843 hdr->orig_len = hdr->incl_len;
844 hdr->incl_len = temp;
850 libpcap_read_rec_data(FILE_T fh, guchar *pd, int length, int *err)
854 errno = WTAP_ERR_CANT_READ;
855 bytes_read = file_read(pd, 1, length, fh);
857 if (bytes_read != length) {
858 *err = file_error(fh);
860 *err = WTAP_ERR_SHORT_READ;
867 libpcap_close(wtap *wth)
869 g_free(wth->capture.pcap);
872 /* Returns 0 if we could write the specified encapsulation type,
873 an error indication otherwise. */
874 int libpcap_dump_can_write_encap(int encap)
876 /* Per-packet encapsulations aren't supported. */
877 if (encap == WTAP_ENCAP_PER_PACKET)
878 return WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED;
880 if (wtap_wtap_encap_to_pcap_encap(encap) == -1)
881 return WTAP_ERR_UNSUPPORTED_ENCAP;
886 /* Returns TRUE on success, FALSE on failure; sets "*err" to an error code on
888 gboolean libpcap_dump_open(wtap_dumper *wdh, gboolean cant_seek _U_, int *err)
891 struct pcap_hdr file_hdr;
894 /* This is a libpcap file */
895 wdh->subtype_write = libpcap_dump;
896 wdh->subtype_close = NULL;
898 /* Write the file header. */
899 switch (wdh->file_type) {
902 case WTAP_FILE_PCAP_SS990417: /* modified, but with the old magic, sigh */
903 case WTAP_FILE_PCAP_NOKIA: /* Nokia libpcap of some sort */
905 wdh->tsprecision = WTAP_FILE_TSPREC_USEC;
908 case WTAP_FILE_PCAP_SS990915: /* new magic, extra crap */
909 case WTAP_FILE_PCAP_SS991029:
910 magic = PCAP_MODIFIED_MAGIC;
911 wdh->tsprecision = WTAP_FILE_TSPREC_USEC;
914 case WTAP_FILE_PCAP_NSEC: /* same as WTAP_FILE_PCAP, but nsec precision */
915 magic = PCAP_NSEC_MAGIC;
916 wdh->tsprecision = WTAP_FILE_TSPREC_NSEC;
920 /* We should never get here - our open routine
921 should only get called for the types above. */
922 *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
926 nwritten = wtap_dump_file_write(wdh, &magic, sizeof magic);
927 if (nwritten != sizeof magic) {
928 if (nwritten == 0 && wtap_dump_file_ferror(wdh))
929 *err = wtap_dump_file_ferror(wdh);
931 *err = WTAP_ERR_SHORT_WRITE;
934 wdh->bytes_dumped += sizeof magic;
936 /* current "libpcap" format is 2.4 */
937 file_hdr.version_major = 2;
938 file_hdr.version_minor = 4;
939 file_hdr.thiszone = 0; /* XXX - current offset? */
940 file_hdr.sigfigs = 0; /* unknown, but also apparently unused */
942 * Tcpdump cannot handle capture files with a snapshot length of 0,
943 * as BPF filters return either 0 if they fail or the snapshot length
944 * if they succeed, and a snapshot length of 0 means success is
945 * indistinguishable from failure and the filter expression would
946 * reject all packets.
948 * A snapshot length of 0, inside Wiretap, means "snapshot length
949 * unknown"; if the snapshot length supplied to us is 0, we make
950 * the snapshot length in the header file WTAP_MAX_PACKET_SIZE.
952 file_hdr.snaplen = (wdh->snaplen != 0) ? wdh->snaplen :
953 WTAP_MAX_PACKET_SIZE;
954 file_hdr.network = wtap_wtap_encap_to_pcap_encap(wdh->encap);
955 nwritten = wtap_dump_file_write(wdh, &file_hdr, sizeof file_hdr);
956 if (nwritten != sizeof file_hdr) {
957 if (nwritten == 0 && wtap_dump_file_ferror(wdh))
958 *err = wtap_dump_file_ferror(wdh);
960 *err = WTAP_ERR_SHORT_WRITE;
963 wdh->bytes_dumped += sizeof file_hdr;
968 /* Write a record for a packet to a dump file.
969 Returns TRUE on success, FALSE on failure. */
970 static gboolean libpcap_dump(wtap_dumper *wdh,
971 const struct wtap_pkthdr *phdr,
972 const union wtap_pseudo_header *pseudo_header,
973 const guchar *pd, int *err)
975 struct pcaprec_ss990915_hdr rec_hdr;
980 phdrsize = pcap_get_phdr_size(wdh->encap, pseudo_header);
982 rec_hdr.hdr.ts_sec = (guint32) phdr->ts.secs;
983 if(wdh->tsprecision == WTAP_FILE_TSPREC_NSEC) {
984 rec_hdr.hdr.ts_usec = phdr->ts.nsecs;
986 rec_hdr.hdr.ts_usec = phdr->ts.nsecs / 1000;
988 rec_hdr.hdr.incl_len = phdr->caplen + phdrsize;
989 rec_hdr.hdr.orig_len = phdr->len + phdrsize;
990 switch (wdh->file_type) {
993 case WTAP_FILE_PCAP_NSEC:
994 hdr_size = sizeof (struct pcaprec_hdr);
997 case WTAP_FILE_PCAP_SS990417: /* modified, but with the old magic, sigh */
998 case WTAP_FILE_PCAP_SS991029:
999 /* XXX - what should we supply here?
1001 Alexey's "libpcap" looks up the interface in the system's
1002 interface list if "ifindex" is non-zero, and prints
1003 the interface name. It ignores "protocol", and uses
1004 "pkt_type" to tag the packet as "host", "broadcast",
1005 "multicast", "other host", "outgoing", or "none of the
1006 above", but that's it.
1008 If the capture we're writing isn't a modified or
1009 RH 6.1 capture, we'd have to do some work to
1010 generate the packet type and interface index - and
1011 we can't generate the interface index unless we
1012 just did the capture ourselves in any case.
1014 I'm inclined to continue to punt; systems other than
1015 those with the older patch can read standard "libpcap"
1016 files, and systems with the older patch, e.g. RH 6.1,
1017 will just have to live with this. */
1018 rec_hdr.ifindex = 0;
1019 rec_hdr.protocol = 0;
1020 rec_hdr.pkt_type = 0;
1021 hdr_size = sizeof (struct pcaprec_modified_hdr);
1024 case WTAP_FILE_PCAP_SS990915: /* new magic, extra crap at the end */
1025 rec_hdr.ifindex = 0;
1026 rec_hdr.protocol = 0;
1027 rec_hdr.pkt_type = 0;
1030 hdr_size = sizeof (struct pcaprec_ss990915_hdr);
1033 case WTAP_FILE_PCAP_NOKIA: /* old magic, extra crap at the end */
1034 rec_hdr.ifindex = 0;
1035 rec_hdr.protocol = 0;
1036 rec_hdr.pkt_type = 0;
1039 hdr_size = sizeof (struct pcaprec_nokia_hdr);
1043 /* We should never get here - our open routine
1044 should only get called for the types above. */
1045 g_assert_not_reached();
1046 *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE;
1050 nwritten = wtap_dump_file_write(wdh, &rec_hdr, hdr_size);
1051 if (nwritten != hdr_size) {
1052 if (nwritten == 0 && wtap_dump_file_ferror(wdh))
1053 *err = wtap_dump_file_ferror(wdh);
1055 *err = WTAP_ERR_SHORT_WRITE;
1058 wdh->bytes_dumped += hdr_size;
1060 if (!pcap_write_phdr(wdh, wdh->encap, pseudo_header, err))
1063 nwritten = wtap_dump_file_write(wdh, pd, phdr->caplen);
1064 if (nwritten != phdr->caplen) {
1065 if (nwritten == 0 && wtap_dump_file_ferror(wdh))
1066 *err = wtap_dump_file_ferror(wdh);
1068 *err = WTAP_ERR_SHORT_WRITE;
1071 wdh->bytes_dumped += phdr->caplen;