diff options
author | Anders Broman <anders.broman@ericsson.com> | 2011-10-12 05:08:51 +0000 |
---|---|---|
committer | Anders Broman <anders.broman@ericsson.com> | 2011-10-12 05:08:51 +0000 |
commit | 3e9d852a1b46a50a96c04fd25427c10e9b90a12c (patch) | |
tree | 8f8e3a1b084b14e02762b2b9d3ca6b781ef4d823 /epan/dissectors/packet-ieee80211-prism.c | |
parent | 9ef1758adffe973469308d1690280cc305ff3d50 (diff) |
From Jouni Malinen:
Move sniffer meta data parsing to separate files
packet-ieee80211.c includes dissectors for three different styles
of IEEE 802.11 sniffer meta data (like signal strength). Move these
to separate files in the same style as a fourth format (radiotap)
was already handled, so that packet-ieee80211.c focuses on the
actual IEEE 802.11 frame dissecting.
This reverts
http://anonsvn.wireshark.org/viewvc?revision=23911&view=revision
Objections?
https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=6443
svn path=/trunk/; revision=39379
Diffstat (limited to 'epan/dissectors/packet-ieee80211-prism.c')
-rw-r--r-- | epan/dissectors/packet-ieee80211-prism.c | 479 |
1 files changed, 479 insertions, 0 deletions
diff --git a/epan/dissectors/packet-ieee80211-prism.c b/epan/dissectors/packet-ieee80211-prism.c new file mode 100644 index 0000000000..2ef51788b2 --- /dev/null +++ b/epan/dissectors/packet-ieee80211-prism.c @@ -0,0 +1,479 @@ +/* packet-ieee80211-prism.c + * Routines for Prism monitoring mode header dissection + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * 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 + +#include <epan/packet.h> +#include "packet-ieee80211.h" + +#define SHORT_STR 256 + +static dissector_handle_t wlancap_handle; +static dissector_handle_t ieee80211_handle; + +static int proto_prism = -1; + +/* Prism radio header */ + +static int hf_ieee80211_prism_msgcode = -1; +static int hf_ieee80211_prism_msglen = -1; +static int hf_ieee80211_prism_devname = -1; +static int hf_ieee80211_prism_did = -1; +static int hf_ieee80211_prism_did_type = -1; +static int hf_ieee80211_prism_did_status = -1; +static int hf_ieee80211_prism_did_length = -1; +static int hf_ieee80211_prism_did_hosttime = -1; +static int hf_ieee80211_prism_did_mactime = -1; +static int hf_ieee80211_prism_did_channel = -1; +static int hf_ieee80211_prism_did_rssi = -1; +static int hf_ieee80211_prism_did_sq = -1; +static int hf_ieee80211_prism_did_signal = -1; +static int hf_ieee80211_prism_did_noise = -1; +static int hf_ieee80211_prism_did_rate = -1; +static int hf_ieee80211_prism_did_istx = -1; +static int hf_ieee80211_prism_did_frmlen = -1; +static int hf_ieee80211_prism_did_unknown = -1; + +static gint ett_prism = -1; +static gint ett_prism_did = -1; + +/* + * Prism II-based 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. + * + * Support by Tim Newsham + * + * A value from the header. + * + * It appears from looking at the linux-wlan-ng and Prism II HostAP + * drivers, and various patches to the orinoco_cs drivers to add + * Prism headers, that: + * + * the "did" identifies what the value is (i.e., what it's the value + * of); + * + * "status" is 0 if the value is present or 1 if it's absent; + * + * "len" is the length of the value (always 4, in that code); + * + * "data" is the value of the data (or 0 if not present). + * + * Note: all of those values are in the *host* byte order of the machine + * on which the capture was written. + */ + + +/* + * Header attached during Prism monitor mode. + * + * At least according to one paper I've seen, the Prism 2.5 chip set + * provides: + * + * RSSI (receive signal strength indication) is "the total power + * received by the radio hardware while receiving the frame, + * including signal, interfereence, and background noise"; + * + * "silence value" is "the total power observed just before the + * start of the frame". + * + * None of the drivers I looked at supply the "rssi" or "sq" value, + * but they do supply "signal" and "noise" values, along with a "rate" + * value that's 1/5 of the raw value from what is presumably a raw + * HFA384x frame descriptor, with the comment "set to 802.11 units", + * which presumably means the units are 500 Kb/s. + * + * I infer from the current NetBSD "wi" driver that "signal" and "noise" + * are adjusted dBm values, with the dBm value having 100 added to it + * for the Prism II cards (although the NetBSD code has an XXX comment + * for the #define for WI_PRISM_DBM_OFFSET) and 149 (with no XXX comment) + * for the Orinoco cards. + * + * XXX - what about other drivers that supply Prism headers, such as + * old versions of the MadWifi driver? + */ + +#define PRISM_HEADER_LENGTH 144 /* Default Prism Header Length */ +#define PRISM_DID_HOSTTIME 0x00010044 /* Host time element */ +#define PRISM_DID_MACTIME 0x00020044 /* Mac time element */ +#define PRISM_DID_CHANNEL 0x00030044 /* Channel element */ +#define PRISM_DID_RSSI 0x00040044 /* RSSI element */ +#define PRISM_DID_SQ 0x00050044 /* SQ element */ +#define PRISM_DID_SIGNAL 0x00060044 /* Signal element */ +#define PRISM_DID_NOISE 0x00070044 /* Noise element */ +#define PRISM_DID_RATE 0x00080044 /* Rate element */ +#define PRISM_DID_ISTX 0x00090044 /* Is Tx frame */ +#define PRISM_DID_FRMLEN 0x000A0044 /* Frame length */ + +static const value_string prism_did_vals[] = +{ + { PRISM_DID_HOSTTIME, "Host Time" }, + { PRISM_DID_MACTIME, "Mac Time" }, + { PRISM_DID_CHANNEL, "Channel" }, + { PRISM_DID_RSSI, "RSSI" }, + { PRISM_DID_SQ, "SQ" }, + { PRISM_DID_SIGNAL, "Signal" }, + { PRISM_DID_NOISE, "Noise" }, + { PRISM_DID_RATE, "Rate" }, + { PRISM_DID_ISTX, "Is Tx" }, + { PRISM_DID_FRMLEN, "Frame Length" }, + { 0, NULL} +}; + +static const value_string prism_status_vals[] = +{ + { 0, "Not Supplied" }, + { 1, "Supplied" }, + { 0, NULL} +}; + +static const value_string prism_istx_vals[] = +{ + { 0, "Rx Packet" }, + { 1, "Tx Packet" }, + { 0, NULL} +}; + +static void +prism_rate_base_custom(gchar *result, guint32 rate) +{ + g_snprintf(result, ITEM_LABEL_LENGTH, "%u.%u", rate /2, rate & 1 ? 5 : 0); +} + +static gchar * +prism_rate_return(guint32 rate) +{ + gchar *result=NULL; + result = ep_alloc(SHORT_STR); + result[0] = '\0'; + prism_rate_base_custom(result, rate); + + return result; +} + + +void +capture_prism(const guchar *pd, int offset, int len, packet_counts *ld) +{ + guint32 cookie; + + if (!BYTES_ARE_IN_FRAME(offset, len, 4)) { + ld->other++; + return; + } + + /* Some captures with DLT_PRISM have the AVS WLAN header */ + cookie = pntohl(pd); + if ((cookie == WLANCAP_MAGIC_COOKIE_V1) || + (cookie == WLANCAP_MAGIC_COOKIE_V2)) { + capture_wlancap(pd, offset, len, ld); + return; + } + + /* Prism header */ + if (!BYTES_ARE_IN_FRAME(offset, len, PRISM_HEADER_LENGTH)) { + ld->other++; + return; + } + offset += PRISM_HEADER_LENGTH; + + /* 802.11 header follows */ + capture_ieee80211(pd, offset, len, ld); +} + +static void +dissect_prism(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + proto_tree *prism_tree = NULL, *prism_did_tree = NULL; + proto_item *ti = NULL, *ti_did = NULL; + tvbuff_t *next_tvb; + int offset; + guint32 msgcode, msglen, did; + guint8 *devname; + + offset = 0; + did = 0; + + /* handle the new capture type. */ + msgcode = tvb_get_ntohl(tvb, offset); + if ((msgcode == WLANCAP_MAGIC_COOKIE_V1) || + (msgcode == WLANCAP_MAGIC_COOKIE_V2)) { + call_dissector(wlancap_handle, tvb, pinfo, tree); + return; + } + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "Prism"); + col_clear(pinfo->cinfo, COL_INFO); + + if(tree) { + ti = proto_tree_add_item(tree, proto_prism, tvb, 0, 144, ENC_BIG_ENDIAN); + prism_tree = proto_item_add_subtree(ti, ett_prism); + } + + /* Message Code */ + if(tree) { + proto_tree_add_item(prism_tree, hf_ieee80211_prism_msgcode, tvb, offset, 4, ENC_LITTLE_ENDIAN); + } + msgcode = tvb_get_letohl(tvb, offset); + offset += 4; + + /* Message Length */ + if(tree) { + proto_tree_add_item(prism_tree, hf_ieee80211_prism_msglen, tvb, offset, 4, ENC_LITTLE_ENDIAN); + } + msglen = tvb_get_letohl(tvb, offset); + offset += 4; + + /* Device Name */ + if(tree) { + proto_tree_add_item(prism_tree, hf_ieee80211_prism_devname, tvb, offset, 16, ENC_LITTLE_ENDIAN); + } + devname = tvb_get_ephemeral_string(tvb, offset, 16); + offset += 16; + + col_add_fstr(pinfo->cinfo, COL_INFO, "Device: %s, Message 0x%x, Length %d", devname, msgcode, msglen); + + + while(offset < PRISM_HEADER_LENGTH) + { + /* DID */ + if(tree) { + ti_did = proto_tree_add_item(prism_tree, hf_ieee80211_prism_did, tvb, offset, 12, ENC_NA); + prism_did_tree = proto_item_add_subtree(ti_did, ett_prism_did); + + proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_type, tvb, offset, 4, ENC_LITTLE_ENDIAN); + did = tvb_get_letohl(tvb, offset); + proto_item_append_text(ti_did, " %s", val_to_str(did, prism_did_vals, "Unknown %x") ); + } + offset += 4; + + + /* Status */ + if(tree) { + proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_status, tvb, offset, 2, ENC_LITTLE_ENDIAN); + } + offset += 2; + + /* Length */ + if(tree) { + proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); + } + offset += 2; + + /* Data... */ + switch(did){ + case PRISM_DID_HOSTTIME: + if(tree){ + proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_hosttime, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_item_append_text(ti_did, " %d", tvb_get_letohl(tvb, offset) ); + } + break; + case PRISM_DID_MACTIME: + if(tree){ + proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_mactime, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_item_append_text(ti_did, " %d", tvb_get_letohl(tvb, offset) ); + } + break; + case PRISM_DID_CHANNEL: + if(tree){ + proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_channel, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_item_append_text(ti_did, " %d", tvb_get_letohl(tvb, offset) ); + } + col_add_fstr(pinfo->cinfo, COL_FREQ_CHAN, "%u", tvb_get_letohl(tvb, offset)); + break; + case PRISM_DID_RSSI: + if(tree){ + proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_rssi, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_item_append_text(ti_did, " 0x%x", tvb_get_letohl(tvb, offset) ); + } + col_add_fstr(pinfo->cinfo, COL_RSSI, "%d", tvb_get_letohl(tvb, offset)); + break; + case PRISM_DID_SQ: + if(tree){ + proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_sq, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_item_append_text(ti_did, " 0x%x", tvb_get_letohl(tvb, offset) ); + } + break; + case PRISM_DID_SIGNAL: + if(tree){ + proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_signal, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_item_append_text(ti_did, " 0x%x", tvb_get_letohl(tvb, offset) ); + } + break; + case PRISM_DID_NOISE: + if(tree){ + proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_noise, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_item_append_text(ti_did, " 0x%x", tvb_get_letohl(tvb, offset) ); + } + break; + case PRISM_DID_RATE: + if(tree){ + proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_rate, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_item_append_text(ti_did, " %s Mb/s", prism_rate_return(tvb_get_letohl(tvb, offset)) ); + } + col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%s", prism_rate_return(tvb_get_letohl(tvb, offset)) ); + + break; + case PRISM_DID_ISTX: + if(tree){ + proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_istx, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_item_append_text(ti_did, " 0x%x", tvb_get_letohl(tvb, offset) ); + } + break; + case PRISM_DID_FRMLEN: + if(tree){ + proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_frmlen, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_item_append_text(ti_did, " %d", tvb_get_letohl(tvb, offset) ); + } + break; + default: + if(tree){ + proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_unknown, tvb, offset, 4, ENC_LITTLE_ENDIAN); + } + break; + } + offset += 4; + } + + /* dissect the 802.11 header next */ + next_tvb = tvb_new_subset_remaining(tvb, offset); + call_dissector(ieee80211_handle, next_tvb, pinfo, tree); +} + +static hf_register_info hf_prism[] = { + /* Prism-specific header fields + XXX - make as many of these generic as possible. */ + { &hf_ieee80211_prism_msgcode, + {"Message Code", "prism.msgcode", FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_ieee80211_prism_msglen, + {"Message Length", "prism.msglen", FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_ieee80211_prism_devname, + {"Device Name", "prism.devname", FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_ieee80211_prism_did, + {"DID", "prism.did.type", FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + + { &hf_ieee80211_prism_did_type, + {"DID", "prism.did.type", FT_UINT32, BASE_HEX, VALS(prism_did_vals), 0x0, + "Different ID for each parameter", HFILL }}, + + { &hf_ieee80211_prism_did_status, + {"Status", "prism.did.status", FT_UINT16, BASE_DEC, VALS(prism_status_vals), 0x0, + "Supplied by the driver or not", HFILL }}, + + { &hf_ieee80211_prism_did_length, + {"Length", "prism.did.length", FT_UINT16, BASE_DEC, NULL, 0x0, + "Length of data", HFILL }}, + + { &hf_ieee80211_prism_did_hosttime, + {"Host Time", "prism.did.hosttime", FT_UINT32, BASE_DEC, NULL, 0x0, + "In jiffies - for our system this is in 10ms units", HFILL }}, + + { &hf_ieee80211_prism_did_mactime, + {"Mac Time", "prism.did.hosttime", FT_UINT32, BASE_DEC, NULL, 0x0, + "In micro-seconds", HFILL }}, + + { &hf_ieee80211_prism_did_channel, + {"Channel", "prism.did.hosttime", FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL }}, + + { &hf_ieee80211_prism_did_rssi, + {"RSSI", "prism.did.rssi", FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_ieee80211_prism_did_sq, + {"SQ", "prism.did.sq", FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_ieee80211_prism_did_signal, + {"Signal", "prism.did.signal", FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_ieee80211_prism_did_noise, + {"Noise", "prism.did.noise", FT_UINT32, BASE_HEX, NULL, 0x0, + NULL, HFILL }}, + + { &hf_ieee80211_prism_did_rate, + {"Rate (In Mb/s)", "prism.did.rate", FT_UINT32, BASE_CUSTOM, prism_rate_base_custom, 0x0, + "In Mb/s", HFILL }}, + + { &hf_ieee80211_prism_did_istx, + {"IsTX", "prism.did.istx", FT_UINT32, BASE_HEX, VALS(prism_istx_vals), 0x0, + "Type of packet (RX or TX ?)", HFILL }}, + + { &hf_ieee80211_prism_did_frmlen, + {"Frame Length", "prism.did.frmlen", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, + "Length of the following frame in bytes", HFILL }}, + + { &hf_ieee80211_prism_did_unknown, + {"Unknown DID Field", "prism.did.unknown", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, + NULL, HFILL }} +}; + +static gint *tree_array[] = { + &ett_prism, + &ett_prism_did +}; + +void proto_register_ieee80211_prism(void) +{ + proto_prism = proto_register_protocol("Prism capture header", "Prism", + "prism"); + proto_register_field_array(proto_prism, hf_prism, array_length(hf_prism)); + proto_register_subtree_array(tree_array, array_length(tree_array)); +} + +void proto_reg_handoff_ieee80211_prism(void) +{ + dissector_handle_t prism_handle; + + prism_handle = create_dissector_handle(dissect_prism, proto_prism); + dissector_add_uint("wtap_encap", WTAP_ENCAP_PRISM_HEADER, prism_handle); + ieee80211_handle = find_dissector("wlan"); + wlancap_handle = find_dissector("wlancap"); +} + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 2 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=2 tabstop=8 expandtab: + * :indentSize=2:tabSize=8:noTabs=true: + */ |