From 148d0c865a696eee0dbd7476b3e3d7c775961aee Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Sat, 6 Nov 1999 08:42:01 +0000 Subject: [PATCH] Add support for capture files written by programs linked with Alexey Kuznetsov's modified "libpcap" *as long as you have the ss990915 or later patch*; the 990417 patch, alas, changes the per-packet header but *doesn't* change the magic number, so you can't just look at the magic number to see that it's Not Standard Libpcap. (Even more unfortunately, Red Hat appears to have picked up *that* patch for Red Hat 6.1; I've filed bug 6773 with Bugzilla on their site - hopefully, if I'm not misremembering the RH 6.1 code I've seen, and they really *did* pick up the older patch, they'll fix it ASAP to use the new magic number, and will make updates available.) svn path=/trunk/; revision=986 --- wiretap/libpcap.c | 102 ++++++++++++++++++++++++++++++++++------------ wiretap/wtap.h | 5 ++- 2 files changed, 78 insertions(+), 29 deletions(-) diff --git a/wiretap/libpcap.c b/wiretap/libpcap.c index f4dfc19d35..2580c15066 100644 --- a/wiretap/libpcap.c +++ b/wiretap/libpcap.c @@ -1,6 +1,6 @@ /* libpcap.c * - * $Id: libpcap.c,v 1.21 1999/10/05 07:06:06 guy Exp $ + * $Id: libpcap.c,v 1.22 1999/11/06 08:42:00 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez @@ -39,9 +39,19 @@ writes them, and the reader is expected to fix this up. PCAP_MAGIC is the magic number, in host byte order; PCAP_SWAPPED_MAGIC - is a byte-swapped version of that. */ -#define PCAP_MAGIC 0xa1b2c3d4 -#define PCAP_SWAPPED_MAGIC 0xd4c3b2a1 + is a byte-swapped version of that. + + PCAP_MUTANT_MAGIC is for Alexey Kuznetsov's modified "libpcap" + format, as generated on Linux systems that have a "libpcap" with + his patches, at + + http://ftp.sunet.se/pub/os/Linux/ip-routing/lbl-tools/ + + applied; PCAP_SWAPPED_MUTANT_MAGIC is the byte-swapped version. */ +#define PCAP_MAGIC 0xa1b2c3d4 +#define PCAP_SWAPPED_MAGIC 0xd4c3b2a1 +#define PCAP_MUTANT_MAGIC 0xa1b2cd34 +#define PCAP_SWAPPED_MUTANT_MAGIC 0x34cdb2a1 /* Macros to byte-swap 32-bit and 16-bit quantities. */ #define BSWAP32(x) \ @@ -76,6 +86,16 @@ struct pcaprec_hdr { guint32 orig_len; /* actual length of packet */ }; +/* "libpcap" record header for Alexey's patched version. */ +struct pcaprec_mutant_hdr { + struct pcaprec_hdr hdr; /* the regular header */ + guint32 ifindex; /* index, in *capturing* machine's list of + interfaces, of the interface on which this + packet came in. */ + guint16 protocol; /* Ethernet packet type */ + guint8 pkt_type; /* broadcast/multicast/etc. indication */ +}; + static int libpcap_read(wtap *wth, int *err); static int libpcap_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr, const u_char *pd, int *err); @@ -144,7 +164,8 @@ int libpcap_open(wtap *wth, int *err) int bytes_read; guint32 magic; struct pcap_hdr hdr; - int byte_swapped = 0; + gboolean byte_swapped = FALSE; + gboolean mutant = FALSE; /* Read in the number that should be at the start of a "libpcap" file */ file_seek(wth->fh, 0, SEEK_SET); @@ -159,12 +180,37 @@ int libpcap_open(wtap *wth, int *err) } wth->data_offset += sizeof magic; - if (magic == PCAP_SWAPPED_MAGIC) { + switch (magic) { + + case PCAP_MAGIC: + /* Host that wrote it has our byte order. */ + byte_swapped = FALSE; + mutant = FALSE; + break; + + case PCAP_MUTANT_MAGIC: + /* Host that wrote it has our byte order, but was running + a program using the patched "libpcap". */ + byte_swapped = FALSE; + mutant = TRUE; + break; + + case PCAP_SWAPPED_MAGIC: /* Host that wrote it has a byte order opposite to ours. */ - magic = PCAP_MAGIC; - byte_swapped = 1; - } - if (magic != PCAP_MAGIC) { + byte_swapped = TRUE; + mutant = FALSE; + break; + + case PCAP_SWAPPED_MUTANT_MAGIC: + /* Host that wrote it out has a byte order opposite to + ours, and was running a program using the patched + "libpcap". */ + byte_swapped = TRUE; + mutant = TRUE; + break; + + default: + /* Not a "libpcap" type we know about. */ return 0; } @@ -205,6 +251,7 @@ int libpcap_open(wtap *wth, int *err) wth->file_type = WTAP_FILE_PCAP; wth->capture.pcap = g_malloc(sizeof(libpcap_t)); wth->capture.pcap->byte_swapped = byte_swapped; + wth->capture.pcap->mutant = mutant; wth->capture.pcap->version_major = hdr.version_major; wth->capture.pcap->version_minor = hdr.version_minor; wth->subtype_read = libpcap_read; @@ -217,14 +264,15 @@ int libpcap_open(wtap *wth, int *err) static int libpcap_read(wtap *wth, int *err) { guint packet_size; - int bytes_read; - struct pcaprec_hdr hdr; + int bytes_to_read, bytes_read; + struct pcaprec_mutant_hdr hdr; int data_offset; /* Read record header. */ errno = WTAP_ERR_CANT_READ; - bytes_read = file_read(&hdr, 1, sizeof hdr, wth->fh); - if (bytes_read != sizeof hdr) { + bytes_to_read = wth->capture.pcap->mutant ? sizeof hdr : sizeof hdr.hdr; + 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) return -1; @@ -234,14 +282,14 @@ static int libpcap_read(wtap *wth, int *err) } return 0; } - wth->data_offset += sizeof hdr; + wth->data_offset += bytes_read; if (wth->capture.pcap->byte_swapped) { /* Byte-swap the record header fields. */ - hdr.ts_sec = BSWAP32(hdr.ts_sec); - hdr.ts_usec = BSWAP32(hdr.ts_usec); - hdr.incl_len = BSWAP32(hdr.incl_len); - hdr.orig_len = BSWAP32(hdr.orig_len); + hdr.hdr.ts_sec = BSWAP32(hdr.hdr.ts_sec); + hdr.hdr.ts_usec = BSWAP32(hdr.hdr.ts_usec); + hdr.hdr.incl_len = BSWAP32(hdr.hdr.incl_len); + hdr.hdr.orig_len = BSWAP32(hdr.hdr.orig_len); } /* In file format version 2.3, the "incl_len" and "orig_len" fields @@ -255,15 +303,15 @@ static int libpcap_read(wtap *wth, int *err) if (wth->capture.pcap->version_major == 2 && (wth->capture.pcap->version_minor < 3 || (wth->capture.pcap->version_minor == 3 && - hdr.incl_len > hdr.orig_len))) { + hdr.hdr.incl_len > hdr.hdr.orig_len))) { guint32 temp; - temp = hdr.orig_len; - hdr.orig_len = hdr.incl_len; - hdr.incl_len = temp; + temp = hdr.hdr.orig_len; + hdr.hdr.orig_len = hdr.hdr.incl_len; + hdr.hdr.incl_len = temp; } - packet_size = hdr.incl_len; + packet_size = hdr.hdr.incl_len; if (packet_size > WTAP_MAX_PACKET_SIZE) { /* * Probably a corrupt capture file; don't blow up trying @@ -289,10 +337,10 @@ static int libpcap_read(wtap *wth, int *err) } wth->data_offset += packet_size; - wth->phdr.ts.tv_sec = hdr.ts_sec; - wth->phdr.ts.tv_usec = hdr.ts_usec; + 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.orig_len; + wth->phdr.len = hdr.hdr.orig_len; wth->phdr.pkt_encap = wth->file_encap; return data_offset; diff --git a/wiretap/wtap.h b/wiretap/wtap.h index 6f73d558ea..bf1471a8b8 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -1,6 +1,6 @@ /* wtap.h * - * $Id: wtap.h,v 1.46 1999/10/31 17:46:11 gram Exp $ + * $Id: wtap.h,v 1.47 1999/11/06 08:42:01 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez @@ -159,7 +159,8 @@ typedef struct { } lanalyzer_t; typedef struct { - int byte_swapped; + gboolean byte_swapped; + gboolean mutant; guint16 version_major; guint16 version_minor; } libpcap_t;