aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2016-06-26 13:44:17 -0700
committerGuy Harris <guy@alum.mit.edu>2016-06-26 20:45:22 +0000
commit497159f37245164dba6cb2b80b29f866c051cf25 (patch)
tree1bd93e7b87327658bba2fff6b1813ecaf0a537d7 /epan
parentb84637b4f6a1f3f910b97c21264ff6132a9c19c4 (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>
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-ieee80211-radio.c93
-rw-r--r--epan/dissectors/packet-ieee80211-radiotap.c94
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,