diff options
-rw-r--r-- | AUTHORS | 5 | ||||
-rw-r--r-- | doc/ethereal.pod | 1 | ||||
-rw-r--r-- | wiretap/AUTHORS | 1 | ||||
-rw-r--r-- | wiretap/Makefile.am | 4 | ||||
-rw-r--r-- | wiretap/Makefile.nmake | 5 | ||||
-rw-r--r-- | wiretap/airopeek9.c | 278 | ||||
-rw-r--r-- | wiretap/airopeek9.h | 29 | ||||
-rw-r--r-- | wiretap/file_access.c | 8 | ||||
-rw-r--r-- | wiretap/wtap.h | 5 |
9 files changed, 330 insertions, 6 deletions
@@ -1935,6 +1935,11 @@ David Fort <david.fort [AT] irisa.fr> { DNS DSS RR support } +Martijn Schipper <mschipper [AT] globespanvirata.com> { + Support for reading AiroPeek files in V9 capture file format + (AiroPeek 2.x) +} + And assorted fixes and enhancements by the people listed above and by: Pavel Roskin <proski [AT] gnu.org> diff --git a/doc/ethereal.pod b/doc/ethereal.pod index bdc6977dcd..b9bfdc9275 100644 --- a/doc/ethereal.pod +++ b/doc/ethereal.pod @@ -2057,6 +2057,7 @@ B<http://www.ethereal.com>. Dave Sclarsky <dave_sclarsky [AT] cnt.com> Scott Hovis <scott.hovis [AT] ums.msfc.nasa.gov> David Fort <david.fort [AT] irisa.fr> + Martijn Schipper <mschipper [AT] globespanvirata.com> Pavel Roskin <proski [AT] gnu.org> Georgi Guninski <guninski [AT] guninski.com> Jason Copenhaver <jcopenha [AT] typedef.org> diff --git a/wiretap/AUTHORS b/wiretap/AUTHORS index 5216c86a3d..f7775cb502 100644 --- a/wiretap/AUTHORS +++ b/wiretap/AUTHORS @@ -21,3 +21,4 @@ Thierry Martin <thierry.martin[AT]accellent-group.com> Jesper Peterson <jesper[AT]endace.com> Marcel Holtmann <marcel[AT]holtmann.org> Scott Emberley <scotte[AT]netinst.com> +Martijn Schipper <mschipper[AT]globespanvirata.com> diff --git a/wiretap/Makefile.am b/wiretap/Makefile.am index 7b7acb9ee6..beb6fee9b5 100644 --- a/wiretap/Makefile.am +++ b/wiretap/Makefile.am @@ -1,7 +1,7 @@ # Makefile.am # Automake file for Wiretap # -# $Id: Makefile.am,v 1.47 2003/10/31 00:43:21 guy Exp $ +# $Id: Makefile.am,v 1.48 2003/12/02 19:37:04 guy Exp $ # # Ethereal - Network traffic analyzer # By Gerald Combs <gerald@ethereal.com> @@ -32,6 +32,8 @@ CLEANFILES = \ *~ libwiretap_a_SOURCES = \ + airopeek9.c \ + airopeek9.h \ ascend-grammar.y \ ascend-scanner.l \ ascend.c \ diff --git a/wiretap/Makefile.nmake b/wiretap/Makefile.nmake index c5a8813d1b..e25eae6d4b 100644 --- a/wiretap/Makefile.nmake +++ b/wiretap/Makefile.nmake @@ -1,5 +1,5 @@ # -# $Id: Makefile.nmake,v 1.38 2003/11/07 23:27:13 guy Exp $ +# $Id: Makefile.nmake,v 1.39 2003/12/02 19:37:04 guy Exp $ # include ..\config.nmake @@ -13,7 +13,8 @@ CFLAGS=-DHAVE_CONFIG_H $(GLIB_CFLAGS) $(ZLIB_CFLAGS) /I$(PCAP_DIR)/include \ .c.obj:: $(CC) $(cvarsdll) $(CFLAGS) -Fd.\ -c $< -OBJECTS=ascend-grammar.obj \ +OBJECTS=airopeek9.obj \ + ascend-grammar.obj \ ascend-scanner.obj \ ascend.obj \ atm.obj \ diff --git a/wiretap/airopeek9.c b/wiretap/airopeek9.c new file mode 100644 index 0000000000..7cf2be3523 --- /dev/null +++ b/wiretap/airopeek9.c @@ -0,0 +1,278 @@ +/* airopeek9.c + * Routines for opening AiroPeek V9 files + * + * $Id: airopeek9.c,v 1.1 2003/12/02 19:37:05 guy Exp $ + * + * Wiretap Library + * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include <errno.h> +#include <string.h> +#include <stdlib.h> +#include "wtap-int.h" +#include "file_wrappers.h" +#include "buffer.h" +#include "airopeek9.h" + +/* CREDITS + * + * This file decoder could not have been writen without examining + * http://www.varsanofiev.com/inside/airopeekv9.htm, the help from + * Martin Regner and Guy Harris, and the etherpeek.c file. + */ + +/* section header */ +typedef struct airopeek_section_header { + gint8 section_id[4]; + guint32 section_len; + guint32 section_const; +} airopeek_section_header_t; + +#define AIROPEEK_V9_LENGTH_OFFSET 2 +#define AIROPEEK_V9_TIMESTAMP_LOWER_OFFSET 8 +#define AIROPEEK_V9_TIMESTAMP_UPPER_OFFSET 14 +#define AIROPEEK_V9_FLAGS_OFFSET 20 +#define AIROPEEK_V9_STATUS_OFFSET 22 +#define AIROPEEK_V9_CHANNEL_OFFSET 26 +#define AIROPEEK_V9_RATE_OFFSET 32 +#define AIROPEEK_V9_SIGNAL_PERC_OFFSET 38 +#define AIROPEEK_V9_SIGNAL_DBM_OFFSET 44 +#define AIROPEEK_V9_NOISE_PERC_OFFSET 50 +#define AIROPEEK_V9_NOISE_DBM_OFFSET 56 +#define AIROPEEK_V9_SLICE_LENGTH_OFFSET 62 + +#define AIROPEEK_V9_PKT_SIZE 66 + +/* 64-bit time in nano seconds from the (Mac) epoch */ +typedef struct airopeek_utime { + guint32 upper; + guint32 lower; +} airopeek_utime; + +static const unsigned int mac2unix = 2082844800u; + +static gboolean airopeek_read_v9(wtap *wth, int *err, long *data_offset); +static gboolean airopeek_seek_read_v9(wtap *wth, long seek_off, + union wtap_pseudo_header *pseudo_header, guchar *pd, int length, int *err); + +static int wtap_file_read_pattern (wtap *wth, char *pattern, int *err) +{ + char c; + char *cp; + + cp = pattern; + while (*cp) + { + wtap_file_read_unknown_bytes(&c, 1, wth->fh, err); + if (c == *cp) + cp++; + else + { + if (c == pattern[0]) + cp = &pattern[1]; + else + cp = pattern; + } + } + return (*cp == '\0' ? TRUE : FALSE); +} + + +static int wtap_file_read_till_separator (wtap *wth, char *buffer, int buflen, + char *separators, int *err) +{ + char c; + char *cp; + int i; + + for (cp = buffer, i = 0; i < buflen; i++, cp++) + { + wtap_file_read_unknown_bytes(&c, 1, wth->fh, err); + if (strchr (separators, c)) + { + *cp = '\0'; + break; + } + else + *cp = c; + } + return i; +} + + +static gboolean wtap_file_read_number (wtap *wth, guint32 *num, int *err) +{ + char str_num[12]; + unsigned long long value; + char *p; + + wtap_file_read_till_separator (wth, str_num, sizeof (str_num)-1, "<", err); + value = strtoul (str_num, &p, 10); + if (p == str_num || value > UINT_MAX) + return FALSE; + *num = value; + return TRUE; +} + + +int airopeek9_open(wtap *wth, int *err) +{ + airopeek_section_header_t ap_hdr; + guint32 fileVersion; + guint32 mediaType; + int file_encap; + + wtap_file_read_unknown_bytes(&ap_hdr, sizeof(ap_hdr), wth->fh, err); + + if (memcmp (ap_hdr.section_id, "\177ver", sizeof(ap_hdr.section_id)) || + wtap_file_read_pattern (wth, "<FileVersion>", err) == FALSE || + wtap_file_read_number (wth, &fileVersion, err) == FALSE || + fileVersion != 9 || + wtap_file_read_pattern (wth, "<MediaType>", err) == FALSE || + wtap_file_read_number (wth, &mediaType, err) == FALSE) + return 0; + + if (wtap_file_read_pattern (wth, "pkts", err) == FALSE) + return 0; + + /* skip 8 zero bytes */ + if (file_seek (wth->fh, 8L, SEEK_CUR, err) == -1) + return 0; + + /* + * This is an AiroPeek V9 file. + */ + + wth->data_offset = file_tell (wth->fh); + + file_encap = WTAP_ENCAP_IEEE_802_11_WITH_RADIO; + + wth->file_type = WTAP_FILE_AIROPEEK_V9; + wth->file_encap = file_encap; + wth->subtype_read = airopeek_read_v9; + wth->subtype_seek_read = airopeek_seek_read_v9; + + wth->snapshot_length = 0; /* not available in header */ + + return 1; +} + +static gboolean airopeek_read_v9(wtap *wth, int *err, long *data_offset) +{ + guchar ap_pkt[AIROPEEK_V9_PKT_SIZE]; + guint32 length; + guint32 sliceLength; + airopeek_utime timestamp; + double t; + + *data_offset = wth->data_offset; + + wtap_file_read_expected_bytes(ap_pkt, sizeof(ap_pkt), wth->fh, err); + wth->data_offset += sizeof(ap_pkt); + + /* Extract the fields from the packet */ + length = pletohl(&ap_pkt[AIROPEEK_V9_LENGTH_OFFSET]); + sliceLength = pletohl(&ap_pkt[AIROPEEK_V9_SLICE_LENGTH_OFFSET]); + timestamp.upper = pletohl(&ap_pkt[AIROPEEK_V9_TIMESTAMP_UPPER_OFFSET]); + timestamp.lower = pletohl(&ap_pkt[AIROPEEK_V9_TIMESTAMP_LOWER_OFFSET]); + + /* force sliceLength to be the actual length of the packet */ + if (sliceLength == 0) { + sliceLength = length; + } + + /* fill in packet header length values before slicelength may be + adjusted */ + wth->phdr.len = length; + wth->phdr.caplen = sliceLength; + + /* + * Fill the pseudo header with radio information. + * XXX - we should supply the additional information; + * the pseudo-header should probably be supplied in a fashion + * similar to the new BSD radio header, so that the 802.11 + * dissector can determine which, if any, information items + * are present. + */ + wth->pseudo_header.ieee_802_11.channel = + pletohl(&ap_pkt[AIROPEEK_V9_CHANNEL_OFFSET]); + wth->pseudo_header.ieee_802_11.data_rate = + pletohl(&ap_pkt[AIROPEEK_V9_RATE_OFFSET]); + wth->pseudo_header.ieee_802_11.signal_level = + pletohl(&ap_pkt[AIROPEEK_V9_SIGNAL_PERC_OFFSET]); + + /* read the frame data */ + buffer_assure_space(wth->frame_buffer, sliceLength); + wtap_file_read_expected_bytes(buffer_start_ptr(wth->frame_buffer), + sliceLength, wth->fh, err); + wth->data_offset += sliceLength; + + /* recalculate and fill in packet time stamp */ + t = (double) timestamp.lower + + (double) timestamp.upper * 4294967296.0; + + t = t / 1000.0; /* nano seconds -> micro seconds */ + t -= (double) mac2unix * 1000000.0; + wth->phdr.ts.tv_sec = (time_t) (t/1000000.0); + wth->phdr.ts.tv_usec = (guint32) (t - (double) wth->phdr.ts.tv_sec * + 1000000.0); + + /* + * The last 4 bytes sometimes contains the FCS but on a lot of + * interfaces these are zero. To eleminate problems we reduce + * the length by 4. + * + * XXX - is there any way to find out whether it's an FCS or not? + */ + wth->phdr.len -= 4; + wth->phdr.caplen -= 4; + + wth->phdr.pkt_encap = wth->file_encap; + return TRUE; +} + + +static gboolean +airopeek_seek_read_v9(wtap *wth, long seek_off, + union wtap_pseudo_header *pseudo_header, guchar *pd, int length, int *err) +{ + guchar ap_pkt[AIROPEEK_V9_PKT_SIZE]; + + if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) + return FALSE; + + /* Read the packet header. */ + wtap_file_read_expected_bytes(ap_pkt, sizeof(ap_pkt), wth->random_fh, err); + + pseudo_header->ieee_802_11.channel = + pletohl(&ap_pkt[AIROPEEK_V9_CHANNEL_OFFSET]); + pseudo_header->ieee_802_11.data_rate = + pletohl(&ap_pkt[AIROPEEK_V9_RATE_OFFSET]); + pseudo_header->ieee_802_11.signal_level = + pletohl(&ap_pkt[AIROPEEK_V9_SIGNAL_PERC_OFFSET]); + + /* + * XXX - should "errno" be set in "wtap_file_read_expected_bytes()"? + */ + errno = WTAP_ERR_CANT_READ; + wtap_file_read_expected_bytes(pd, length, wth->random_fh, err); + return TRUE; +} diff --git a/wiretap/airopeek9.h b/wiretap/airopeek9.h new file mode 100644 index 0000000000..ce2435db1a --- /dev/null +++ b/wiretap/airopeek9.h @@ -0,0 +1,29 @@ +/* airopeek9.h + * + * $Id: airopeek9.h,v 1.1 2003/12/02 19:37:05 guy Exp $ + * + * Wiretap Library + * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef __W_AIROPEEK9_H__ +#define __W_AIROPEEK9_H__ + +int airopeek9_open(wtap *wth, int *err); + +#endif diff --git a/wiretap/file_access.c b/wiretap/file_access.c index 9a88b79671..47d475a198 100644 --- a/wiretap/file_access.c +++ b/wiretap/file_access.c @@ -1,6 +1,6 @@ /* file_access.c * - * $Id: file_access.c,v 1.7 2003/12/01 06:59:10 sharpe Exp $ + * $Id: file_access.c,v 1.8 2003/12/02 19:37:05 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu> @@ -50,6 +50,7 @@ #include "file_wrappers.h" #include "buffer.h" #include "lanalyzer.h" +#include "airopeek9.h" #include "ngsniffer.h" #include "radcom.h" #include "ascend.h" @@ -106,6 +107,7 @@ static int (*const open_routines[])(wtap *, int *) = { visual_open, _5views_open, network_instruments_open, + airopeek9_open, /* Files that don't have magic bytes at a fixed location, * but that instead require a heuristic of some sort to @@ -447,6 +449,10 @@ static const struct file_type_info { /* WTAP_FILE_NETWORK_INSTRUMENTS_V9 */ { "Network Instruments Observer version 9", "niobserverv9", network_instruments_dump_can_write_encap, network_instruments_dump_open }, + + /* WTAP_FILE_AIROPEEK_V9 */ + { "AiroPeek trace (V9 file format)", NULL, + NULL, NULL }, }; /* Name that should be somewhat descriptive. */ diff --git a/wiretap/wtap.h b/wiretap/wtap.h index cdc174b7e8..66731b6fdd 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -1,6 +1,6 @@ /* wtap.h * - * $Id: wtap.h,v 1.144 2003/10/31 00:43:21 guy Exp $ + * $Id: wtap.h,v 1.145 2003/12/02 19:37:05 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu> @@ -175,9 +175,10 @@ #define WTAP_FILE_ERF 35 #define WTAP_FILE_HCIDUMP 36 #define WTAP_FILE_NETWORK_INSTRUMENTS_V9 37 +#define WTAP_FILE_AIROPEEK_V9 38 /* last WTAP_FILE_ value + 1 */ -#define WTAP_NUM_FILE_TYPES 38 +#define WTAP_NUM_FILE_TYPES 39 /* * Maximum packet size we'll support. |