From b373ded136367f49569569272830e32e0bdd49da Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Mon, 5 Jul 2004 09:29:06 +0000 Subject: [PATCH] From Jouni Malinen: add columns for the 802.11 data rate and signal strength for AVS headers. Also add them for the Prism and Radiotap headers, and for the pseudo-header from non-native captures. svn path=/trunk/; revision=11316 --- column.c | 24 ++++++++- epan/column_info.h | 4 +- packet-ieee80211.c | 15 +++++- packet-prism.c | 61 +++++++++++++-------- packet-radiotap.c | 128 +++++++++++++++++++++++++++------------------ packet-wlancap.c | 17 +++++- 6 files changed, 169 insertions(+), 80 deletions(-) diff --git a/column.c b/column.c index 125ba546bf..e0674a292f 100644 --- a/column.c +++ b/column.c @@ -1,7 +1,7 @@ /* column.c * Routines for handling column preferences * - * $Id: column.c,v 1.47 2004/03/18 19:04:30 obiot Exp $ + * $Id: column.c,v 1.48 2004/07/05 09:29:04 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -53,7 +53,7 @@ col_format_to_string(gint fmt) { "%rd", "%ud", "%hd", "%rhd", "%uhd", "%nd", "%rnd", "%und", "%S", "%rS", "%uS", "%D", "%rD", "%uD", "%p", "%i", "%L", "%B", "%XO", "%XR", "%I", "%c", "%Xs", - "%Xd", "%V" }; + "%Xd", "%V", "%x", "%e" }; if (fmt < 0 || fmt > NUM_COL_FMTS) return NULL; @@ -105,6 +105,8 @@ static gchar *dlist[NUM_COL_FMTS] = { "Src PortIdx", "Dst PortIdx", "VSAN", + "IEEE 802.11 TX rate", + "IEEE 802.11 RSSI", }; gchar * @@ -187,6 +189,12 @@ get_column_format_matches(gboolean *fmt_list, gint format) { case COL_VSAN: fmt_list[COL_VSAN] = TRUE; break; + case COL_TX_RATE: + fmt_list[COL_TX_RATE] = TRUE; + break; + case COL_RSSI: + fmt_list[COL_RSSI] = TRUE; + break; default: break; } @@ -283,6 +291,12 @@ get_column_longest_string(gint format) case COL_VSAN: return "000000"; break; + case COL_TX_RATE: + return "108.0"; + break; + case COL_RSSI: + return "100"; + break; default: /* COL_INFO */ return "Source port: kerberos-master Destination port: kerberos-master"; break; @@ -414,6 +428,12 @@ get_column_format_from_str(gchar *str) { case 'V': return COL_VSAN; break; + case 'x': + return COL_TX_RATE; + break; + case 'e': + return COL_RSSI; + break; } cptr++; } diff --git a/epan/column_info.h b/epan/column_info.h index 51b6661b6a..6556ad3d7b 100644 --- a/epan/column_info.h +++ b/epan/column_info.h @@ -1,7 +1,7 @@ /* column.h * Definitions for column structures and routines * - * $Id: column_info.h,v 1.12 2004/01/31 04:10:04 guy Exp $ + * $Id: column_info.h,v 1.13 2004/07/05 09:29:06 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -93,6 +93,8 @@ enum { COL_SRCIDX, /* Src port idx - Cisco MDS-specific */ COL_DSTIDX, /* Dst port idx - Cisco MDS-specific */ COL_VSAN, /* VSAN - Cisco MDS-specific */ + COL_TX_RATE, /* IEEE 802.11 - TX rate in Mbps */ + COL_RSSI, /* IEEE 802.11 - received signal strength */ NUM_COL_FMTS /* Should always be last */ }; diff --git a/packet-ieee80211.c b/packet-ieee80211.c index 6a2ae9a1ed..a5f159cd86 100644 --- a/packet-ieee80211.c +++ b/packet-ieee80211.c @@ -3,7 +3,7 @@ * Copyright 2000, Axis Communications AB * Inquiries/bugreports should be sent to Johan.Jorgensen@axis.com * - * $Id: packet-ieee80211.c,v 1.112 2004/07/04 03:46:01 guy Exp $ + * $Id: packet-ieee80211.c,v 1.113 2004/07/05 09:29:04 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -1450,6 +1450,19 @@ dissect_ieee80211_common (tvbuff_t * tvb, packet_info * pinfo, if (check_col (pinfo->cinfo, COL_INFO)) col_clear (pinfo->cinfo, COL_INFO); + /* Add the radio information, if present, to the column information */ + if (has_radio_information) { + if (check_col(pinfo->cinfo, COL_TX_RATE)) { + col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%g", + .5*pinfo->pseudo_header->ieee_802_11.data_rate); + } + if (check_col(pinfo->cinfo, COL_RSSI)) { + /* XX - this is a percentage, not a dBm or normalized or raw RSSI */ + col_add_fstr(pinfo->cinfo, COL_RSSI, "%u", + pinfo->pseudo_header->ieee_802_11.signal_level); + } + } + fcf = tvb_get_letohs (tvb, 0); if (wlan_broken_fc) { /* Swap bytes */ diff --git a/packet-prism.c b/packet-prism.c index 5da3fb5929..0aedf6662b 100644 --- a/packet-prism.c +++ b/packet-prism.c @@ -9,7 +9,7 @@ * * By Tim Newsham * - * $Id: packet-prism.c,v 1.11 2004/02/14 20:55:23 guy Exp $ + * $Id: packet-prism.c,v 1.12 2004/07/05 09:29:04 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -122,23 +122,27 @@ capture_prism(const guchar *pd, int offset, int len, packet_counts *ld) * 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); \ + if(tree) { \ + 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); \ + if(tree) { \ + 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_tree *prism_tree = NULL; proto_item *ti; tvbuff_t *next_tvb; int offset; @@ -169,24 +173,35 @@ dissect_prism(tvbuff_t *tvb, packet_info *pinfo, proto_tree *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"); + INTFIELD(4, msgcode, "Message Code: %d"); + INTFIELD(4, msglen, "Message Length: %d"); + if(tree) { 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"); - VALFIELD(rssi, "RSSI"); - VALFIELD(sq, "SQ"); - VALFIELD(signal, "Signal"); - VALFIELD(noise, "Noise"); - VALFIELD(rate, "Rate"); - VALFIELD(istx, "IsTX"); - VALFIELD(frmlen, "Frame Length"); } + offset += sizeof hdr.devname; + + VALFIELD(hosttime, "Host Time"); + VALFIELD(mactime, "MAC Time"); + VALFIELD(channel, "Channel"); + VALFIELD(rssi, "RSSI"); + if (check_col(pinfo->cinfo, COL_RSSI)) { + col_add_fstr(pinfo->cinfo, COL_RSSI, "%d", + hdr.rssi.data); + } + + VALFIELD(sq, "SQ"); + VALFIELD(signal, "Signal"); + VALFIELD(noise, "Noise"); + if (check_col(pinfo->cinfo, COL_TX_RATE)) { + col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%d.%d", + hdr.rate.data / 10, hdr.rate.data % 10); + } + 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); diff --git a/packet-radiotap.c b/packet-radiotap.c index aaa252090f..590f77720d 100644 --- a/packet-radiotap.c +++ b/packet-radiotap.c @@ -2,7 +2,7 @@ * packet-radiotap.c * Decode packets with a Radiotap header * - * $Id: packet-radiotap.c,v 1.3 2004/02/01 04:29:07 jmayer Exp $ + * $Id: packet-radiotap.c,v 1.4 2004/07/05 09:29:04 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -266,7 +266,7 @@ dissect_radiotap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x))) #define BITNO_2(x) (((x) & 2) ? 1 : 0) #define BIT(n) (1 << n) - proto_tree *radiotap_tree; + proto_tree *radiotap_tree = NULL; proto_item *ti; int offset; guint32 version; @@ -295,21 +295,24 @@ dissect_radiotap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) ti = proto_tree_add_protocol_format(tree, proto_radiotap, tvb, 0, length, "Radiotap Header"); radiotap_tree = proto_item_add_subtree(ti, ett_radiotap); + } - for (; present; present = next_present) { - /* clear the least significant bit that is set */ - next_present = present & (present - 1); + for (; present; present = next_present) { + /* clear the least significant bit that is set */ + next_present = present & (present - 1); - /* extract the least significant bit that is set */ - bit = BITNO_32(present ^ next_present); + /* extract the least significant bit that is set */ + bit = BITNO_32(present ^ next_present); - switch (bit) { - case IEEE80211_RADIOTAP_FLAGS: + switch (bit) { + case IEEE80211_RADIOTAP_FLAGS: + if (tree) { proto_tree_add_uint(radiotap_tree, hf_radiotap_preamble, tvb, 0, 0, (tvb_get_guint8(tvb, offset) & IEEE80211_RADIOTAP_F_SHORTPRE) != 0); - offset++; - /* XXX CFP, WEP, FRAG */ + } + offset++; + /* XXX CFP, WEP, FRAG */ #if 0 capability = tvb_get_letohs (tvb, offset); @@ -343,39 +346,58 @@ dissect_radiotap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) proto_tree_add_boolean (cap_tree, ff_dsss_ofdm, tvb, offset, 2, capability); #endif - break; - case IEEE80211_RADIOTAP_RATE: - rate = tvb_get_guint8(tvb, offset) & 0x7f; + break; + case IEEE80211_RADIOTAP_RATE: + rate = tvb_get_guint8(tvb, offset) & 0x7f; + if (check_col(pinfo->cinfo, COL_TX_RATE)) { + col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%d.%d", + rate / 2, rate & 1 ? 5 : 0); + } + if (tree) { proto_tree_add_uint_format(radiotap_tree, hf_radiotap_datarate, tvb, offset, 1, tvb_get_guint8(tvb, offset), "Datarate: %d.%d Mbps", rate / 2, rate & 1 ? 5 : 0); - offset++; - break; - case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: - case IEEE80211_RADIOTAP_DB_ANTSIGNAL: - /* XXX distinguish units */ + } + offset++; + break; + case IEEE80211_RADIOTAP_DBM_ANTSIGNAL: + case IEEE80211_RADIOTAP_DB_ANTSIGNAL: + /* XXX distinguish units */ + if (check_col(pinfo->cinfo, COL_RSSI)) { + col_add_fstr(pinfo->cinfo, COL_RSSI, "%d", + tvb_get_guint8(tvb, offset)); + } + if (tree) { proto_tree_add_int(radiotap_tree, hf_radiotap_antsignal, tvb, offset, 1, tvb_get_guint8(tvb, offset)); - offset++; - break; - case IEEE80211_RADIOTAP_DBM_ANTNOISE: - case IEEE80211_RADIOTAP_DB_ANTNOISE: - /* XXX distinguish units */ + } + offset++; + break; + case IEEE80211_RADIOTAP_DBM_ANTNOISE: + case IEEE80211_RADIOTAP_DB_ANTNOISE: + /* XXX distinguish units */ + if (tree) { proto_tree_add_int(radiotap_tree, hf_radiotap_antnoise, tvb, offset, 1, tvb_get_guint8(tvb, offset)); - offset++; - break; - case IEEE80211_RADIOTAP_ANTENNA: + } + offset++; + break; + case IEEE80211_RADIOTAP_ANTENNA: + if (tree) { proto_tree_add_uint(radiotap_tree, hf_radiotap_antenna, tvb, offset, 1, tvb_get_guint8(tvb, offset)); - offset++; - break; - case IEEE80211_RADIOTAP_DBM_TX_POWER: + } + offset++; + break; + case IEEE80211_RADIOTAP_DBM_TX_POWER: + if (tree) { proto_tree_add_int(radiotap_tree, hf_radiotap_txpower, tvb, offset, 1, tvb_get_guint8(tvb, offset)); - offset++; - break; - case IEEE80211_RADIOTAP_CHANNEL: + } + offset++; + break; + case IEEE80211_RADIOTAP_CHANNEL: + if (tree) { freq = tvb_get_letohs(tvb, offset); flags = tvb_get_letohs(tvb, offset+2); proto_tree_add_uint_format(radiotap_tree, hf_radiotap_channel_frequency, @@ -383,30 +405,32 @@ dissect_radiotap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) "Channel: %u (chan %u)", freq, ieee80211_mhz2ieee(freq, flags)); proto_tree_add_uint(radiotap_tree, hf_radiotap_channel_flags, tvb, offset+2, 2, flags); - offset+=4; - break; - case IEEE80211_RADIOTAP_FHSS: - case IEEE80211_RADIOTAP_LOCK_QUALITY: - case IEEE80211_RADIOTAP_TX_ATTENUATION: - case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: + } + offset+=4; + break; + case IEEE80211_RADIOTAP_FHSS: + case IEEE80211_RADIOTAP_LOCK_QUALITY: + case IEEE80211_RADIOTAP_TX_ATTENUATION: + case IEEE80211_RADIOTAP_DB_TX_ATTENUATION: #if 0 - tvb_get_letohs(tvb, offset); + tvb_get_letohs(tvb, offset); #endif - offset+=2; - break; - case IEEE80211_RADIOTAP_TSFT: + offset+=2; + break; + case IEEE80211_RADIOTAP_TSFT: + if (tree) { proto_tree_add_item(radiotap_tree, hf_radiotap_mactime, tvb, offset, 8, FALSE); - offset+=8; - break; - default: - /* - * This indicates a field whose size we do not - * know, so we cannot proceed. - */ - next_present = 0; - continue; } + offset+=8; + break; + default: + /* + * This indicates a field whose size we do not + * know, so we cannot proceed. + */ + next_present = 0; + continue; } } diff --git a/packet-wlancap.c b/packet-wlancap.c index 508c0de623..24e0a00404 100644 --- a/packet-wlancap.c +++ b/packet-wlancap.c @@ -7,10 +7,14 @@ * additional fields, is designed to be non-hardware-specific, and more * importantly, version and length fields so it can be extended later * without breaking anything. + * + * See + * + * http://www.shaftnet.org/~pizza/software/capturefrm.txt * * By Solomon Peachy * - * $Id: packet-wlancap.c,v 1.4 2004/01/29 10:58:28 guy Exp $ + * $Id: packet-wlancap.c,v 1.5 2004/07/05 09:29:05 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -206,6 +210,17 @@ dissect_wlancap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) if(check_col(pinfo->cinfo, COL_INFO)) col_add_fstr(pinfo->cinfo, COL_INFO, "AVS WLAN Capture v%x, Length %d",version, length); + if (check_col(pinfo->cinfo, COL_TX_RATE)) { + guint32 txrate = tvb_get_ntohl(tvb, offset + 32); + col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%d.%d", + txrate / 10, txrate % 10); + } + if (check_col(pinfo->cinfo, COL_RSSI)) { + /* XXX cook ssi_signal (Based on type; ie format) */ + col_add_fstr(pinfo->cinfo, COL_RSSI, "%d", + tvb_get_ntohl(tvb, offset + 48)); + } + /* Dissect the packet */ if (tree) { ti = proto_tree_add_protocol_format(tree, proto_wlancap,