aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2015-06-20 15:57:57 -0700
committerGuy Harris <guy@alum.mit.edu>2015-06-20 23:02:21 +0000
commit2895d58dc38321a72c82e1bf77d165ef4acbc73a (patch)
tree1091e87a52bf3c266edeb282f7baa7deea13fbd6 /epan
parent77ed0387c6e03d9667a56ab5effca755bac78df2 (diff)
Call the "802.11 radio information" dissector for radio headers.
Have dissectors of various forms of radio information headers in the packets fill in a struct ieee_802_11_phdr with radio information as appropriate, and call the "802.11 radio information" dissector rather than the raw 802.11 dissector. This means that the radio information can be found in a protocol-independent and encapsulation-independent form when you're looking at the packet; that information can be presented in a form somewhat easier to read than the raw metadata header format. It also enables having a single "radio information" tap that allows statistics to handle all different sorts of radio information encapsulation. In addition, it lets us clean up some of the arguments passed to the common 802.11 dissector routine, by having it pull that information from the struct ieee_802_11_phdr. Ensure that the right structure gets passed to that routine, and that all the appropriate parts of that structure are filled in. Rename the 802.11 radio protocol to "wlan_radio", rather than just "radio", as it's 802.11-specific. Give all its fields "wlan_radio." names rather than "wlan." names. Change-Id: I78d79afece0ce0cf5fc17293c1e29596413b31c8 Reviewed-on: https://code.wireshark.org/review/8992 Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-aruba-erm.c75
-rw-r--r--epan/dissectors/packet-cisco-wids.c15
-rw-r--r--epan/dissectors/packet-ieee80211-airopeek.c19
-rw-r--r--epan/dissectors/packet-ieee80211-netmon.c142
-rw-r--r--epan/dissectors/packet-ieee80211-radio.c183
-rw-r--r--epan/dissectors/packet-ieee80211-radiotap.c97
-rw-r--r--epan/dissectors/packet-ieee80211.c126
-rw-r--r--epan/dissectors/packet-ixveriwave.c29
-rw-r--r--epan/dissectors/packet-peekremote.c63
-rw-r--r--epan/dissectors/packet-ppi.c122
10 files changed, 560 insertions, 311 deletions
diff --git a/epan/dissectors/packet-aruba-erm.c b/epan/dissectors/packet-aruba-erm.c
index 931c031d69..fffb839b16 100644
--- a/epan/dissectors/packet-aruba-erm.c
+++ b/epan/dissectors/packet-aruba-erm.c
@@ -89,6 +89,8 @@
#include "config.h"
+#include <wiretap/wtap.h>
+
#include <epan/packet.h>
#include <epan/expert.h>
#include <epan/prefs.h>
@@ -151,8 +153,8 @@ static dissector_handle_t aruba_erm_handle_type1;
static dissector_handle_t aruba_erm_handle_type2;
static dissector_handle_t aruba_erm_handle_type3;
static dissector_handle_t aruba_erm_handle_type4;
-static dissector_handle_t wlan_withoutfcs;
-static dissector_handle_t wlan_withfcs;
+static dissector_handle_t wlan_radio_handle;
+static dissector_handle_t wlan_withfcs_handle;
static dissector_handle_t peek_handle;
static dissector_handle_t ppi_handle;
static dissector_handle_t data_handle;
@@ -177,30 +179,6 @@ dissect_aruba_erm_pcap(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *aruba_
return offset;
}
-static int
-dissect_aruba_erm_pcap_radio(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *aruba_erm_tree, gint offset, guint32 *signal_strength)
-{
- proto_item *ti_data_rate;
- guint16 data_rate;
-
- data_rate = tvb_get_ntohs(tvb, offset);
- proto_tree_add_item(aruba_erm_tree, hf_aruba_erm_data_rate, tvb, offset, 2, ENC_BIG_ENDIAN);
- ti_data_rate = proto_tree_add_float_format(aruba_erm_tree, hf_aruba_erm_data_rate_gen,
- tvb, 16, 2,
- (float)data_rate / 2,
- "Data Rate: %.1f Mb/s",
- (float)data_rate / 2);
- PROTO_ITEM_SET_GENERATED(ti_data_rate);
- offset += 2;
-
- proto_tree_add_item(aruba_erm_tree, hf_aruba_erm_channel, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
-
- proto_tree_add_item_ret_uint(aruba_erm_tree, hf_aruba_erm_signal_strength, tvb, offset, 1, ENC_BIG_ENDIAN, signal_strength);
- offset += 1;
-
- return offset;
-}
static proto_tree *
dissect_aruba_erm_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset _U_)
@@ -257,7 +235,7 @@ dissect_aruba_erm_type0(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
next_tvb = tvb_new_subset_remaining(tvb, offset);
/* No way to determine if TX or RX packet... (TX = no FCS, RX = FCS...)*/
- call_dissector(wlan_withfcs, next_tvb, pinfo, tree);
+ call_dissector(wlan_withfcs_handle, next_tvb, pinfo, tree);
}
@@ -292,22 +270,51 @@ dissect_aruba_erm_type3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
tvbuff_t * next_tvb;
int offset = 0;
proto_tree *aruba_erm_tree;
+ struct ieee_802_11_phdr phdr;
guint32 signal_strength;
+ proto_item *ti_data_rate;
+ guint16 data_rate;
+ guint channel;
aruba_erm_tree = dissect_aruba_erm_common(tvb, pinfo, tree, &offset);
-
offset = dissect_aruba_erm_pcap(tvb, pinfo, aruba_erm_tree, offset);
- offset = dissect_aruba_erm_pcap_radio(tvb, pinfo, aruba_erm_tree, offset, &signal_strength);
+
+ phdr.decrypted = FALSE;
+ phdr.presence_flags |=
+ PHDR_802_11_HAS_DATA_RATE|
+ PHDR_802_11_HAS_CHANNEL|
+ PHDR_802_11_HAS_SIGNAL_PERCENT;
+ data_rate = tvb_get_ntohs(tvb, offset);
+ phdr.data_rate = data_rate;
+ proto_tree_add_item(aruba_erm_tree, hf_aruba_erm_data_rate, tvb, offset, 2, ENC_BIG_ENDIAN);
+ ti_data_rate = proto_tree_add_float_format(aruba_erm_tree, hf_aruba_erm_data_rate_gen,
+ tvb, 16, 2,
+ (float)data_rate / 2,
+ "Data Rate: %.1f Mb/s",
+ (float)data_rate / 2);
+ PROTO_ITEM_SET_GENERATED(ti_data_rate);
+ offset += 2;
+
+ proto_tree_add_item_ret_uint(aruba_erm_tree, hf_aruba_erm_channel, tvb, offset, 1, ENC_BIG_ENDIAN, &channel);
+ phdr.channel = channel;
+ offset += 1;
+
+ proto_tree_add_item_ret_uint(aruba_erm_tree, hf_aruba_erm_signal_strength, tvb, offset, 1, ENC_BIG_ENDIAN, &signal_strength);
+ phdr.signal_percent = signal_strength;
+ offset += 1;
+
proto_item_set_len(aruba_erm_tree, offset);
next_tvb = tvb_new_subset_remaining(tvb, offset);
if(signal_strength == 100){ /* When signal = 100 %, it is TX packet and there is no FCS */
- call_dissector(wlan_withoutfcs, next_tvb, pinfo, tree);
+ phdr.fcs_len = 0; /* TX packet, no FCS */
} else {
- call_dissector(wlan_withfcs, next_tvb, pinfo, tree);
+ phdr.fcs_len = 4; /* We have an FCS */
}
-
+ phdr.decrypted = FALSE;
+ phdr.datapad = FALSE;
+ call_dissector_with_data(wlan_radio_handle, next_tvb, pinfo, tree, &phdr);
}
static void
@@ -446,8 +453,8 @@ proto_reg_handoff_aruba_erm(void)
static gboolean initialized = FALSE;
if (!initialized) {
- wlan_withoutfcs = find_dissector("wlan_withoutfcs");
- wlan_withfcs = find_dissector("wlan_withfcs");
+ wlan_radio_handle = find_dissector("wlan_radio");
+ wlan_withfcs_handle = find_dissector("wlan_withfcs");
ppi_handle = find_dissector("ppi");
peek_handle = find_dissector("peekremote");
data_handle = find_dissector("data");
diff --git a/epan/dissectors/packet-cisco-wids.c b/epan/dissectors/packet-cisco-wids.c
index bd0b3b7f4a..d194fdb735 100644
--- a/epan/dissectors/packet-cisco-wids.c
+++ b/epan/dissectors/packet-cisco-wids.c
@@ -45,6 +45,8 @@
#include "config.h"
+#include <wiretap/wtap.h>
+
#include <epan/packet.h>
#include <epan/exceptions.h>
#include <epan/expert.h>
@@ -66,7 +68,7 @@ static gint ett_cwids = -1;
static expert_field ie_ieee80211_subpacket = EI_INIT;
-static dissector_handle_t ieee80211_handle;
+static dissector_handle_t ieee80211_radio_handle;
static void
dissect_cwids(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
@@ -83,13 +85,20 @@ dissect_cwids(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
cwids_tree = NULL;
while(tvb_reported_length_remaining(tvb, offset) > 0) {
+ struct ieee_802_11_phdr phdr;
+
ti = proto_tree_add_item(tree, proto_cwids, tvb, offset, 28, ENC_NA);
cwids_tree = proto_item_add_subtree(ti, ett_cwids);
+ phdr.fcs_len = 0; /* no FCS */
+ phdr.decrypted = FALSE;
+ phdr.datapad = FALSE;
+ phdr.presence_flags = PHDR_802_11_HAS_CHANNEL;
proto_tree_add_item(cwids_tree, hf_cwids_version, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
proto_tree_add_item(cwids_tree, hf_cwids_unknown1, tvb, offset, 7, ENC_NA);
offset += 7;
+ phdr.channel = tvb_get_guint8(tvb, offset);
proto_tree_add_item(cwids_tree, hf_cwids_channel, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
proto_tree_add_item(cwids_tree, hf_cwids_unknown2, tvb, offset, 6, ENC_NA);
@@ -105,7 +114,7 @@ dissect_cwids(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
wlan_tvb = tvb_new_subset_length(tvb, offset, capturelen);
/* Continue after ieee80211 dissection errors */
TRY {
- call_dissector(ieee80211_handle, wlan_tvb, pinfo, tree);
+ call_dissector_with_data(ieee80211_radio_handle, wlan_tvb, pinfo, tree, &phdr);
} CATCH_BOUNDS_ERRORS {
show_exception(wlan_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
@@ -187,7 +196,7 @@ proto_reg_handoff_cwids(void)
if (!initialized) {
cwids_handle = create_dissector_handle(dissect_cwids, proto_cwids);
dissector_add_for_decode_as("udp.port", cwids_handle);
- ieee80211_handle = find_dissector("wlan_withoutfcs");
+ ieee80211_radio_handle = find_dissector("wlan_radio");
initialized = TRUE;
} else {
if (saved_udp_port != 0) {
diff --git a/epan/dissectors/packet-ieee80211-airopeek.c b/epan/dissectors/packet-ieee80211-airopeek.c
index 6a321b6776..ff82d9892e 100644
--- a/epan/dissectors/packet-ieee80211-airopeek.c
+++ b/epan/dissectors/packet-ieee80211-airopeek.c
@@ -29,7 +29,7 @@
void proto_register_ieee80211_airopeek(void);
void proto_reg_handoff_ieee80211_airopeek(void);
-static dissector_handle_t ieee80211_handle;
+static dissector_handle_t ieee80211_radio_handle;
static int proto_airopeek = -1;
@@ -47,6 +47,7 @@ dissect_airopeek(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
guint8 data_rate;
guint8 signal_level;
tvbuff_t *next_tvb;
+ struct ieee_802_11_phdr phdr;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "AiroPeek");
col_clear(pinfo->cinfo, COL_INFO);
@@ -57,7 +58,17 @@ dissect_airopeek(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
airopeek_tree = proto_item_add_subtree(ti, ett_airopeek);
}
+ /* We don't have any 802.11 metadata yet. */
+ phdr.fcs_len = 0;
+ phdr.decrypted = FALSE;
+ phdr.datapad = FALSE;
+ phdr.presence_flags =
+ PHDR_802_11_HAS_CHANNEL|
+ PHDR_802_11_HAS_DATA_RATE|
+ PHDR_802_11_HAS_SIGNAL_PERCENT;
+
data_rate = tvb_get_guint8(tvb, 0);
+ phdr.data_rate = data_rate;
/* Add the radio information to the column information */
col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%u.%u",
data_rate / 2,
@@ -70,6 +81,7 @@ dissect_airopeek(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
data_rate & 1 ? 5 : 0);
}
+ phdr.channel = tvb_get_guint8(tvb, 1);
if (tree)
proto_tree_add_item(airopeek_tree, hf_channel, tvb, 1, 1, ENC_BIG_ENDIAN);
@@ -84,6 +96,7 @@ dissect_airopeek(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
* an adapter-dependent process, so, as we don't know what type of
* adapter was used to do the capture, we can't do the conversion.
*/
+ phdr.signal_percent = signal_level;
col_add_fstr(pinfo->cinfo, COL_RSSI, "%u%%", signal_level);
proto_tree_add_uint_format_value(airopeek_tree, hf_signal_strength, tvb, 2, 1,
@@ -94,7 +107,7 @@ dissect_airopeek(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* dissect the 802.11 header next */
pinfo->current_proto = "IEEE 802.11";
next_tvb = tvb_new_subset_remaining(tvb, 4);
- call_dissector(ieee80211_handle, next_tvb, pinfo, tree);
+ call_dissector_with_data(ieee80211_radio_handle, next_tvb, pinfo, tree, &phdr);
}
void proto_register_ieee80211_airopeek(void)
@@ -132,7 +145,7 @@ void proto_reg_handoff_ieee80211_airopeek(void)
airopeek_handle = create_dissector_handle(dissect_airopeek, proto_airopeek);
dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE_802_11_AIROPEEK,
airopeek_handle);
- ieee80211_handle = find_dissector("wlan");
+ ieee80211_radio_handle = find_dissector("wlan_radio");
}
/*
diff --git a/epan/dissectors/packet-ieee80211-netmon.c b/epan/dissectors/packet-ieee80211-netmon.c
index 27a188ff08..bfc650e9f6 100644
--- a/epan/dissectors/packet-ieee80211-netmon.c
+++ b/epan/dissectors/packet-ieee80211-netmon.c
@@ -64,12 +64,13 @@ static int hf_netmon_802_11_timestamp = -1;
static gint ett_netmon_802_11 = -1;
static gint ett_netmon_802_11_op_mode = -1;
-static dissector_handle_t ieee80211_handle;
+static dissector_handle_t ieee80211_radio_handle;
static int
-dissect_netmon_802_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
+dissect_netmon_802_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
- proto_tree *wlan_tree, *opmode_tree;
+ struct ieee_802_11_phdr *phdr = (struct ieee_802_11_phdr *)data;
+ proto_tree *wlan_tree = NULL, *opmode_tree;
proto_item *ti;
tvbuff_t *next_tvb;
int offset;
@@ -98,76 +99,93 @@ dissect_netmon_802_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
}
/* Dissect the packet */
- if (tree) {
- ti = proto_tree_add_item(tree, proto_netmon_802_11, tvb, 0, length,
- ENC_NA);
- wlan_tree = proto_item_add_subtree(ti, ett_netmon_802_11);
- proto_tree_add_item(wlan_tree, hf_netmon_802_11_version, tvb, offset, 1,
+ ti = proto_tree_add_item(tree, proto_netmon_802_11, tvb, 0, length,
+ ENC_NA);
+ wlan_tree = proto_item_add_subtree(ti, ett_netmon_802_11);
+ proto_tree_add_item(wlan_tree, hf_netmon_802_11_version, tvb, offset, 1,
+ ENC_LITTLE_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(wlan_tree, hf_netmon_802_11_length, tvb, offset, 2,
+ ENC_LITTLE_ENDIAN);
+ offset += 2;
+ ti = proto_tree_add_item(wlan_tree, hf_netmon_802_11_op_mode, tvb, offset,
+ 4, ENC_LITTLE_ENDIAN);
+ opmode_tree = proto_item_add_subtree(ti, ett_netmon_802_11_op_mode);
+ proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_sta, tvb, offset,
+ 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_ap, tvb, offset,
+ 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_sta_ext, tvb,
+ offset, 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_mon, tvb, offset,
+ 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ flags = tvb_get_letohl(tvb, offset);
+ offset += 4;
+ if (flags != 0xffffffff) {
+ proto_tree_add_item(wlan_tree, hf_netmon_802_11_phy_type, tvb, offset, 4,
ENC_LITTLE_ENDIAN);
- offset += 1;
- proto_tree_add_item(wlan_tree, hf_netmon_802_11_length, tvb, offset, 2,
- ENC_LITTLE_ENDIAN);
- offset += 2;
- ti = proto_tree_add_item(wlan_tree, hf_netmon_802_11_op_mode, tvb, offset,
- 4, ENC_LITTLE_ENDIAN);
- opmode_tree = proto_item_add_subtree(ti, ett_netmon_802_11_op_mode);
- proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_sta, tvb, offset,
- 4, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_ap, tvb, offset,
- 4, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_sta_ext, tvb,
- offset, 4, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_mon, tvb, offset,
- 4, ENC_LITTLE_ENDIAN);
- offset += 4;
- flags = tvb_get_letohl(tvb, offset);
offset += 4;
- if (flags != 0xffffffff) {
- proto_tree_add_item(wlan_tree, hf_netmon_802_11_phy_type, tvb, offset, 4,
- ENC_LITTLE_ENDIAN);
- offset += 4;
- channel = tvb_get_letohl(tvb, offset);
- if (channel < 1000) {
+ channel = tvb_get_letohl(tvb, offset);
+ if (channel < 1000) {
+ if (channel == 0) {
+ proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_channel,
+ tvb, offset, 4, channel,
+ "Unknown");
+ } else {
+ phdr->presence_flags |= PHDR_802_11_HAS_CHANNEL;
+ phdr->channel = channel;
proto_tree_add_uint(wlan_tree, hf_netmon_802_11_channel,
tvb, offset, 4, channel);
- } else {
- proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_frequency,
- tvb, offset, 4, channel,
- "%u Mhz", channel);
}
- offset += 4;
- rssi = tvb_get_letohl(tvb, offset);
+ } else {
+ phdr->presence_flags |= PHDR_802_11_HAS_FREQUENCY;
+ phdr->frequency = channel;
+ proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_frequency,
+ tvb, offset, 4, channel,
+ "%u Mhz", channel);
+ }
+ offset += 4;
+ rssi = tvb_get_letohl(tvb, offset);
+ if (rssi == 0) {
+ proto_tree_add_int_format_value(wlan_tree, hf_netmon_802_11_rssi,
+ tvb, offset, 4, rssi,
+ "Unknown");
+ } else {
+ phdr->presence_flags |= PHDR_802_11_HAS_SIGNAL_DBM;
+ phdr->signal_dbm = rssi;
proto_tree_add_int_format_value(wlan_tree, hf_netmon_802_11_rssi,
tvb, offset, 4, rssi,
"%d dBm", rssi);
- offset += 4;
- rate = tvb_get_guint8(tvb, offset);
- if (rate == 0) {
- proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_datarate,
- tvb, offset, 1, rate,
- "Unknown");
- } else {
- proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_datarate,
- tvb, offset, 1, rate,
- "%f Mb/s", rate*.5);
- }
- offset += 1;
- } else
- offset += 13;
- proto_tree_add_item(wlan_tree, hf_netmon_802_11_timestamp, tvb, offset, 8,
- ENC_LITTLE_ENDIAN);
- /*offset += 8;*/
-
- }
-
- /* no return */
+ }
+ offset += 4;
+ rate = tvb_get_guint8(tvb, offset);
+ if (rate == 0) {
+ proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_datarate,
+ tvb, offset, 1, rate,
+ "Unknown");
+ } else {
+ phdr->presence_flags |= PHDR_802_11_HAS_DATA_RATE;
+ phdr->data_rate = rate;
+ proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_datarate,
+ tvb, offset, 1, rate,
+ "%f Mb/s", rate*.5);
+ }
+ offset += 1;
+ } else
+ offset += 13;
+ phdr->presence_flags |= PHDR_802_11_HAS_TSF_TIMESTAMP;
+ phdr->tsf_timestamp = tvb_get_letoh64(tvb, offset);
+ proto_tree_add_item(wlan_tree, hf_netmon_802_11_timestamp, tvb, offset, 8,
+ ENC_LITTLE_ENDIAN);
+ /*offset += 8;*/
skip:
offset = length;
- /* dissect the 802.11 header next */
+ /* dissect the 802.11 packet next */
next_tvb = tvb_new_subset_remaining(tvb, offset);
- call_dissector(ieee80211_handle, next_tvb, pinfo, tree);
+ call_dissector_with_data(ieee80211_radio_handle, next_tvb, pinfo, tree, phdr);
return offset;
}
@@ -235,8 +253,8 @@ proto_reg_handoff_netmon_802_11(void)
{
dissector_handle_t netmon_802_11_handle;
- /* handle for 802.11 dissector */
- ieee80211_handle = find_dissector("wlan");
+ /* handle for 802.11+radio information dissector */
+ ieee80211_radio_handle = find_dissector("wlan_radio");
netmon_802_11_handle = new_create_dissector_handle(dissect_netmon_802_11,
proto_netmon_802_11);
dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE_802_11_NETMON, netmon_802_11_handle);
diff --git a/epan/dissectors/packet-ieee80211-radio.c b/epan/dissectors/packet-ieee80211-radio.c
index f965396e14..549cf4377b 100644
--- a/epan/dissectors/packet-ieee80211-radio.c
+++ b/epan/dissectors/packet-ieee80211-radio.c
@@ -32,23 +32,25 @@
void proto_register_ieee80211_radio(void);
void proto_reg_handoff_ieee80211_radio(void);
+static dissector_handle_t wlan_radio_handle;
static dissector_handle_t ieee80211_handle;
-static int proto_radio = -1;
+static int proto_wlan_radio = -1;
/* ************************************************************************* */
/* Header field info values for radio information */
/* ************************************************************************* */
-static int hf_data_rate = -1;
-static int hf_mcs_index = -1;
-static int hf_bandwidth = -1;
-static int hf_short_gi = -1;
-static int hf_channel = -1;
-static int hf_frequency = -1;
-static int hf_signal_percent = -1;
-static int hf_signal_dbm = -1;
-static int hf_noise_percent = -1;
-static int hf_noise_dbm = -1;
+static int hf_wlan_radio_data_rate = -1;
+static int hf_wlan_radio_mcs_index = -1;
+static int hf_wlan_radio_bandwidth = -1;
+static int hf_wlan_radio_short_gi = -1;
+static int hf_wlan_radio_channel = -1;
+static int hf_wlan_radio_frequency = -1;
+static int hf_wlan_radio_signal_percent = -1;
+static int hf_wlan_radio_signal_dbm = -1;
+static int hf_wlan_radio_noise_percent = -1;
+static int hf_wlan_radio_noise_dbm = -1;
+static int hf_wlan_radio_timestamp = -1;
static const value_string bandwidth_vals[] = {
{ PHDR_802_11_BANDWIDTH_20_MHZ, "20 MHz" },
@@ -458,15 +460,16 @@ const float ieee80211_float_htrates[MAX_MCS_INDEX+1][2][2] = {
},
};
-static gint ett_radio = -1;
+static gint ett_wlan_radio = -1;
/*
* Dissect 802.11 with a variable-length link-layer header and a pseudo-
* header containing radio information.
*/
static int
-dissect_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void *data)
+dissect_wlan_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void *data)
{
+ struct ieee_802_11_phdr *phdr = (struct ieee_802_11_phdr *)data;
proto_item *ti = NULL;
proto_tree *radio_tree = NULL;
float data_rate = 0.0f;
@@ -476,8 +479,8 @@ dissect_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void *dat
col_clear(pinfo->cinfo, COL_INFO);
/* Calculate the data rate, if we have the necessary data */
- if (pinfo->pseudo_header->ieee_802_11.presence_flags & PHDR_802_11_HAS_DATA_RATE) {
- data_rate = pinfo->pseudo_header->ieee_802_11.data_rate * 0.5f;
+ if (phdr->presence_flags & PHDR_802_11_HAS_DATA_RATE) {
+ data_rate = phdr->data_rate * 0.5f;
have_data_rate = TRUE;
} else {
/* Do we have all the fields we need to look it up? */
@@ -488,12 +491,12 @@ dissect_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void *dat
guint bandwidth_40;
- if ((pinfo->pseudo_header->ieee_802_11.presence_flags & PHDR_802_11_ALL_MCS_FIELDS) == PHDR_802_11_ALL_MCS_FIELDS) {
+ if ((phdr->presence_flags & PHDR_802_11_ALL_MCS_FIELDS) == PHDR_802_11_ALL_MCS_FIELDS) {
bandwidth_40 =
- (pinfo->pseudo_header->ieee_802_11.bandwidth == PHDR_802_11_BANDWIDTH_40_MHZ) ?
+ (phdr->bandwidth == PHDR_802_11_BANDWIDTH_40_MHZ) ?
1 : 0;
- if (pinfo->pseudo_header->ieee_802_11.mcs_index < MAX_MCS_INDEX) {
- data_rate = ieee80211_float_htrates[pinfo->pseudo_header->ieee_802_11.mcs_index][bandwidth_40][pinfo->pseudo_header->ieee_802_11.short_gi];
+ if (phdr->mcs_index < MAX_MCS_INDEX) {
+ data_rate = ieee80211_float_htrates[phdr->mcs_index][bandwidth_40][phdr->short_gi];
have_data_rate = TRUE;
}
}
@@ -503,7 +506,7 @@ dissect_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void *dat
if (have_data_rate)
col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%.1f", data_rate);
- if (pinfo->pseudo_header->ieee_802_11.presence_flags & PHDR_802_11_HAS_SIGNAL_PERCENT) {
+ if (phdr->presence_flags & PHDR_802_11_HAS_SIGNAL_PERCENT) {
/*
* For tagged Peek files, this is presumably signal strength as a
* percentage of the maximum, as it is for classic Peek files,
@@ -518,143 +521,151 @@ dissect_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void *dat
* It's *probably* something similar for other capture file formats.
*/
col_add_fstr(pinfo->cinfo, COL_RSSI, "%u%%",
- pinfo->pseudo_header->ieee_802_11.signal_percent);
+ phdr->signal_percent);
}
if (tree) {
- ti = proto_tree_add_item(tree, proto_radio, tvb, 0, 0, ENC_NA);
- radio_tree = proto_item_add_subtree (ti, ett_radio);
+ ti = proto_tree_add_item(tree, proto_wlan_radio, tvb, 0, 0, ENC_NA);
+ radio_tree = proto_item_add_subtree (ti, ett_wlan_radio);
- if (pinfo->pseudo_header->ieee_802_11.presence_flags & PHDR_802_11_HAS_MCS_INDEX) {
- proto_tree_add_uint(radio_tree, hf_mcs_index, tvb, 0, 0,
- pinfo->pseudo_header->ieee_802_11.mcs_index);
+ if (phdr->presence_flags & PHDR_802_11_HAS_MCS_INDEX) {
+ proto_tree_add_uint(radio_tree, hf_wlan_radio_mcs_index, tvb, 0, 0,
+ phdr->mcs_index);
}
- if (pinfo->pseudo_header->ieee_802_11.presence_flags & PHDR_802_11_HAS_BANDWIDTH) {
- proto_tree_add_uint(radio_tree, hf_bandwidth, tvb, 0, 0,
- pinfo->pseudo_header->ieee_802_11.bandwidth);
+ if (phdr->presence_flags & PHDR_802_11_HAS_BANDWIDTH) {
+ proto_tree_add_uint(radio_tree, hf_wlan_radio_bandwidth, tvb, 0, 0,
+ phdr->bandwidth);
}
- if (pinfo->pseudo_header->ieee_802_11.presence_flags & PHDR_802_11_HAS_SHORT_GI) {
- proto_tree_add_boolean(radio_tree, hf_short_gi, tvb, 0, 0,
- pinfo->pseudo_header->ieee_802_11.short_gi);
+ if (phdr->presence_flags & PHDR_802_11_HAS_SHORT_GI) {
+ proto_tree_add_boolean(radio_tree, hf_wlan_radio_short_gi, tvb, 0, 0,
+ phdr->short_gi);
}
if (have_data_rate) {
- proto_tree_add_float_format_value(radio_tree, hf_data_rate, tvb, 0, 0,
+ proto_tree_add_float_format_value(radio_tree, hf_wlan_radio_data_rate, tvb, 0, 0,
data_rate,
"%.1f Mb/s",
data_rate);
}
- if (pinfo->pseudo_header->ieee_802_11.presence_flags & PHDR_802_11_HAS_CHANNEL) {
- proto_tree_add_uint(radio_tree, hf_channel, tvb, 0, 0,
- pinfo->pseudo_header->ieee_802_11.channel);
+ if (phdr->presence_flags & PHDR_802_11_HAS_CHANNEL) {
+ proto_tree_add_uint(radio_tree, hf_wlan_radio_channel, tvb, 0, 0,
+ phdr->channel);
}
- if (pinfo->pseudo_header->ieee_802_11.presence_flags & PHDR_802_11_HAS_FREQUENCY) {
- proto_tree_add_uint_format_value(radio_tree, hf_frequency, tvb, 0, 0,
- pinfo->pseudo_header->ieee_802_11.frequency,
+ if (phdr->presence_flags & PHDR_802_11_HAS_FREQUENCY) {
+ proto_tree_add_uint_format_value(radio_tree, hf_wlan_radio_frequency, tvb, 0, 0,
+ phdr->frequency,
"%u MHz",
- pinfo->pseudo_header->ieee_802_11.frequency);
+ phdr->frequency);
}
- if (pinfo->pseudo_header->ieee_802_11.presence_flags & PHDR_802_11_HAS_SIGNAL_PERCENT) {
- proto_tree_add_uint_format_value(radio_tree, hf_signal_percent, tvb, 0, 0,
- pinfo->pseudo_header->ieee_802_11.signal_percent,
+ if (phdr->presence_flags & PHDR_802_11_HAS_SIGNAL_PERCENT) {
+ proto_tree_add_uint_format_value(radio_tree, hf_wlan_radio_signal_percent, tvb, 0, 0,
+ phdr->signal_percent,
"%u%%",
- pinfo->pseudo_header->ieee_802_11.signal_percent);
+ phdr->signal_percent);
}
- if (pinfo->pseudo_header->ieee_802_11.presence_flags & PHDR_802_11_HAS_SIGNAL_DBM) {
- proto_tree_add_int_format_value(radio_tree, hf_signal_dbm, tvb, 0, 0,
- pinfo->pseudo_header->ieee_802_11.signal_dbm,
+ if (phdr->presence_flags & PHDR_802_11_HAS_SIGNAL_DBM) {
+ proto_tree_add_int_format_value(radio_tree, hf_wlan_radio_signal_dbm, tvb, 0, 0,
+ phdr->signal_dbm,
"%d dBm",
- pinfo->pseudo_header->ieee_802_11.signal_dbm);
+ phdr->signal_dbm);
}
- if (pinfo->pseudo_header->ieee_802_11.presence_flags & PHDR_802_11_HAS_NOISE_PERCENT) {
- proto_tree_add_uint_format_value(radio_tree, hf_noise_percent, tvb, 0, 0,
- pinfo->pseudo_header->ieee_802_11.noise_percent,
+ if (phdr->presence_flags & PHDR_802_11_HAS_NOISE_PERCENT) {
+ proto_tree_add_uint_format_value(radio_tree, hf_wlan_radio_noise_percent, tvb, 0, 0,
+ phdr->noise_percent,
"%u%%",
- pinfo->pseudo_header->ieee_802_11.noise_percent);
+ phdr->noise_percent);
}
- if (pinfo->pseudo_header->ieee_802_11.presence_flags & PHDR_802_11_HAS_NOISE_DBM) {
- proto_tree_add_int_format_value(radio_tree, hf_noise_dbm, tvb, 0, 0,
- pinfo->pseudo_header->ieee_802_11.noise_dbm,
+ if (phdr->presence_flags & PHDR_802_11_HAS_NOISE_DBM) {
+ proto_tree_add_int_format_value(radio_tree, hf_wlan_radio_noise_dbm, tvb, 0, 0,
+ phdr->noise_dbm,
"%d dBm",
- pinfo->pseudo_header->ieee_802_11.noise_dbm);
+ phdr->noise_dbm);
+ }
+
+ if (phdr->presence_flags & PHDR_802_11_HAS_TSF_TIMESTAMP) {
+ proto_tree_add_uint64(radio_tree, hf_wlan_radio_timestamp, tvb, 0, 0,
+ phdr->tsf_timestamp);
}
}
- /* dissect the 802.11 header next */
+ /* dissect the 802.11 packet next */
pinfo->current_proto = "IEEE 802.11";
return call_dissector_with_data(ieee80211_handle, tvb, pinfo, tree, data);
}
-static hf_register_info hf_radio[] = {
- {&hf_data_rate,
- {"Data rate", "wlan.data_rate", FT_FLOAT, BASE_NONE, NULL, 0,
+static hf_register_info hf_wlan_radio[] = {
+ {&hf_wlan_radio_data_rate,
+ {"Data rate", "wlan_radio.data_rate", FT_FLOAT, BASE_NONE, NULL, 0,
"Data rate (bits/s)", HFILL }},
- {&hf_mcs_index,
- {"MCS index", "wlan.mcs_index", FT_UINT32, BASE_DEC, NULL, 0,
+ {&hf_wlan_radio_mcs_index,
+ {"MCS index", "wlan_radio.mcs_index", FT_UINT32, BASE_DEC, NULL, 0,
NULL, HFILL }},
- {&hf_bandwidth,
- {"Bandwidth", "wlan.bandwidth", FT_UINT32, BASE_DEC, VALS(bandwidth_vals), 0,
+ {&hf_wlan_radio_bandwidth,
+ {"Bandwidth", "wlan_radio.bandwidth", FT_UINT32, BASE_DEC, VALS(bandwidth_vals), 0,
NULL, HFILL }},
- {&hf_short_gi,
- {"Short GI", "wlan.short_gi", FT_BOOLEAN, 0, NULL, 0,
+ {&hf_wlan_radio_short_gi,
+ {"Short GI", "wlan_radio.short_gi", FT_BOOLEAN, 0, NULL, 0,
NULL, HFILL }},
- {&hf_channel,
- {"Channel", "wlan.channel", FT_UINT8, BASE_DEC, NULL, 0,
+ {&hf_wlan_radio_channel,
+ {"Channel", "wlan_radio.channel", FT_UINT8, BASE_DEC, NULL, 0,
"802.11 channel number that this frame was sent/received on", HFILL }},
- {&hf_frequency,
- {"Frequency", "wlan.frequency", FT_UINT16, BASE_DEC, NULL, 0,
+ {&hf_wlan_radio_frequency,
+ {"Frequency", "wlan_radio.frequency", FT_UINT16, BASE_DEC, NULL, 0,
"Center frequency of the 802.11 channel that this frame was sent/received on", HFILL }},
- {&hf_signal_percent,
- {"Signal strength (percentage)", "wlan.signal_dbm", FT_UINT8, BASE_DEC, NULL, 0,
+ {&hf_wlan_radio_signal_percent,
+ {"Signal strength (percentage)", "wlan_radio.signal_dbm", FT_UINT8, BASE_DEC, NULL, 0,
"Signal strength, as percentage of maximum RSSI", HFILL }},
- {&hf_signal_dbm,
- {"Signal strength (dBm)", "wlan.signal_dbm", FT_INT8, BASE_DEC, NULL, 0,
+ {&hf_wlan_radio_signal_dbm,
+ {"Signal strength (dBm)", "wlan_radio.signal_dbm", FT_INT8, BASE_DEC, NULL, 0,
+ NULL, HFILL }},
+
+ {&hf_wlan_radio_noise_percent,
+ {"Noise level (percentage)", "wlan_radio.noise_percentage", FT_UINT8, BASE_DEC, NULL, 0,
NULL, HFILL }},
- {&hf_noise_percent,
- {"Noise level (percentage)", "wlan.noise_percentage", FT_UINT8, BASE_DEC, NULL, 0,
+ {&hf_wlan_radio_noise_dbm,
+ {"Noise level (dBm)", "wlan_radio.noise_dbm", FT_INT8, BASE_DEC, NULL, 0,
NULL, HFILL }},
- {&hf_noise_dbm,
- {"Noise level (dBm)", "wlan.noise_dbm", FT_INT8, BASE_DEC, NULL, 0,
+ {&hf_wlan_radio_timestamp,
+ {"TSF timestamp", "wlan_radio.timestamp", FT_UINT64, BASE_DEC, NULL, 0,
NULL, HFILL }},
};
static gint *tree_array[] = {
- &ett_radio
+ &ett_wlan_radio
};
void proto_register_ieee80211_radio(void)
{
- proto_radio = proto_register_protocol("802.11 radio information", "Radio",
- "radio");
- proto_register_field_array(proto_radio, hf_radio, array_length(hf_radio));
+ proto_wlan_radio = proto_register_protocol("802.11 radio information", "802.11 Radio",
+ "wlan_radio");
+ proto_register_field_array(proto_wlan_radio, hf_wlan_radio, array_length(hf_wlan_radio));
proto_register_subtree_array(tree_array, array_length(tree_array));
+
+ wlan_radio_handle = new_register_dissector("wlan_radio", dissect_wlan_radio, proto_wlan_radio);
}
void proto_reg_handoff_ieee80211_radio(void)
{
- dissector_handle_t radio_handle;
-
/* Register handoff to radio-header dissectors */
- radio_handle = new_create_dissector_handle(dissect_radio, proto_radio);
dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE_802_11_WITH_RADIO,
- radio_handle);
+ wlan_radio_handle);
ieee80211_handle = find_dissector("wlan");
}
diff --git a/epan/dissectors/packet-ieee80211-radiotap.c b/epan/dissectors/packet-ieee80211-radiotap.c
index be696547a2..78bb206a17 100644
--- a/epan/dissectors/packet-ieee80211-radiotap.c
+++ b/epan/dissectors/packet-ieee80211-radiotap.c
@@ -215,8 +215,7 @@ static expert_field ei_radiotap_data_past_header = EI_INIT;
static expert_field ei_radiotap_present_reserved = EI_INIT;
static expert_field ei_radiotap_present = EI_INIT;
-static dissector_handle_t ieee80211_handle;
-static dissector_handle_t ieee80211_datapad_handle;
+static dissector_handle_t ieee80211_radio_handle;
static int radiotap_tap = -1;
@@ -608,6 +607,7 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
/* We don't have any 802.11 metadata yet. */
phdr.fcs_len = -1;
phdr.decrypted = FALSE;
+ phdr.datapad = FALSE;
phdr.presence_flags = 0;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "WLAN");
@@ -826,6 +826,8 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
case IEEE80211_RADIOTAP_TSFT:
radiotap_info->tsft = tvb_get_letoh64(tvb, offset);
+ phdr.tsf_timestamp = radiotap_info->tsft;
+ phdr.presence_flags |= PHDR_802_11_HAS_TSF_TIMESTAMP;
if (tree) {
proto_tree_add_uint64(radiotap_tree,
hf_radiotap_mactime, tvb,
@@ -836,10 +838,22 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
case IEEE80211_RADIOTAP_FLAGS: {
rflags = tvb_get_guint8(tvb, offset);
+ if (rflags & IEEE80211_RADIOTAP_F_DATAPAD)
+ phdr.datapad = TRUE;
if (rflags & IEEE80211_RADIOTAP_F_FCS)
phdr.fcs_len = 4;
else
phdr.fcs_len = 0;
+ /*
+ * This is "Currently unspecified but used",
+ * according to the radiotap.org page for
+ * the Flags field.
+ */
+ phdr.presence_flags |= PHDR_802_11_HAS_SHORT_GI;
+ if (rflags & 0x80)
+ phdr.short_gi = 1;
+ else
+ phdr.short_gi = 0;
if (tree) {
proto_tree *flags_tree;
@@ -938,11 +952,22 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
(float)rate / 2);
}
radiotap_info->rate = rate;
+ phdr.presence_flags |= PHDR_802_11_HAS_DATA_RATE;
+ phdr.data_rate = rate;
}
break;
}
case IEEE80211_RADIOTAP_CHANNEL: {
+ freq = tvb_get_letohs(tvb, offset);
+ if (freq != 0) {
+ /*
+ * XXX - some captures have 0, which is
+ * obviously bogus.
+ */
+ phdr.presence_flags |= PHDR_802_11_HAS_FREQUENCY;
+ phdr.frequency = freq;
+ }
if (tree) {
guint16 flags;
gchar *chan_str;
@@ -962,7 +987,6 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
NULL
};
- freq = tvb_get_letohs(tvb, offset);
flags = tvb_get_letohs(tvb, offset + 2);
chan_str = ieee80211_mhz_to_str(freq);
col_add_fstr(pinfo->cinfo,
@@ -1153,7 +1177,46 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
mcs_known = tvb_get_guint8(tvb, offset);
mcs_flags = tvb_get_guint8(tvb, offset + 1);
- mcs = tvb_get_guint8(tvb, offset + 2);
+ if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_MCS) {
+ mcs = tvb_get_guint8(tvb, offset + 2);
+ phdr.presence_flags |= PHDR_802_11_HAS_MCS_INDEX;
+ phdr.mcs_index = mcs;
+ } else {
+ mcs = 0;
+ can_calculate_rate = FALSE; /* no MCS index */
+ }
+ if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_BW) {
+ phdr.presence_flags |= PHDR_802_11_HAS_BANDWIDTH;
+ phdr.bandwidth = (mcs_flags & IEEE80211_RADIOTAP_MCS_BW_MASK);
+ }
+ if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_GI) {
+ gi_length = (mcs_flags & IEEE80211_RADIOTAP_MCS_SGI) ?
+ 1 : 0;
+ phdr.presence_flags |= PHDR_802_11_HAS_SHORT_GI;
+ phdr.short_gi = (gi_length == 0);
+ } else {
+ gi_length = 0;
+ can_calculate_rate = FALSE; /* no GI width */
+ }
+ if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_FMT) {
+ phdr.presence_flags |= PHDR_802_11_HAS_GREENFIELD;
+ phdr.greenfield = (mcs_flags & IEEE80211_RADIOTAP_MCS_FMT_GF) != 0;
+ }
+ if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_FEC) {
+ phdr.presence_flags |= PHDR_802_11_HAS_LDPC;
+ phdr.ldpc = (mcs_flags & IEEE80211_RADIOTAP_MCS_FEC_LDPC) != 0;
+ }
+ if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_STBC) {
+ phdr.presence_flags |= PHDR_802_11_HAS_STBC_STREAMS;
+ phdr.stbc_streams = (mcs_flags & IEEE80211_RADIOTAP_MCS_STBC_MASK) >> IEEE80211_RADIOTAP_MCS_STBC_SHIFT;
+ }
+ if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_NESS) {
+ phdr.presence_flags |= PHDR_802_11_HAS_NESS;
+ /* This is stored a bit weirdly */
+ phdr.ness =
+ ((mcs_known & IEEE80211_RADIOTAP_MCS_NESS_BIT1) >> 6) |
+ ((mcs_flags & IEEE80211_RADIOTAP_MCS_NESS_BIT0) >> 7);
+ }
if (tree) {
proto_item *it;
@@ -1198,13 +1261,8 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
can_calculate_rate = FALSE; /* no bandwidth */
}
if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_GI) {
- gi_length = (mcs_flags & IEEE80211_RADIOTAP_MCS_SGI) ?
- 1 : 0;
proto_tree_add_uint(mcs_tree, hf_radiotap_mcs_gi,
tvb, offset + 1, 1, mcs_flags);
- } else {
- gi_length = 0;
- can_calculate_rate = FALSE; /* no GI width */
}
if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_FMT) {
proto_tree_add_uint(mcs_tree, hf_radiotap_mcs_format,
@@ -1225,8 +1283,7 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_MCS) {
proto_tree_add_uint(mcs_tree, hf_radiotap_mcs_index,
tvb, offset + 2, 1, mcs);
- } else
- can_calculate_rate = FALSE; /* no MCS index */
+ }
/*
* If we have the MCS index, channel width, and
@@ -1516,8 +1573,7 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
}
/* dissect the 802.11 packet next */
- call_dissector_with_data((rflags & IEEE80211_RADIOTAP_F_DATAPAD) ?
- ieee80211_datapad_handle : ieee80211_handle, next_tvb, pinfo,
+ call_dissector_with_data(ieee80211_radio_handle, next_tvb, pinfo,
tree, &phdr);
tap_queue_packet(radiotap_tap, pinfo, radiotap_info);
@@ -1991,6 +2047,11 @@ void proto_register_radiotap(void)
FT_BOOLEAN, 8, TFS(&tfs_present_absent), IEEE80211_RADIOTAP_MCS_HAVE_BW,
"Bandwidth information present", HFILL}},
+ {&hf_radiotap_mcs_have_index,
+ {"MCS index", "radiotap.mcs.have_index",
+ FT_BOOLEAN, 8, TFS(&tfs_present_absent), IEEE80211_RADIOTAP_MCS_HAVE_MCS,
+ "MCS index information present", HFILL}},
+
{&hf_radiotap_mcs_have_gi,
{"Guard interval", "radiotap.mcs.have_gi",
FT_BOOLEAN, 8, TFS(&tfs_present_absent), IEEE80211_RADIOTAP_MCS_HAVE_GI,
@@ -2021,11 +2082,6 @@ void proto_register_radiotap(void)
FT_BOOLEAN, 8, TFS(&tfs_1_0), IEEE80211_RADIOTAP_MCS_NESS_BIT1,
"Bit 1 of number of extension spatial streams information", HFILL}},
- {&hf_radiotap_mcs_have_index,
- {"MCS index", "radiotap.mcs.have_index",
- FT_BOOLEAN, 8, TFS(&tfs_present_absent), IEEE80211_RADIOTAP_MCS_HAVE_MCS,
- "MCS index information present", HFILL}},
-
{&hf_radiotap_mcs_bw,
{"Bandwidth", "radiotap.mcs.bw",
FT_UINT8, BASE_DEC, VALS(mcs_bandwidth),
@@ -2391,9 +2447,8 @@ void proto_reg_handoff_radiotap(void)
{
dissector_handle_t radiotap_handle;
- /* handle for 802.11 dissector */
- ieee80211_handle = find_dissector("wlan");
- ieee80211_datapad_handle = find_dissector("wlan_datapad");
+ /* handle for 802.11+radio information dissector */
+ ieee80211_radio_handle = find_dissector("wlan_radio");
radiotap_handle = find_dissector("radiotap");
diff --git a/epan/dissectors/packet-ieee80211.c b/epan/dissectors/packet-ieee80211.c
index a09caaca2c..aa22747cd9 100644
--- a/epan/dissectors/packet-ieee80211.c
+++ b/epan/dissectors/packet-ieee80211.c
@@ -16563,10 +16563,9 @@ typedef enum {
static int
dissect_ieee80211_common (tvbuff_t *tvb, packet_info *pinfo,
- proto_tree *tree, gboolean fixed_length_header, gint fcs_len,
- gboolean wlan_broken_fc, gboolean datapad,
- gboolean is_ht, gboolean is_centrino,
- struct ieee_802_11_phdr *phdr)
+ proto_tree *tree, gboolean fixed_length_header,
+ gboolean wlan_broken_fc, gboolean is_ht,
+ gboolean is_centrino, struct ieee_802_11_phdr *phdr)
{
guint16 fcf, flags, frame_type_subtype, ctrl_fcf, ctrl_type_subtype;
guint16 seq_control;
@@ -16673,7 +16672,7 @@ dissect_ieee80211_common (tvbuff_t *tvb, packet_info *pinfo,
* of recalculating it every time we need it.
*/
ohdr_len = hdr_len;
- if (datapad)
+ if (phdr->datapad)
hdr_len = roundup2(hdr_len, 4);
/* Add the FC and duration/id to the current tree */
@@ -16687,7 +16686,7 @@ dissect_ieee80211_common (tvbuff_t *tvb, packet_info *pinfo,
dissect_durid(hdr_tree, tvb, frame_type_subtype, 2);
}
- switch (fcs_len)
+ switch (phdr->fcs_len)
{
case 0: /* Definitely has no FCS */
has_fcs = FALSE;
@@ -17507,7 +17506,7 @@ dissect_ieee80211_common (tvbuff_t *tvb, packet_info *pinfo,
guint32 sent_fcs = tvb_get_ntohl(tvb, hdr_len + len);
guint32 fcs;
- if (datapad)
+ if (phdr->datapad)
fcs = crc32_802_tvb_padded(tvb, ohdr_len, hdr_len, len);
else
fcs = crc32_802_tvb(tvb, hdr_len + len);
@@ -17770,7 +17769,7 @@ dissect_ieee80211_common (tvbuff_t *tvb, packet_info *pinfo,
}
if (IS_PROTECTED(FCF_FLAGS(fcf))
- && (phdr == NULL || !phdr->decrypted)
+ && !phdr->decrypted
&& (wlan_ignore_wep != WLAN_IGNORE_WEP_WO_IV)) {
/*
* It's a WEP or WPA encrypted frame, and it hasn't already been
@@ -18272,80 +18271,76 @@ dissect_ieee80211_common (tvbuff_t *tvb, packet_info *pinfo,
/*
* Dissect 802.11 with a variable-length link-layer header and with the FCS
- * presence or absence indicated by the pseudo-header.
+ * presence or absence indicated by the pseudo-header, if there is one.
*/
static int
dissect_ieee80211 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
struct ieee_802_11_phdr *phdr = (struct ieee_802_11_phdr *)data;
+ struct ieee_802_11_phdr ourphdr;
- return dissect_ieee80211_common (tvb, pinfo, tree, FALSE,
- (phdr == NULL) ? -1 : phdr->fcs_len, FALSE, FALSE, FALSE, FALSE, phdr);
+ if (phdr == NULL) {
+ /*
+ * Fake a pseudo-header.
+ * XXX - what are we supposed to do if the FCS length is unknown?
+ */
+ ourphdr.fcs_len = -1;
+ ourphdr.decrypted = FALSE;
+ ourphdr.datapad = FALSE;
+ ourphdr.presence_flags = 0;
+ phdr = &ourphdr;
+ }
+ return dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, FALSE, FALSE, phdr);
}
/*
* Dissect 802.11 with a variable-length link-layer header and with an
- * FCS.
+ * FCS, but no pseudo-header.
*/
static void
dissect_ieee80211_withfcs (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
- dissect_ieee80211_common (tvb, pinfo, tree, FALSE, 4, FALSE, FALSE, FALSE, FALSE, NULL);
+ struct ieee_802_11_phdr phdr;
+
+ /* Construct a pseudo-header to hand to the common code. */
+ phdr.fcs_len = 4;
+ phdr.decrypted = FALSE;
+ phdr.datapad = FALSE;
+ phdr.presence_flags = 0;
+ dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, FALSE, FALSE, &phdr);
}
/*
* Dissect 802.11 with a variable-length link-layer header and without an
- * FCS.
+ * FCS, but no pseudo-header.
*/
static void
dissect_ieee80211_withoutfcs (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
- dissect_ieee80211_common (tvb, pinfo, tree, FALSE, 0, FALSE, FALSE, FALSE, FALSE, NULL);
-}
-
-/*
- * Dissect 802.11 with a variable-length link-layer header.
- */
-static int
-dissect_ieee80211_centrino(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
-{
- struct ieee_802_11_phdr *phdr = (struct ieee_802_11_phdr *)data;
-
- return dissect_ieee80211_common (tvb, pinfo, tree, FALSE,
- (phdr == NULL) ? -1 : phdr->fcs_len, FALSE, FALSE, FALSE, TRUE, phdr);
-}
-
-/*
- * Dissect 802.11 with a variable-length link-layer header and data padding
- * and with the FCS presence or absence indicated by the pseudo-header.
- */
-static int
-dissect_ieee80211_datapad (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
-{
- struct ieee_802_11_phdr *phdr = (struct ieee_802_11_phdr *)data;
+ struct ieee_802_11_phdr phdr;
- return dissect_ieee80211_common (tvb, pinfo, tree, FALSE,
- (phdr == NULL) ? -1 : phdr->fcs_len, FALSE, TRUE, FALSE, FALSE, phdr);
+ /* Construct a pseudo-header to hand to the common code. */
+ phdr.fcs_len = 0;
+ phdr.decrypted = FALSE;
+ phdr.datapad = FALSE;
+ phdr.presence_flags = 0;
+ dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, FALSE, FALSE, &phdr);
}
/*
- * Dissect 802.11 with a variable-length link-layer header and data padding
- * and with an FCS.
+ * Dissect 802.11 with a variable-length link-layer header.
*/
static void
-dissect_ieee80211_datapad_withfcs (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+dissect_ieee80211_centrino(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
- dissect_ieee80211_common (tvb, pinfo, tree, FALSE, 4, FALSE, TRUE, FALSE, FALSE, NULL);
-}
+ struct ieee_802_11_phdr phdr;
-/*
- * Dissect 802.11 with a variable-length link-layer header and data padding
- * and without an FCS.
- */
-static void
-dissect_ieee80211_datapad_withoutfcs (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
-{
- dissect_ieee80211_common (tvb, pinfo, tree, FALSE, 0, FALSE, TRUE, FALSE, FALSE, NULL);
+ /* Construct a pseudo-header to hand to the common code. */
+ phdr.fcs_len = 0;
+ phdr.decrypted = FALSE;
+ phdr.datapad = FALSE;
+ phdr.presence_flags = 0;
+ dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, FALSE, TRUE, &phdr);
}
/*
@@ -18356,7 +18351,14 @@ dissect_ieee80211_datapad_withoutfcs (tvbuff_t *tvb, packet_info *pinfo, proto_t
static void
dissect_ieee80211_bsfc (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
- dissect_ieee80211_common (tvb, pinfo, tree, FALSE, 0, TRUE, FALSE, FALSE, FALSE, NULL);
+ struct ieee_802_11_phdr phdr;
+
+ /* Construct a pseudo-header to hand to the common code. */
+ phdr.fcs_len = 0;
+ phdr.decrypted = FALSE;
+ phdr.datapad = FALSE;
+ phdr.presence_flags = 0;
+ dissect_ieee80211_common (tvb, pinfo, tree, FALSE, TRUE, FALSE, FALSE, &phdr);
}
/*
@@ -18366,7 +18368,14 @@ dissect_ieee80211_bsfc (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
static void
dissect_ieee80211_fixed (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
- dissect_ieee80211_common (tvb, pinfo, tree, TRUE, 0, FALSE, FALSE, FALSE, FALSE, NULL);
+ struct ieee_802_11_phdr phdr;
+
+ /* Construct a pseudo-header to hand to the common code. */
+ phdr.fcs_len = 0;
+ phdr.decrypted = FALSE;
+ phdr.datapad = FALSE;
+ phdr.presence_flags = 0;
+ dissect_ieee80211_common (tvb, pinfo, tree, TRUE, FALSE, FALSE, FALSE, &phdr);
}
/*
@@ -18379,8 +18388,7 @@ dissect_ieee80211_ht (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
{
struct ieee_802_11_phdr *phdr = (struct ieee_802_11_phdr *)data;
- return dissect_ieee80211_common (tvb, pinfo, tree, FALSE,
- (phdr == NULL) ? -1 : phdr->fcs_len, FALSE, FALSE, TRUE, FALSE, phdr);
+ return dissect_ieee80211_common (tvb, pinfo, tree, FALSE, FALSE, TRUE, FALSE, phdr);
}
static void
@@ -26932,9 +26940,6 @@ proto_register_ieee80211 (void)
register_dissector("wlan_withoutfcs", dissect_ieee80211_withoutfcs, proto_wlan);
register_dissector("wlan_fixed", dissect_ieee80211_fixed, proto_wlan);
register_dissector("wlan_bsfc", dissect_ieee80211_bsfc, proto_wlan);
- new_register_dissector("wlan_datapad", dissect_ieee80211_datapad, proto_wlan);
- register_dissector("wlan_datapad_withfcs", dissect_ieee80211_datapad_withfcs, proto_wlan);
- register_dissector("wlan_datapad_withoutfcs", dissect_ieee80211_datapad_withoutfcs, proto_wlan);
new_register_dissector("wlan_ht", dissect_ieee80211_ht, proto_wlan);
register_init_routine(wlan_defragment_init);
@@ -27158,9 +27163,8 @@ proto_reg_handoff_ieee80211(void)
ieee80211_handle = find_dissector("wlan");
dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE_802_11, ieee80211_handle);
- dissector_add_uint("wtap_encap", WTAP_ENCAP_IEEE_802_11_WITH_RADIO, ieee80211_handle);
- centrino_handle = new_create_dissector_handle( dissect_ieee80211_centrino, proto_wlan );
+ centrino_handle = create_dissector_handle( dissect_ieee80211_centrino, proto_wlan );
dissector_add_uint("ethertype", ETHERTYPE_CENTRINO_PROMISC, centrino_handle);
/* Register handoff to Aruba GRE */
diff --git a/epan/dissectors/packet-ixveriwave.c b/epan/dissectors/packet-ixveriwave.c
index 8dfd4872e6..c0fd5331d3 100644
--- a/epan/dissectors/packet-ixveriwave.c
+++ b/epan/dissectors/packet-ixveriwave.c
@@ -124,7 +124,7 @@ static gint ett_radiotap_present = -1;
static gint ett_radiotap_flags = -1;
/* static gint ett_radiotap_channel_flags = -1; */
-static dissector_handle_t ieee80211_handle;
+static dissector_handle_t ieee80211_radio_handle;
/* Ethernet fields */
static int hf_ixveriwave_vw_info = -1;
@@ -653,6 +653,7 @@ wlantap_dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree
guint length;
gint8 dbm;
guint8 mcs_index;
+ guint8 ness;
float phyRate;
proto_tree *vweft, *vw_errorFlags_tree = NULL, *vwift,*vw_infoFlags_tree = NULL;
@@ -661,6 +662,13 @@ wlantap_dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree
ifg_info *p_ifg_info;
proto_item *ti;
+ struct ieee_802_11_phdr phdr;
+
+ /* We don't have any 802.11 metadata yet. */
+ phdr.fcs_len = 0; /* no FCS */
+ phdr.decrypted = FALSE;
+ phdr.datapad = FALSE;
+ phdr.presence_flags = 0;
/* First add the IFG information, need to grab the info bit field here */
vw_info = tvb_get_letohs(tvb, 20);
@@ -679,6 +687,10 @@ wlantap_dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree
offset += 2;
vw_rflags = tvb_get_letohs(tvb, offset);
+ if ((vw_rflags & FLAGS_CHAN_HT) || (vw_rflags & FLAGS_CHAN_VHT) ) {
+ phdr.presence_flags |= PHDR_802_11_HAS_SHORT_GI;
+ phdr.short_gi = ((vw_rflags & FLAGS_CHAN_SHORTGI) != 0);
+ }
if (tree) {
ft = proto_tree_add_uint(tap_tree, hf_radiotap_flags, tvb, offset, 2, vw_rflags);
flags_tree = proto_item_add_subtree(ft, ett_radiotap_flags);
@@ -711,12 +723,16 @@ wlantap_dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree
offset +=2;
phyRate = (float)tvb_get_letohs(tvb, offset) / 10;
offset +=2;
+ ness = tvb_get_guint8(tvb, offset);
offset++;
mcs_index = tvb_get_guint8(tvb, offset);
offset++;
offset++;
if ((vw_rflags & FLAGS_CHAN_HT) || (vw_rflags & FLAGS_CHAN_VHT) ) {
+ phdr.presence_flags |= (PHDR_802_11_HAS_MCS_INDEX|PHDR_802_11_HAS_NESS);
+ phdr.mcs_index = mcs_index;
+ phdr.ness = ness;
if (tree) {
proto_tree_add_item(tap_tree, hf_radiotap_mcsindex,
tvb, offset - 2, 1, ENC_BIG_ENDIAN);
@@ -729,6 +745,8 @@ wlantap_dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree
"%.1f (MCS %d)", phyRate, mcs_index);
}
} else {
+ phdr.presence_flags |= PHDR_802_11_HAS_DATA_RATE;
+ phdr.data_rate = tvb_get_letohs(tvb, offset-5) / 5;
if (tree) {
proto_tree_add_uint_format_value(tap_tree, hf_radiotap_datarate,
tvb, offset - 5, 2, tvb_get_letohs(tvb, offset-5),
@@ -738,7 +756,8 @@ wlantap_dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree
col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%.1f", phyRate);
dbm = (gint8) tvb_get_guint8(tvb, offset);
-
+ phdr.presence_flags |= PHDR_802_11_HAS_SIGNAL_DBM;
+ phdr.signal_dbm = dbm;
col_add_fstr(pinfo->cinfo, COL_RSSI, "%d dBm", dbm);
if (tree) {
proto_tree_add_int_format_value(tap_tree,
@@ -905,7 +924,7 @@ wlantap_dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree
next_tvb = tvb_new_subset_remaining(tvb, length);
/* dissect the 802.11 packet next */
- call_dissector(ieee80211_handle, next_tvb, pinfo, tree);
+ call_dissector_with_data(ieee80211_radio_handle, next_tvb, pinfo, tree, &phdr);
}
void proto_register_ixveriwave(void)
@@ -1350,8 +1369,8 @@ void proto_reg_handoff_ixveriwave(void)
{
/* handle for ethertype dissector */
ethernet_handle = find_dissector("eth_withoutfcs");
- /* handle for 802.11 dissector */
- ieee80211_handle = find_dissector("wlan_withoutfcs");
+ /* handle for 802.11+radio information dissector */
+ ieee80211_radio_handle = find_dissector("wlan_radio");
ixveriwave_handle = create_dissector_handle(dissect_ixveriwave, proto_ixveriwave);
dissector_add_uint("wtap_encap", WTAP_ENCAP_IXVERIWAVE, ixveriwave_handle);
diff --git a/epan/dissectors/packet-peekremote.c b/epan/dissectors/packet-peekremote.c
index 49e4050e09..864c382c13 100644
--- a/epan/dissectors/packet-peekremote.c
+++ b/epan/dissectors/packet-peekremote.c
@@ -54,6 +54,8 @@
#include "config.h"
+#include <wiretap/wtap.h>
+
#include <epan/packet.h>
#include <epan/expert.h>
@@ -312,8 +314,7 @@ static gint ett_peekremote_flags = -1;
static gint ett_peekremote_status = -1;
static gint ett_peekremote_extflags = -1;
-static dissector_handle_t wlan_withfcs;
-static dissector_handle_t wlan_withoutfcs;
+static dissector_handle_t wlan_radio_handle;
static int
@@ -380,6 +381,8 @@ dissect_peekremote_new(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
proto_item *ti_header_version, *ti_header_size;
guint8 header_version;
guint header_size;
+ struct ieee_802_11_phdr phdr;
+ guint16 frequency;
tvbuff_t *next_tvb;
if (tvb_memeql(tvb, 0, magic, 4) == -1) {
@@ -390,6 +393,12 @@ dissect_peekremote_new(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
return FALSE;
}
+ /* We don't have any 802.11 metadata yet. */
+ phdr.fcs_len = 4; /* has an FCS */
+ phdr.decrypted = FALSE;
+ phdr.datapad = FALSE;
+ phdr.presence_flags = 0;
+
col_set_str(pinfo->cinfo, COL_PROTOCOL, "PEEKREMOTE");
col_clear(pinfo->cinfo, COL_INFO);
@@ -412,23 +421,42 @@ dissect_peekremote_new(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
if (header_size > 9)
offset += (header_size - 9);
} else {
+ phdr.presence_flags |=
+ PHDR_802_11_HAS_MCS_INDEX|
+ PHDR_802_11_HAS_CHANNEL|
+ PHDR_802_11_HAS_SIGNAL_PERCENT|
+ PHDR_802_11_HAS_NOISE_PERCENT|
+ PHDR_802_11_HAS_SIGNAL_DBM|
+ PHDR_802_11_HAS_NOISE_DBM|
+ PHDR_802_11_HAS_TSF_TIMESTAMP;
proto_tree_add_item(peekremote_tree, &hfi_peekremote_type, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
+ phdr.mcs_index = tvb_get_ntohs(tvb, offset);
proto_tree_add_item(peekremote_tree, &hfi_peekremote_mcs_index, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
+ phdr.channel = tvb_get_ntohs(tvb, offset);
proto_tree_add_item(peekremote_tree, &hfi_peekremote_channel, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
+ frequency = tvb_get_ntohl(tvb, offset);
+ if (frequency != 0) {
+ phdr.presence_flags |= PHDR_802_11_HAS_FREQUENCY;
+ phdr.frequency = frequency;
+ }
proto_tree_add_item(peekremote_tree, &hfi_peekremote_frequency, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
proto_tree_add_item(peekremote_tree, &hfi_peekremote_band, tvb, offset, 4, ENC_BIG_ENDIAN);
offset +=4;
offset += dissect_peekremote_extflags(tvb, pinfo, peekremote_tree, offset);
+ phdr.signal_percent = tvb_get_guint8(tvb, offset);
proto_tree_add_item(peekremote_tree, &hfi_peekremote_signal_percent, tvb, offset, 1, ENC_NA);
offset += 1;
+ phdr.noise_percent = tvb_get_guint8(tvb, offset);
proto_tree_add_item(peekremote_tree, &hfi_peekremote_noise_percent, tvb, offset, 1, ENC_NA);
offset += 1;
+ phdr.signal_dbm = tvb_get_guint8(tvb, offset);
proto_tree_add_item(peekremote_tree, &hfi_peekremote_signal_dbm, tvb, offset, 1, ENC_NA);
offset += 1;
+ phdr.noise_dbm = tvb_get_guint8(tvb, offset);
proto_tree_add_item(peekremote_tree, &hfi_peekremote_noise_dbm, tvb, offset, 1, ENC_NA);
offset += 1;
proto_tree_add_item(peekremote_tree, &hfi_peekremote_signal_1_dbm, tvb, offset, 1, ENC_NA);
@@ -454,6 +482,7 @@ dissect_peekremote_new(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
offset += dissect_peekremote_flags(tvb, pinfo, peekremote_tree, offset);
offset += dissect_peekremote_status(tvb, pinfo, peekremote_tree, offset);
proto_tree_add_item(peekremote_tree, &hfi_peekremote_timestamp, tvb, offset, 8, ENC_BIG_ENDIAN);
+ phdr.tsf_timestamp = tvb_get_ntoh64(tvb, offset);
offset += 8;
}
break;
@@ -467,7 +496,7 @@ dissect_peekremote_new(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
proto_item_set_end(ti, tvb, offset);
next_tvb = tvb_new_subset_remaining(tvb, offset);
- call_dissector(wlan_withfcs, next_tvb, pinfo, tree);
+ call_dissector_with_data(wlan_radio_handle, next_tvb, pinfo, tree, &phdr);
return TRUE;
}
@@ -477,6 +506,7 @@ dissect_peekremote_legacy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, v
tvbuff_t *next_tvb;
proto_tree *peekremote_tree = NULL;
proto_item *ti = NULL;
+ struct ieee_802_11_phdr phdr;
guint8 signal_percent;
/*
@@ -511,11 +541,29 @@ dissect_peekremote_legacy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, v
proto_item_set_end(ti, tvb, 20);
next_tvb = tvb_new_subset_remaining(tvb, 20);
/* When signal = 100 % and coming from ARUBA ERM, it is TX packet and there is no FCS */
- if (GPOINTER_TO_INT(data) == IS_ARUBA && signal_percent == 100){
- return 20 + call_dissector(wlan_withoutfcs, next_tvb, pinfo, tree);
+ if (GPOINTER_TO_INT(data) == IS_ARUBA && signal_percent == 100) {
+ phdr.fcs_len = 0; /* TX packet, no FCS */
} else {
- return 20 + call_dissector(wlan_withfcs, next_tvb, pinfo, tree);
+ phdr.fcs_len = 4; /* We have an FCS */
}
+ phdr.decrypted = FALSE;
+ phdr.presence_flags =
+ PHDR_802_11_HAS_CHANNEL|
+ PHDR_802_11_HAS_DATA_RATE|
+ PHDR_802_11_HAS_SIGNAL_PERCENT|
+ PHDR_802_11_HAS_NOISE_PERCENT|
+ PHDR_802_11_HAS_SIGNAL_DBM|
+ PHDR_802_11_HAS_NOISE_DBM|
+ PHDR_802_11_HAS_TSF_TIMESTAMP;
+ phdr.channel = tvb_get_guint8(tvb, 17);
+ phdr.data_rate = tvb_get_guint8(tvb, 16);
+ phdr.signal_percent = tvb_get_guint8(tvb, 18);
+ phdr.noise_percent = tvb_get_guint8(tvb, 18);
+ phdr.signal_dbm = tvb_get_guint8(tvb, 0);
+ phdr.noise_dbm = tvb_get_guint8(tvb, 1);
+ phdr.tsf_timestamp = tvb_get_ntoh64(tvb, 8);
+
+ return 20 + call_dissector_with_data(wlan_radio_handle, next_tvb, pinfo, tree, &phdr);
}
void
@@ -598,8 +646,7 @@ proto_reg_handoff_peekremote(void)
{
dissector_handle_t peekremote_handle;
- wlan_withfcs = find_dissector("wlan_withfcs");
- wlan_withoutfcs = find_dissector("wlan_withoutfcs");
+ wlan_radio_handle = find_dissector("wlan_radio");
peekremote_handle = new_create_dissector_handle(dissect_peekremote_legacy, proto_peekremote);
dissector_add_uint("udp.port", 5000, peekremote_handle);
diff --git a/epan/dissectors/packet-ppi.c b/epan/dissectors/packet-ppi.c
index 5541bcd779..15c2dee156 100644
--- a/epan/dissectors/packet-ppi.c
+++ b/epan/dissectors/packet-ppi.c
@@ -115,11 +115,18 @@
#define PPI_FLAG_ALIGN 0x01
#define IS_PPI_FLAG_ALIGN(x) ((x) & PPI_FLAG_ALIGN)
-#define DOT11_FLAG_HAVE_FCS 0x0001
-
-#define DOT11N_FLAG_IS_AGGREGATE 0x0010
+#define DOT11_FLAG_HAVE_FCS 0x0001
+#define DOT11_FLAG_TSF_TIMER_MS 0x0002
+#define DOT11_FLAG_FCS_INVALID 0x0004
+#define DOT11_FLAG_PHY_ERROR 0x0008
+
+#define DOT11N_FLAG_GREENFIELD 0x0001
+#define DOT11N_FLAG_HT40 0x0002
+#define DOT11N_FLAG_SHORT_GI 0x0004
+#define DOT11N_FLAG_DUPLICATE_RX 0x0008
+#define DOT11N_FLAG_IS_AGGREGATE 0x0010
#define DOT11N_FLAG_MORE_AGGREGATES 0x0020
-#define DOT11N_FLAG_AGG_CRC_ERROR 0x0040
+#define DOT11N_FLAG_AGG_CRC_ERROR 0x0040
#define DOT11N_IS_AGGREGATE(flags) (flags & DOT11N_FLAG_IS_AGGREGATE)
#define DOT11N_MORE_AGGREGATES(flags) ( \
@@ -333,7 +340,7 @@ static expert_field ei_ppi_invalid_length = EI_INIT;
static dissector_handle_t ppi_handle;
static dissector_handle_t data_handle;
-static dissector_handle_t ieee80211_handle;
+static dissector_handle_t ieee80211_radio_handle;
static dissector_handle_t ieee80211_ht_handle;
static dissector_handle_t ppi_gps_handle, ppi_vector_handle, ppi_sensor_handle, ppi_antenna_handle;
static dissector_handle_t ppi_fnet_handle;
@@ -482,9 +489,12 @@ dissect_80211_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of
proto_tree *ftree;
proto_item *ti;
ptvcursor_t *csr;
- gint rate_kbps;
+ guint64 tsft_raw;
+ guint rate_raw;
+ guint rate_kbps;
guint32 common_flags;
guint16 common_frequency;
+ gint8 dbm_value;
gchar *chan_str;
ftree = proto_tree_add_subtree(tree, tvb, offset, data_len, ett_dot11_common, NULL, "802.11-Common");
@@ -504,6 +514,15 @@ dissect_80211_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of
csr = ptvcursor_new(ftree, tvb, offset);
+ tsft_raw = tvb_get_letoh64(tvb, offset);
+ if (tsft_raw != 0) {
+ phdr->presence_flags |= PHDR_802_11_HAS_TSF_TIMESTAMP;
+ if (common_flags & DOT11_FLAG_TSF_TIMER_MS)
+ phdr->tsf_timestamp = tsft_raw * 1000;
+ else
+ phdr->tsf_timestamp = tsft_raw;
+ }
+
ptvcursor_add_invalid_check(csr, hf_80211_common_tsft, 8, 0);
ptvcursor_add_with_subtree(csr, hf_80211_common_flags, 2, ENC_LITTLE_ENDIAN,
@@ -514,7 +533,12 @@ dissect_80211_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of
ptvcursor_add(csr, hf_80211_common_flags_phy_err, 2, ENC_LITTLE_ENDIAN);
ptvcursor_pop_subtree(csr);
- rate_kbps = tvb_get_letohs(tvb, ptvcursor_current_offset(csr)) * 500;
+ rate_raw = tvb_get_letohs(tvb, ptvcursor_current_offset(csr));
+ if (rate_raw != 0) {
+ phdr->presence_flags |= PHDR_802_11_HAS_DATA_RATE;
+ phdr->data_rate = rate_raw;
+ }
+ rate_kbps = rate_raw * 500;
ti = proto_tree_add_uint_format(ftree, hf_80211_common_rate, tvb,
ptvcursor_current_offset(csr), 2, rate_kbps, "Rate: %.1f Mbps",
rate_kbps / 1000.0);
@@ -524,6 +548,10 @@ dissect_80211_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of
ptvcursor_advance(csr, 2);
common_frequency = tvb_get_letohs(ptvcursor_tvbuff(csr), ptvcursor_current_offset(csr));
+ if (common_frequency != 0) {
+ phdr->presence_flags |= PHDR_802_11_HAS_FREQUENCY;
+ phdr->frequency = common_frequency;
+ }
chan_str = ieee80211_mhz_to_str(common_frequency);
proto_tree_add_uint_format_value(ptvcursor_tree(csr), hf_80211_common_chan_freq, ptvcursor_tvbuff(csr),
ptvcursor_current_offset(csr), 2, common_frequency, "%s", chan_str);
@@ -547,21 +575,43 @@ dissect_80211_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int of
ptvcursor_add(csr, hf_80211_common_fhss_hopset, 1, ENC_LITTLE_ENDIAN);
ptvcursor_add(csr, hf_80211_common_fhss_pattern, 1, ENC_LITTLE_ENDIAN);
- col_add_fstr(pinfo->cinfo, COL_RSSI, "%d dBm",
- (gint8) tvb_get_guint8(tvb, ptvcursor_current_offset(csr)));
-
+ dbm_value = (gint8) tvb_get_guint8(tvb, ptvcursor_current_offset(csr));
+ if (dbm_value != -128 && dbm_value != 0) {
+ /*
+ * XXX - the spec says -128 is invalid, presumably meaning "use
+ * -128 if you don't have the signal strength", but some captures
+ * have 0 for noise, presumably meaning it's incorrectly being
+ * used for "don't have it", so we check for it as well.
+ */
+ col_add_fstr(pinfo->cinfo, COL_RSSI, "%d dBm", dbm_value);
+ phdr->presence_flags |= PHDR_802_11_HAS_SIGNAL_DBM;
+ phdr->signal_dbm = dbm_value;
+ }
ptvcursor_add_invalid_check(csr, hf_80211_common_dbm_antsignal, 1, 0x80); /* -128 */
+
+ dbm_value = (gint8) tvb_get_guint8(tvb, ptvcursor_current_offset(csr));
+ if (dbm_value != -128 && dbm_value != 0) {
+ /*
+ * XXX - the spec says -128 is invalid, presumably meaning "use
+ * -128 if you don't have the noise level", but some captures
+ * have 0, presumably meaning it's incorrectly being used for
+ * "don't have it", so we check for it as well.
+ */
+ phdr->presence_flags |= PHDR_802_11_HAS_NOISE_DBM;
+ phdr->noise_dbm = dbm_value;
+ }
ptvcursor_add_invalid_check(csr, hf_80211_common_dbm_antnoise, 1, 0x80);
ptvcursor_free(csr);
}
static void
-dissect_80211n_mac(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, int data_len, gboolean add_subtree, guint32 *n_mac_flags, guint32 *ampdu_id)
+dissect_80211n_mac(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, int data_len, gboolean add_subtree, guint32 *n_mac_flags, guint32 *ampdu_id, struct ieee_802_11_phdr *phdr)
{
proto_tree *ftree = tree;
ptvcursor_t *csr;
int subtree_off = add_subtree ? 4 : 0;
+ guint32 flags;
*n_mac_flags = tvb_get_letohl(tvb, offset + subtree_off);
*ampdu_id = tvb_get_letohl(tvb, offset + 4 + subtree_off);
@@ -579,6 +629,10 @@ dissect_80211n_mac(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int
csr = ptvcursor_new(ftree, tvb, offset);
+ flags = tvb_get_letohl(tvb, ptvcursor_current_offset(csr));
+ phdr->presence_flags |= PHDR_802_11_HAS_SHORT_GI|PHDR_802_11_HAS_GREENFIELD;
+ phdr->short_gi = ((flags & DOT11N_FLAG_SHORT_GI) != 0);
+ phdr->greenfield = ((flags & DOT11N_FLAG_GREENFIELD) != 0);
ptvcursor_add_with_subtree(csr, hf_80211n_mac_flags, 4, ENC_LITTLE_ENDIAN,
ett_dot11n_mac_flags);
ptvcursor_add_no_advance(csr, hf_80211n_mac_flags_greenfield, 4, ENC_LITTLE_ENDIAN);
@@ -601,11 +655,13 @@ dissect_80211n_mac(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int
}
static void
-dissect_80211n_mac_phy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int data_len, guint32 *n_mac_flags, guint32 *ampdu_id)
+dissect_80211n_mac_phy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int data_len, guint32 *n_mac_flags, guint32 *ampdu_id, struct ieee_802_11_phdr *phdr)
{
proto_tree *ftree;
proto_item *ti;
ptvcursor_t *csr;
+ guint8 mcs;
+ guint8 ness;
guint16 ext_frequency;
gchar *chan_str;
@@ -619,12 +675,21 @@ dissect_80211n_mac_phy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int
}
dissect_80211n_mac(tvb, pinfo, ftree, offset, PPI_80211N_MAC_LEN,
- FALSE, n_mac_flags, ampdu_id);
+ FALSE, n_mac_flags, ampdu_id, phdr);
offset += PPI_80211N_MAC_PHY_OFF;
csr = ptvcursor_new(ftree, tvb, offset);
+ mcs = tvb_get_guint8(tvb, ptvcursor_current_offset(csr));
+ if (mcs != 255) {
+ phdr->presence_flags |= PHDR_802_11_HAS_MCS_INDEX;
+ phdr->mcs_index = mcs;
+ }
ptvcursor_add_invalid_check(csr, hf_80211n_mac_phy_mcs, 1, 255);
+
+ ness = tvb_get_guint8(tvb, ptvcursor_current_offset(csr));
+ phdr->presence_flags |= PHDR_802_11_HAS_NESS;
+ phdr->ness = ness;
ti = ptvcursor_add(csr, hf_80211n_mac_phy_num_streams, 1, ENC_LITTLE_ENDIAN);
if (tvb_get_guint8(tvb, ptvcursor_current_offset(csr) - 1) == 0)
proto_item_append_text(ti, " (unknown)");
@@ -795,6 +860,7 @@ dissect_ppi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* We don't have any 802.11 metadata yet. */
phdr.fcs_len = -1;
phdr.decrypted = FALSE;
+ phdr.datapad = FALSE;
phdr.presence_flags = 0;
while (tot_len > 0) {
@@ -810,13 +876,13 @@ dissect_ppi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
case PPI_80211N_MAC:
dissect_80211n_mac(tvb, pinfo, ppi_tree, offset, data_len,
- TRUE, &n_ext_flags, &ampdu_id);
+ TRUE, &n_ext_flags, &ampdu_id, &phdr);
is_ht = TRUE;
break;
case PPI_80211N_MAC_PHY:
dissect_80211n_mac_phy(tvb, pinfo, ppi_tree, offset,
- data_len, &n_ext_flags, &ampdu_id);
+ data_len, &n_ext_flags, &ampdu_id, &phdr);
is_ht = TRUE;
break;
@@ -1028,7 +1094,7 @@ dissect_ppi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
if (is_ht) { /* We didn't hit the reassembly code */
call_dissector_with_data(ieee80211_ht_handle, next_tvb, pinfo, tree, &phdr);
} else {
- call_dissector_with_data(ieee80211_handle, next_tvb, pinfo, tree, &phdr);
+ call_dissector_with_data(ieee80211_radio_handle, next_tvb, pinfo, tree, &phdr);
}
} else {
/* Everything else. This will pass a NULL data argument. */
@@ -1089,16 +1155,16 @@ proto_register_ppi(void)
FT_UINT16, BASE_HEX, NULL, 0x0, "PPI 802.11-Common Flags", HFILL } },
{ &hf_80211_common_flags_fcs,
{ "FCS present flag", "ppi.80211-common.flags.fcs",
- FT_BOOLEAN, 16, TFS(&tfs_present_absent), 0x0001, "PPI 802.11-Common Frame Check Sequence (FCS) Present Flag", HFILL } },
+ FT_BOOLEAN, 16, TFS(&tfs_present_absent), DOT11_FLAG_HAVE_FCS, "PPI 802.11-Common Frame Check Sequence (FCS) Present Flag", HFILL } },
{ &hf_80211_common_flags_tsft,
{ "TSFT flag", "ppi.80211-common.flags.tsft",
- FT_BOOLEAN, 16, TFS(&tfs_tsft_ms), 0x0002, "PPI 802.11-Common Timing Synchronization Function Timer (TSFT) msec/usec flag", HFILL } },
+ FT_BOOLEAN, 16, TFS(&tfs_tsft_ms), DOT11_FLAG_TSF_TIMER_MS, "PPI 802.11-Common Timing Synchronization Function Timer (TSFT) msec/usec flag", HFILL } },
{ &hf_80211_common_flags_fcs_valid,
{ "FCS validity", "ppi.80211-common.flags.fcs-invalid",
- FT_BOOLEAN, 16, TFS(&tfs_invalid_valid), 0x0004, "PPI 802.11-Common Frame Check Sequence (FCS) Validity flag", HFILL } },
+ FT_BOOLEAN, 16, TFS(&tfs_invalid_valid), DOT11_FLAG_FCS_INVALID, "PPI 802.11-Common Frame Check Sequence (FCS) Validity flag", HFILL } },
{ &hf_80211_common_flags_phy_err,
{ "PHY error flag", "ppi.80211-common.flags.phy-err",
- FT_BOOLEAN, 16, TFS(&tfs_phy_error), 0x0008, "PPI 802.11-Common Physical level (PHY) Error", HFILL } },
+ FT_BOOLEAN, 16, TFS(&tfs_phy_error), DOT11_FLAG_PHY_ERROR, "PPI 802.11-Common Physical level (PHY) Error", HFILL } },
{ &hf_80211_common_rate,
{ "Data rate", "ppi.80211-common.rate",
FT_UINT16, BASE_DEC, NULL, 0x0, "PPI 802.11-Common Data Rate (x 500 Kbps)", HFILL } },
@@ -1154,25 +1220,25 @@ proto_register_ppi(void)
FT_UINT32, BASE_HEX, NULL, 0x0, "PPI 802.11n MAC flags", HFILL } },
{ &hf_80211n_mac_flags_greenfield,
{ "Greenfield flag", "ppi.80211n-mac.flags.greenfield",
- FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x0001, "PPI 802.11n MAC Greenfield Flag", HFILL } },
+ FT_BOOLEAN, 32, TFS(&tfs_true_false), DOT11N_FLAG_GREENFIELD, "PPI 802.11n MAC Greenfield Flag", HFILL } },
{ &hf_80211n_mac_flags_ht20_40,
{ "HT20/HT40 flag", "ppi.80211n-mac.flags.ht20_40",
- FT_BOOLEAN, 32, TFS(&tfs_ht20_40), 0x0002, "PPI 802.11n MAC HT20/HT40 Flag", HFILL } },
+ FT_BOOLEAN, 32, TFS(&tfs_ht20_40), DOT11N_FLAG_HT40, "PPI 802.11n MAC HT20/HT40 Flag", HFILL } },
{ &hf_80211n_mac_flags_rx_guard_interval,
{ "RX Short Guard Interval (SGI) flag", "ppi.80211n-mac.flags.rx.short_guard_interval",
- FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x0004, "PPI 802.11n MAC RX Short Guard Interval (SGI) Flag", HFILL } },
+ FT_BOOLEAN, 32, TFS(&tfs_true_false), DOT11N_FLAG_SHORT_GI, "PPI 802.11n MAC RX Short Guard Interval (SGI) Flag", HFILL } },
{ &hf_80211n_mac_flags_duplicate_rx,
{ "Duplicate RX flag", "ppi.80211n-mac.flags.rx.duplicate",
- FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x0008, "PPI 802.11n MAC Duplicate RX Flag", HFILL } },
+ FT_BOOLEAN, 32, TFS(&tfs_true_false), DOT11N_FLAG_DUPLICATE_RX, "PPI 802.11n MAC Duplicate RX Flag", HFILL } },
{ &hf_80211n_mac_flags_aggregate,
{ "Aggregate flag", "ppi.80211n-mac.flags.agg",
- FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x0010, "PPI 802.11 MAC Aggregate Flag", HFILL } },
+ FT_BOOLEAN, 32, TFS(&tfs_true_false), DOT11N_FLAG_IS_AGGREGATE, "PPI 802.11 MAC Aggregate Flag", HFILL } },
{ &hf_80211n_mac_flags_more_aggregates,
{ "More aggregates flag", "ppi.80211n-mac.flags.more_agg",
- FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x0020, "PPI 802.11n MAC More Aggregates Flag", HFILL } },
+ FT_BOOLEAN, 32, TFS(&tfs_true_false), DOT11N_FLAG_MORE_AGGREGATES, "PPI 802.11n MAC More Aggregates Flag", HFILL } },
{ &hf_80211n_mac_flags_delimiter_crc_after,
{ "A-MPDU Delimiter CRC error after this frame flag", "ppi.80211n-mac.flags.delim_crc_error_after",
- FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x0040, "PPI 802.11n MAC A-MPDU Delimiter CRC Error After This Frame Flag", HFILL } },
+ FT_BOOLEAN, 32, TFS(&tfs_true_false), DOT11N_FLAG_AGG_CRC_ERROR, "PPI 802.11n MAC A-MPDU Delimiter CRC Error After This Frame Flag", HFILL } },
{ &hf_80211n_mac_ampdu_id,
{ "AMPDU-ID", "ppi.80211n-mac.ampdu_id",
FT_UINT32, BASE_HEX, NULL, 0x0, "PPI 802.11n MAC AMPDU-ID", HFILL } },
@@ -1401,7 +1467,7 @@ void
proto_reg_handoff_ppi(void)
{
data_handle = find_dissector("data");
- ieee80211_handle = find_dissector("wlan");
+ ieee80211_radio_handle = find_dissector("wlan_radio");
ieee80211_ht_handle = find_dissector("wlan_ht");
ppi_gps_handle = find_dissector("ppi_gps");
ppi_vector_handle = find_dissector("ppi_vector");