diff options
author | Guy Harris <guy@alum.mit.edu> | 2016-06-26 13:44:17 -0700 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2016-06-26 20:45:22 +0000 |
commit | 497159f37245164dba6cb2b80b29f866c051cf25 (patch) | |
tree | 1bd93e7b87327658bba2fff6b1813ecaf0a537d7 | |
parent | b84637b4f6a1f3f910b97c21264ff6132a9c19c4 (diff) |
Check for an invalid 11ac MCS/bandwidth/NSS combination.
A few of the combinations are marked as "Not valid" in 802.11ac-2013.
Ping-Bug: 12558
Change-Id: I18b78ebb84ab32a6fc53c6d634ef07ae87fb4866
Reviewed-on: https://code.wireshark.org/review/16153
Reviewed-by: Guy Harris <guy@alum.mit.edu>
-rw-r--r-- | epan/dissectors/packet-ieee80211-radio.c | 93 | ||||
-rw-r--r-- | epan/dissectors/packet-ieee80211-radiotap.c | 94 |
2 files changed, 184 insertions, 3 deletions
diff --git a/epan/dissectors/packet-ieee80211-radio.c b/epan/dissectors/packet-ieee80211-radio.c index 1be0422d2a..35e1094217 100644 --- a/epan/dissectors/packet-ieee80211-radio.c +++ b/epan/dissectors/packet-ieee80211-radio.c @@ -266,6 +266,95 @@ static const struct mcs_vht_info ieee80211_vhtinfo[MAX_MCS_VHT_INDEX+1] = { /* map a bandwidth index to the number of data subcarriers */ static const guint subcarriers[4] = { 52, 108, 234, 468 }; +#define MAX_VHT_NSS 8 + +struct mcs_vht_valid { + gboolean valid[4][MAX_VHT_NSS]; /* indexed by bandwidth and NSS-1 */ +}; + +static const struct mcs_vht_valid ieee80211_vhtvalid[MAX_MCS_VHT_INDEX+1] = { + /* MCS 0 */ + { + { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + } + }, + /* MCS 1 */ + { + { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + } + }, + /* MCS 2 */ + { + { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + } + }, + /* MCS 3 */ + { + { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + } + }, + /* MCS 4 */ + { + { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + } + }, + /* MCS 5 */ + { + { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + } + }, + /* MCS 6 */ + { + { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 80 Mhz */ { TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE }, + /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + } + }, + /* MCS 7 */ + { + { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + } + }, + /* MCS 8 */ + { + { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + } + }, + /* MCS 9 */ + { + { /* 20 Mhz */ { FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE }, + /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE }, + /* 160 Mhz */ { TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE }, + } + } +}; + /* * Calculates data rate corresponding to a given 802.11ac MCS index, * bandwidth, and guard interval. @@ -543,7 +632,9 @@ dissect_wlan_radio_phdr (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, /* * If we can calculate the data rate for this user, do so. */ - if (can_calculate_rate && info_ac->mcs[i] <= MAX_MCS_VHT_INDEX) { + if (can_calculate_rate && info_ac->mcs[i] <= MAX_MCS_VHT_INDEX && + info_ac->nss[i] <= MAX_VHT_NSS && + ieee80211_vhtvalid[info_ac->mcs[i]-1].valid[bandwidth][info_ac->nss[i]]) { data_rate = ieee80211_vhtrate(info_ac->mcs[i], bandwidth, info_ac->short_gi) * info_ac->nss[i]; if (data_rate != 0.0f) { proto_tree_add_float_format_value(user_tree, hf_wlan_radio_data_rate, tvb, 0, 0, diff --git a/epan/dissectors/packet-ieee80211-radiotap.c b/epan/dissectors/packet-ieee80211-radiotap.c index 3d4d6d560b..073bd28130 100644 --- a/epan/dissectors/packet-ieee80211-radiotap.c +++ b/epan/dissectors/packet-ieee80211-radiotap.c @@ -282,6 +282,7 @@ struct _radiotap_info { (IEEE80211_CHAN_108A | IEEE80211_CHAN_STURBO) #define MAX_MCS_VHT_INDEX 9 +#define MAX_VHT_NSS 8 /* * Maps a VHT bandwidth index to ieee80211_vhtinfo.rates index. @@ -293,10 +294,97 @@ static const int ieee80211_vht_bw2rate_index[] = { /* 160Mhz total */ 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; +struct mcs_vht_valid { + gboolean valid[4][MAX_VHT_NSS]; /* indexed by bandwidth and NSS-1 */ +}; + +static const struct mcs_vht_valid ieee80211_vhtvalid[MAX_MCS_VHT_INDEX+1] = { + /* MCS 0 */ + { + { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + } + }, + /* MCS 1 */ + { + { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + } + }, + /* MCS 2 */ + { + { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + } + }, + /* MCS 3 */ + { + { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + } + }, + /* MCS 4 */ + { + { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + } + }, + /* MCS 5 */ + { + { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + } + }, + /* MCS 6 */ + { + { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 80 Mhz */ { TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE }, + /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + } + }, + /* MCS 7 */ + { + { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + } + }, + /* MCS 8 */ + { + { /* 20 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 160 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + } + }, + /* MCS 9 */ + { + { /* 20 Mhz */ { FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE }, + /* 40 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, + /* 80 Mhz */ { TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE }, + /* 160 Mhz */ { TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE }, + } + } +}; + struct mcs_vht_info { const char *modulation; const char *coding_rate; - float rates[4][2]; + float rates[4][2]; /* indexed by bandwidth and GI length */ }; static const struct mcs_vht_info ieee80211_vhtinfo[MAX_MCS_VHT_INDEX+1] = { @@ -1713,7 +1801,9 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void* u tvb, offset + 8, 1,ENC_LITTLE_ENDIAN); } - if (can_calculate_rate && mcs <= MAX_MCS_VHT_INDEX) { + if (can_calculate_rate && mcs <= MAX_MCS_VHT_INDEX && + nss <= MAX_VHT_NSS && + ieee80211_vhtvalid[mcs].valid[bandwidth][nss]) { float rate = ieee80211_vhtinfo[mcs].rates[bandwidth][gi_length] * nss; if (rate != 0.0f && user_tree) { rate_ti = proto_tree_add_float_format(user_tree, |