aboutsummaryrefslogtreecommitdiffstats
path: root/wiretap
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2003-12-02 19:37:05 +0000
committerGuy Harris <guy@alum.mit.edu>2003-12-02 19:37:05 +0000
commitfe73d8e3b662f6027ac672a1d8dc6881684fb602 (patch)
tree378d6cbb9c357922cb69f69a1c9c064546627374 /wiretap
parent37b5a4786fd82aa1b71fd0d81877b2982d33a369 (diff)
From Martijn Schipper: support for reading AiroPeek files in V9 capture
file format (AiroPeek 2.x). svn path=/trunk/; revision=9144
Diffstat (limited to 'wiretap')
-rw-r--r--wiretap/AUTHORS1
-rw-r--r--wiretap/Makefile.am4
-rw-r--r--wiretap/Makefile.nmake5
-rw-r--r--wiretap/airopeek9.c278
-rw-r--r--wiretap/airopeek9.h29
-rw-r--r--wiretap/file_access.c8
-rw-r--r--wiretap/wtap.h5
7 files changed, 324 insertions, 6 deletions
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.