aboutsummaryrefslogtreecommitdiffstats
path: root/packet-prism.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2001-11-28 07:11:11 +0000
committerGuy Harris <guy@alum.mit.edu>2001-11-28 07:11:11 +0000
commit56636f157abdc8472bcf43de4837d5af2058de16 (patch)
treebbe4c8fe37fb2677a6f3f3ab3313b96935381174 /packet-prism.c
parentc0b335070c3b8156aed2bf2bf85110ddf9c8275e (diff)
Support for 802.11+Prism II monitor-mode link-layer headers, from
Tim Newsham. Add in missing item for WTAP_ENCAP_CISCO_IOS in the Wiretap encapsulation type table. svn path=/trunk/; revision=4290
Diffstat (limited to 'packet-prism.c')
-rw-r--r--packet-prism.c209
1 files changed, 209 insertions, 0 deletions
diff --git a/packet-prism.c b/packet-prism.c
new file mode 100644
index 0000000000..3a4092f793
--- /dev/null
+++ b/packet-prism.c
@@ -0,0 +1,209 @@
+/*
+ * packet-prism.c
+ * Decode packets with a prism header
+ *
+ * prism wlan devices have a monitoring mode that sticks
+ * a proprietary header on each packet with lots of good
+ * information. This file is responsible for decoding that
+ * data.
+ *
+ * By Tim Newsham
+ *
+ * $Id: packet-prism.c,v 1.1 2001/11/28 07:11:07 guy Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * Copyright 1998 Gerald Combs
+ *
+ * Copied from README.developer
+ *
+ * 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
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#include <glib.h>
+
+#include "packet.h"
+#include "packet-ieee80211.h"
+#include "packet-prism.h"
+
+/* protocol */
+static int proto_prism = -1;
+
+/* header fields */
+static int hf_prism_msgcode = -1;
+static int hf_prism_msglen = -1;
+
+/* a 802.11 value */
+struct val_80211 {
+ unsigned int did;
+ unsigned short status, len;
+ unsigned int data;
+};
+
+/* header attached during prism monitor mode */
+struct prism_hdr {
+ unsigned int msgcode, msglen;
+ char devname[16];
+ struct val_80211 hosttime, mactime, channel, rssi, sq, signal,
+ noise, rate, istx, frmlen;
+};
+
+#define VALFIELDS(name) \
+ static int hf_prism_ ## name ## _data = -1
+VALFIELDS(hosttime);
+VALFIELDS(mactime);
+VALFIELDS(channel);
+VALFIELDS(rssi);
+VALFIELDS(sq);
+VALFIELDS(signal);
+VALFIELDS(noise);
+VALFIELDS(rate);
+VALFIELDS(istx);
+VALFIELDS(frmlen);
+
+static gint ett_prism = -1;
+
+static dissector_handle_t ieee80211_handle;
+
+void
+capture_prism(const u_char *pd, int offset, int len, packet_counts *ld)
+{
+ if(!BYTES_ARE_IN_FRAME(offset, len, (int)sizeof(struct prism_hdr))) {
+ ld->other ++;
+ return;
+ }
+ offset += sizeof(struct prism_hdr);
+
+ /* 802.11 header follows */
+ capture_ieee80211(pd, offset, len, ld);
+}
+
+/*
+ * yah, I know, macros, ugh, but it makes the code
+ * below more readable
+ */
+#define IFHELP(size, name, var, str) \
+ proto_tree_add_uint_format(prism_tree, hf_prism_ ## name, \
+ tvb, offset, size, hdr. ## var, str, hdr. ## var); \
+ offset += (size)
+#define INTFIELD(size, name, str) IFHELP(size, name, name, str)
+#define VALFIELD(name, str) \
+ proto_tree_add_uint_format(prism_tree, hf_prism_ ## name ## _data, \
+ tvb, offset, 12, hdr. ## name ## .data, \
+ str ": 0x%x (DID 0x%x, Status 0x%x, Length 0x%x)", \
+ hdr. ## name ## .data, hdr. ## name ## .did, \
+ hdr. ## name ## .status, hdr. ## name ## .len); \
+ offset += 12
+
+static void
+dissect_prism(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ struct prism_hdr hdr;
+ proto_tree *prism_tree;
+ proto_item *ti;
+ tvbuff_t *next_tvb;
+ int offset;
+
+ if(check_col(pinfo->fd, COL_PROTOCOL))
+ col_set_str(pinfo->fd, COL_PROTOCOL, "Prism");
+ if(check_col(pinfo->fd, COL_INFO))
+ col_clear(pinfo->fd, COL_INFO);
+
+ offset = 0;
+ tvb_memcpy(tvb, (guint8 *)&hdr, offset, sizeof hdr);
+
+ if(check_col(pinfo->fd, COL_INFO))
+ col_add_fstr(pinfo->fd, COL_INFO, "Device: %.16s "
+ "Message 0x%x, Length %d", hdr.devname,
+ hdr.msgcode, hdr.msglen);
+
+ if(tree) {
+ ti = proto_tree_add_protocol_format(tree, proto_prism,
+ tvb, 0, sizeof hdr, "Prism Monitoring Header");
+ prism_tree = proto_item_add_subtree(ti, ett_prism);
+
+ INTFIELD(4, msgcode, "Message Code: %d");
+ INTFIELD(4, msglen, "Message Length: %d");
+ proto_tree_add_text(prism_tree, tvb, offset, sizeof hdr.devname,
+ "Device: %s", hdr.devname);
+ offset += sizeof hdr.devname;
+
+ VALFIELD(hosttime, "Host Time");
+ VALFIELD(mactime, "MAC Time");
+ VALFIELD(channel, "Channel Time");
+ VALFIELD(rssi, "RSSI");
+ VALFIELD(sq, "SQ");
+ VALFIELD(signal, "Signal");
+ VALFIELD(noise, "Noise");
+ VALFIELD(rate, "Rate");
+ VALFIELD(istx, "IsTX");
+ VALFIELD(frmlen, "Frame Length");
+ }
+
+ /* dissect the 802.11 header next */
+ next_tvb = tvb_new_subset(tvb, sizeof hdr, -1, -1);
+ call_dissector(ieee80211_handle, next_tvb, pinfo, tree);
+}
+
+#define IFHELP2(size, name, var, str) \
+ { &hf_prism_ ## name, { \
+ str, "prism." #var, size, BASE_HEX, NULL, 0x0, "" } },
+#define INTFIELD2(size, name, str) IFHELP2(size, name, name, str)
+#define VALFIELD2(name, str) \
+ IFHELP2(FT_UINT32, name ## _data, name ## .data, str ## " Field")
+
+void
+proto_register_prism(void)
+{
+ static hf_register_info hf[] = {
+ INTFIELD2(FT_UINT32, msgcode, "Message Code")
+ INTFIELD2(FT_UINT32, msglen, "Message Length")
+ VALFIELD2(hosttime, "Host Time")
+ VALFIELD2(mactime, "MAC Time")
+ VALFIELD2(channel, "Channel Time")
+ VALFIELD2(rssi, "RSSI")
+ VALFIELD2(sq, "SQ")
+ VALFIELD2(signal, "Signal")
+ VALFIELD2(noise, "Noise")
+ VALFIELD2(rate, "Rate")
+ VALFIELD2(istx, "IsTX")
+ VALFIELD2(frmlen, "Frame Length")
+
+ };
+ static gint *ett[] = {
+ &ett_prism
+ };
+
+ proto_prism = proto_register_protocol("Prism", "Prism", "prism");
+ proto_register_field_array(proto_prism, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+}
+
+void
+proto_reg_handoff_prism(void)
+{
+ /* handle for 802.11 dissector */
+ ieee80211_handle = find_dissector("wlan");
+
+ dissector_add("wtap_encap", WTAP_ENCAP_PRISM, dissect_prism, proto_prism);
+}