summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--wiretap/file.c6
-rw-r--r--wiretap/libpcap.c369
-rw-r--r--wiretap/libpcap.h8
-rw-r--r--wiretap/wtap.h43
4 files changed, 316 insertions, 110 deletions
diff --git a/wiretap/file.c b/wiretap/file.c
index 63649b9590..97ba040e6f 100644
--- a/wiretap/file.c
+++ b/wiretap/file.c
@@ -1,6 +1,6 @@
/* file.c
*
- * $Id: file.c,v 1.60 2000/08/11 13:32:36 deniel Exp $
+ * $Id: file.c,v 1.61 2000/09/15 07:52:41 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
@@ -267,6 +267,10 @@ const static struct file_type_info {
{ "modified libpcap (tcpdump)", "modlibpcap",
libpcap_dump_can_write_encap, libpcap_dump_open },
+ /* WTAP_FILE_PCAP_NOKIA */
+ { "Nokia libpcap (tcpdump)", "nokialibpcap",
+ libpcap_dump_can_write_encap, libpcap_dump_open },
+
/* WTAP_FILE_LANALYZER */
{ "Novell LANalyzer", NULL,
NULL, NULL },
diff --git a/wiretap/libpcap.c b/wiretap/libpcap.c
index 028248c53c..b19c76dfcc 100644
--- a/wiretap/libpcap.c
+++ b/wiretap/libpcap.c
@@ -1,6 +1,6 @@
/* libpcap.c
*
- * $Id: libpcap.c,v 1.40 2000/09/12 18:35:47 guy Exp $
+ * $Id: libpcap.c,v 1.41 2000/09/15 07:52:42 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
@@ -38,7 +38,18 @@
#define BIT_SWAPPED_MAC_ADDRS
#endif
+
+/* Try to read the first two records of the capture file. */
+typedef enum {
+ THIS_FORMAT, /* the reads succeeded, assume it's this format */
+ BAD_READ, /* the file is probably not valid */
+ OTHER_FORMAT /* the file may be valid, but not in this format */
+} libpcap_try_t;
+static libpcap_try_t libpcap_try(wtap *wth, int *err);
+
static gboolean libpcap_read(wtap *wth, int *err, int *data_offset);
+static int libpcap_read_header(wtap *wth, int *err,
+ struct pcaprec_ss990915_hdr *hdr, gboolean silent);
static void adjust_header(wtap *wth, struct pcaprec_hdr *hdr);
static void libpcap_close(wtap *wth);
static gboolean libpcap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
@@ -303,9 +314,6 @@ int libpcap_open(wtap *wth, int *err)
gboolean byte_swapped;
gboolean modified;
int file_encap;
- struct pcaprec_modified_hdr first_rec_hdr;
- struct pcaprec_modified_hdr second_rec_hdr;
- int hdr_len;
/* Read in the number that should be at the start of a "libpcap" file */
file_seek(wth->fh, 0, SEEK_SET);
@@ -391,7 +399,6 @@ int libpcap_open(wtap *wth, int *err)
}
/* This is a libpcap file */
- wth->file_type = modified ? WTAP_FILE_PCAP_SS991029 : WTAP_FILE_PCAP;
wth->capture.pcap = g_malloc(sizeof(libpcap_t));
wth->capture.pcap->byte_swapped = byte_swapped;
wth->capture.pcap->version_major = hdr.version_major;
@@ -430,88 +437,261 @@ int libpcap_open(wtap *wth, int *err)
* 6.3, meaning that programs expecting the standard per-
* packet header in captures with the modified magic number
* can't read dumps from its tcpdump.
+ *
+ * Oh, and if it has the standard magic number, it might, instead,
+ * be a Nokia libpcap file, so we may need to try that if
+ * neither normal nor ss990417 headers work.
*/
- hdr_len = modified ? sizeof (struct pcaprec_modified_hdr) :
- sizeof (struct pcaprec_hdr);
- bytes_read = file_read(&first_rec_hdr, 1, hdr_len, wth->fh);
- if (bytes_read != hdr_len) {
- *err = file_error(wth->fh);
- if (*err != 0)
- return -1; /* failed to read it */
+ if (modified) {
+ /*
+ * Well, we have the magic number from Alexey's
+ * later two patches.
+ *
+ * Try ss991029, the last of his patches, first.
+ */
+ wth->file_type = WTAP_FILE_PCAP_SS991029;
+ switch (libpcap_try(wth, err)) {
+
+ case BAD_READ:
+ /*
+ * Well, we couldn't even read it.
+ * Give up.
+ */
+ return -1;
+
+ case THIS_FORMAT:
+ /*
+ * Well, it looks as if it might be 991029.
+ * Put the seek pointer back, and return success.
+ */
+ file_seek(wth->fh, wth->data_offset, SEEK_SET);
+ return 1;
+
+ case OTHER_FORMAT:
+ /*
+ * Try the next format.
+ */
+ break;
+ }
/*
- * Short read - assume the file isn't modified,
- * and put the seek pointer back. The attempt
- * to read the first packet will presumably get
- * the same short read.
+ * Well, it's not completely unreadable,
+ * but it's not ss991029. Try ss990915;
+ * there are no other types to try after that,
+ * so we put the seek pointer back and treat
+ * it as 990915.
*/
- goto give_up;
- }
+ wth->file_type = WTAP_FILE_PCAP_SS990915;
+ file_seek(wth->fh, wth->data_offset, SEEK_SET);
+ } else {
+ /*
+ * Well, we have the standard magic number.
+ *
+ * Try the standard format first.
+ */
+ wth->file_type = WTAP_FILE_PCAP;
+ switch (libpcap_try(wth, err)) {
+
+ case BAD_READ:
+ /*
+ * Well, we couldn't even read it.
+ * Give up.
+ */
+ return -1;
+
+ case THIS_FORMAT:
+ /*
+ * Well, it looks as if it might be a standard
+ * libpcap file.
+ * Put the seek pointer back, and return success.
+ */
+ file_seek(wth->fh, wth->data_offset, SEEK_SET);
+ return 1;
+
+ case OTHER_FORMAT:
+ /*
+ * Try the next format.
+ */
+ break;
+ }
+
+ /*
+ * Well, it's not completely unreadable, but it's not
+ * a standard file. Put the seek pointer back and try
+ * ss990417.
+ */
+ wth->file_type = WTAP_FILE_PCAP_SS990417;
+ file_seek(wth->fh, wth->data_offset, SEEK_SET);
+ switch (libpcap_try(wth, err)) {
+
+ case BAD_READ:
+ /*
+ * Well, we couldn't even read it.
+ * Give up.
+ */
+ return -1;
- adjust_header(wth, &first_rec_hdr.hdr);
+ case THIS_FORMAT:
+ /*
+ * Well, it looks as if it might be ss990417.
+ * Put the seek pointer back, and return success.
+ */
+ file_seek(wth->fh, wth->data_offset, SEEK_SET);
+ return 1;
+
+ case OTHER_FORMAT:
+ /*
+ * Try the next format.
+ */
+ break;
+ }
- if (first_rec_hdr.hdr.incl_len > WTAP_MAX_PACKET_SIZE) {
/*
- * The first record is bogus, so this is probably
- * a corrupt file. Assume the file has the
- * expected header type, and put the seek pointer
- * back. The attempt to read the first packet will
- * probably get the same bogus length.
+ * Well, it's not completely unreadable,
+ * but it's not a standard file *nor* is it ss990417.
+ * Try it as a Nokia file; there are no other types
+ * to try after that, so we put the seek pointer back
+ * and treat it as a Nokia file.
*/
- goto give_up;
+ wth->file_type = WTAP_FILE_PCAP_NOKIA;
+ file_seek(wth->fh, wth->data_offset, SEEK_SET);
}
- file_seek(wth->fh,
- wth->data_offset + hdr_len + first_rec_hdr.hdr.incl_len, SEEK_SET);
- bytes_read = file_read(&second_rec_hdr, 1, hdr_len, wth->fh);
+ return 1;
+}
+/* Try to read the first two records of the capture file. */
+static libpcap_try_t libpcap_try(wtap *wth, int *err)
+{
/*
- * OK, does the next packet's header look sane?
+ * pcaprec_ss990915_hdr is the largest header type.
*/
- if (bytes_read != hdr_len) {
- *err = file_error(wth->fh);
- if (*err != 0)
- return -1; /* failed to read it */
+ struct pcaprec_ss990915_hdr first_rec_hdr, second_rec_hdr;
+
+ /*
+ * Attempt to read the first record's header.
+ */
+ if (libpcap_read_header(wth, err, &first_rec_hdr, TRUE) == -1) {
+ if (*err == WTAP_ERR_SHORT_READ) {
+ /*
+ * Short read - assume the file is in this format.
+ * When our client tries to read the first packet
+ * they will presumably get the same short read.
+ */
+ return THIS_FORMAT;
+ }
+
+ if (*err == WTAP_ERR_BAD_RECORD) {
+ /*
+ * The first record is bogus, so this is probably
+ * a corrupt file. Assume the file is in this
+ * format. When our client tries to read the
+ * first packet they will presumably get the
+ * same bogus record.
+ */
+ return THIS_FORMAT;
+ }
/*
- * Short read - assume the file has the expected
- * header type, and put the seek pointer back. The
- * attempt to read the second packet will presumably get
- * the same short read error.
+ * Some other error, e.g. an I/O error; just give up.
*/
- goto give_up;
+ return BAD_READ;
}
- adjust_header(wth, &second_rec_hdr.hdr);
- if (second_rec_hdr.hdr.incl_len > WTAP_MAX_PACKET_SIZE) {
+ /*
+ * Now skip over the first record's data, under the assumption
+ * that the header is sane.
+ */
+ file_seek(wth->fh, first_rec_hdr.hdr.incl_len, SEEK_CUR);
+
+ /*
+ * Now attempt to read the second record's header.
+ */
+ if (libpcap_read_header(wth, err, &second_rec_hdr, TRUE) == -1) {
+ if (*err == WTAP_ERR_SHORT_READ) {
+ /*
+ * Short read - assume the file is in this format.
+ * When our client tries to read the second packet
+ * they will presumably get the same short read.
+ */
+ return THIS_FORMAT;
+ }
+
+ if (*err == WTAP_ERR_BAD_RECORD) {
+ /*
+ * The second record is bogus; maybe it's a
+ * Capture File From Hell, and what looks like
+ * the "header" of the next packet is actually
+ * random junk from the middle of a packet.
+ * Try the next format; if we run out of formats,
+ * it probably *is* a corrupt file.
+ */
+ return OTHER_FORMAT;
+ }
+
/*
- * Oh, dear. Maybe it's a Capture File
- * From Hell, and what looks like the
- * "header" of the next packet is actually
- * random junk from the middle of a packet.
- * Try treating it as having the other type for
- * the magic number it had; if that doesn't work,
- * it probably *is* a corrupt file.
+ * Some other error, e.g. an I/O error; just give up.
*/
- wth->file_type = modified ? WTAP_FILE_PCAP_SS990915 :
- WTAP_FILE_PCAP_SS990417;
+ return BAD_READ;
}
-give_up:
/*
- * Restore the seek pointer.
+ * OK, the first two records look OK; assume this is the
+ * right format.
*/
- file_seek(wth->fh, wth->data_offset, SEEK_SET);
-
- return 1;
+ return THIS_FORMAT;
}
/* Read the next packet */
static gboolean libpcap_read(wtap *wth, int *err, int *data_offset)
{
- guint packet_size;
- int bytes_to_read, bytes_read;
struct pcaprec_ss990915_hdr hdr;
+ guint packet_size;
+ int bytes_read;
+
+ bytes_read = libpcap_read_header(wth, err, &hdr, FALSE);
+ if (bytes_read == -1) {
+ /*
+ * We failed to read the header.
+ */
+ return FALSE;
+ }
+
+ wth->data_offset += bytes_read;
+ packet_size = hdr.hdr.incl_len;
+
+ buffer_assure_space(wth->frame_buffer, packet_size);
+ *data_offset = wth->data_offset;
+ errno = WTAP_ERR_CANT_READ;
+ bytes_read = file_read(buffer_start_ptr(wth->frame_buffer), 1,
+ packet_size, wth->fh);
+
+ if (bytes_read != packet_size) {
+ *err = file_error(wth->fh);
+ if (*err == 0)
+ *err = WTAP_ERR_SHORT_READ;
+ return FALSE;
+ }
+ wth->data_offset += packet_size;
+
+ wth->phdr.ts.tv_sec = hdr.hdr.ts_sec;
+ wth->phdr.ts.tv_usec = hdr.hdr.ts_usec;
+ wth->phdr.caplen = packet_size;
+ wth->phdr.len = hdr.hdr.orig_len;
+ wth->phdr.pkt_encap = wth->file_encap;
+
+ return TRUE;
+}
+
+/* Read the header of the next packet; if "silent" is TRUE, don't complain
+ to the console, as we're testing to see if the file appears to be of a
+ particular type.
+
+ Return -1 on an error, or the number of bytes of header read on success. */
+static int libpcap_read_header(wtap *wth, int *err,
+ struct pcaprec_ss990915_hdr *hdr, gboolean silent)
+{
+ int bytes_to_read, bytes_read;
/* Read record header. */
errno = WTAP_ERR_CANT_READ;
@@ -530,55 +710,60 @@ static gboolean libpcap_read(wtap *wth, int *err, int *data_offset)
bytes_to_read = sizeof (struct pcaprec_ss990915_hdr);
break;
+ case WTAP_FILE_PCAP_NOKIA:
+ bytes_to_read = sizeof (struct pcaprec_nokia_hdr);
+ break;
+
default:
g_assert_not_reached();
bytes_to_read = 0;
}
- bytes_read = file_read(&hdr, 1, bytes_to_read, wth->fh);
+ bytes_read = file_read(hdr, 1, bytes_to_read, wth->fh);
if (bytes_read != bytes_to_read) {
*err = file_error(wth->fh);
if (*err == 0 && bytes_read != 0) {
*err = WTAP_ERR_SHORT_READ;
}
- return FALSE;
+ return -1;
}
- wth->data_offset += bytes_read;
- adjust_header(wth, &hdr.hdr);
+ adjust_header(wth, &hdr->hdr);
- packet_size = hdr.hdr.incl_len;
- if (packet_size > WTAP_MAX_PACKET_SIZE) {
+ if (hdr->hdr.incl_len > WTAP_MAX_PACKET_SIZE) {
/*
- * Probably a corrupt capture file; don't blow up trying
- * to allocate space for an immensely-large packet.
+ * Probably a corrupt capture file; return an error,
+ * so that our caller doesn't blow up trying to allocate
+ * space for an immensely-large packet, and so that
+ * the code to try to guess what type of libpcap file
+ * this is can tell when it's not the type we're guessing
+ * it is.
*/
- g_message("pcap: File has %u-byte packet, bigger than maximum of %u",
- packet_size, WTAP_MAX_PACKET_SIZE);
+ if (!silent) {
+ g_message("pcap: File has %u-byte packet, bigger than maximum of %u",
+ hdr->hdr.incl_len, WTAP_MAX_PACKET_SIZE);
+ }
*err = WTAP_ERR_BAD_RECORD;
- return FALSE;
+ return -1;
}
- buffer_assure_space(wth->frame_buffer, packet_size);
- *data_offset = wth->data_offset;
- errno = WTAP_ERR_CANT_READ;
- bytes_read = file_read(buffer_start_ptr(wth->frame_buffer), 1,
- packet_size, wth->fh);
-
- if (bytes_read != packet_size) {
- *err = file_error(wth->fh);
- if (*err == 0)
- *err = WTAP_ERR_SHORT_READ;
- return FALSE;
+ if (hdr->hdr.orig_len > WTAP_MAX_PACKET_SIZE) {
+ /*
+ * Probably a corrupt capture file; return an error,
+ * so that our caller doesn't blow up trying to
+ * cope with a huge "real" packet length, and so that
+ * the code to try to guess what type of libpcap file
+ * this is can tell when it's not the type we're guessing
+ * it is.
+ */
+ if (!silent) {
+ g_message("pcap: File has %u-byte packet, bigger than maximum of %u",
+ hdr->hdr.orig_len, WTAP_MAX_PACKET_SIZE);
+ }
+ *err = WTAP_ERR_BAD_RECORD;
+ return -1;
}
- wth->data_offset += packet_size;
-
- wth->phdr.ts.tv_sec = hdr.hdr.ts_sec;
- wth->phdr.ts.tv_usec = hdr.hdr.ts_usec;
- wth->phdr.caplen = packet_size;
- wth->phdr.len = hdr.hdr.orig_len;
- wth->phdr.pkt_encap = wth->file_encap;
- return TRUE;
+ return bytes_read;
}
static void
@@ -680,6 +865,7 @@ gboolean libpcap_dump_open(wtap_dumper *wdh, int *err)
case WTAP_FILE_PCAP:
case WTAP_FILE_PCAP_SS990417: /* modified, but with the old magic, sigh */
+ case WTAP_FILE_PCAP_NOKIA: /* Nokia libpcap of some sort */
magic = PCAP_MAGIC;
break;
@@ -778,6 +964,15 @@ static gboolean libpcap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
hdr_size = sizeof (struct pcaprec_ss990915_hdr);
break;
+ case WTAP_FILE_PCAP_NOKIA: /* old magic, extra crap at the end */
+ rec_hdr.ifindex = 0;
+ rec_hdr.protocol = 0;
+ rec_hdr.pkt_type = 0;
+ rec_hdr.cpu1 = 0;
+ rec_hdr.cpu2 = 0;
+ hdr_size = sizeof (struct pcaprec_nokia_hdr);
+ break;
+
default:
/* We should never get here - our open routine
should only get called for the types above. */
diff --git a/wiretap/libpcap.h b/wiretap/libpcap.h
index 28b50a8f89..937d2ea262 100644
--- a/wiretap/libpcap.h
+++ b/wiretap/libpcap.h
@@ -1,6 +1,6 @@
/* libpcap.h
*
- * $Id: libpcap.h,v 1.9 2000/08/11 13:32:35 deniel Exp $
+ * $Id: libpcap.h,v 1.10 2000/09/15 07:52:43 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
@@ -86,6 +86,12 @@ struct pcaprec_ss990915_hdr {
guint8 pad[3]; /* pad to a 4-byte boundary */
};
+/* "libpcap" record header for version used on some Nokia boxes (firewalls?) */
+struct pcaprec_nokia_hdr {
+ struct pcaprec_hdr hdr; /* the regular header */
+ guint8 stuff[4]; /* mysterious stuff */
+};
+
int libpcap_open(wtap *wth, int *err);
gboolean libpcap_dump_open(wtap_dumper *wdh, int *err);
int libpcap_dump_can_write_encap(int filetype, int encap);
diff --git a/wiretap/wtap.h b/wiretap/wtap.h
index bc429651f8..313b464975 100644
--- a/wiretap/wtap.h
+++ b/wiretap/wtap.h
@@ -1,6 +1,6 @@
/* wtap.h
*
- * $Id: wtap.h,v 1.78 2000/09/07 05:34:23 gram Exp $
+ * $Id: wtap.h,v 1.79 2000/09/15 07:52:43 guy Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@xiexie.org>
@@ -98,34 +98,35 @@
#define WTAP_NUM_ENCAP_TYPES 17
/* File types that can be read by wiretap.
- We may eventually support writing some or all of these file types,
- too, so we distinguish between different versions of them. */
+ We support writing some many of these file types, too, so we
+ distinguish between different versions of them. */
#define WTAP_FILE_UNKNOWN 0
#define WTAP_FILE_WTAP 1
#define WTAP_FILE_PCAP 2
#define WTAP_FILE_PCAP_SS990417 3
#define WTAP_FILE_PCAP_SS990915 4
#define WTAP_FILE_PCAP_SS991029 5
-#define WTAP_FILE_LANALYZER 6
-#define WTAP_FILE_NGSNIFFER_UNCOMPRESSED 7
-#define WTAP_FILE_NGSNIFFER_COMPRESSED 8
-#define WTAP_FILE_SNOOP 9
-#define WTAP_FILE_IPTRACE_1_0 10
-#define WTAP_FILE_IPTRACE_2_0 11
-#define WTAP_FILE_NETMON_1_x 12
-#define WTAP_FILE_NETMON_2_x 13
-#define WTAP_FILE_NETXRAY_1_0 14
-#define WTAP_FILE_NETXRAY_1_1 15
-#define WTAP_FILE_NETXRAY_2_00x 16
-#define WTAP_FILE_RADCOM 17
-#define WTAP_FILE_ASCEND 18
-#define WTAP_FILE_NETTL 19
-#define WTAP_FILE_TOSHIBA 20
-#define WTAP_FILE_I4BTRACE 21
-#define WTAP_FILE_CSIDS 22
+#define WTAP_FILE_PCAP_NOKIA 6
+#define WTAP_FILE_LANALYZER 7
+#define WTAP_FILE_NGSNIFFER_UNCOMPRESSED 8
+#define WTAP_FILE_NGSNIFFER_COMPRESSED 9
+#define WTAP_FILE_SNOOP 10
+#define WTAP_FILE_IPTRACE_1_0 11
+#define WTAP_FILE_IPTRACE_2_0 12
+#define WTAP_FILE_NETMON_1_x 13
+#define WTAP_FILE_NETMON_2_x 14
+#define WTAP_FILE_NETXRAY_1_0 15
+#define WTAP_FILE_NETXRAY_1_1 16
+#define WTAP_FILE_NETXRAY_2_00x 17
+#define WTAP_FILE_RADCOM 18
+#define WTAP_FILE_ASCEND 19
+#define WTAP_FILE_NETTL 20
+#define WTAP_FILE_TOSHIBA 21
+#define WTAP_FILE_I4BTRACE 22
+#define WTAP_FILE_CSIDS 23
/* last WTAP_FILE_ value + 1 */
-#define WTAP_NUM_FILE_TYPES 23
+#define WTAP_NUM_FILE_TYPES 24
/*
* Maximum packet size we'll support.