aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-ieee80211-radiotap.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors/packet-ieee80211-radiotap.c')
-rw-r--r--epan/dissectors/packet-ieee80211-radiotap.c97
1 files changed, 76 insertions, 21 deletions
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");