aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-ieee80211-radiotap.c
diff options
context:
space:
mode:
authorAlexis La Goutte <alexis.lagoutte@gmail.com>2012-09-18 20:46:05 +0000
committerAlexis La Goutte <alexis.lagoutte@gmail.com>2012-09-18 20:46:05 +0000
commitb6e0cc28a56a0547c13d4547328bf827d8a66895 (patch)
treea6ba0515090be8f9bcfb45af1ea199f69ab48ddd /epan/dissectors/packet-ieee80211-radiotap.c
parent90e68a72b9cca80f064710fe9f68c6ac59c85faf (diff)
From Daniel via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=7716
Adding VHT Radiotap fields support Parsing and UI representation for recently adopted VHT Radiotap fields for 802.11ac specification http://www.radiotap.org/defined-fields/VHT From me : * Make checkAPIs happy * Fix wrong last argument for some proto_tree_add_item * Use proto_tree_add_item when it is possible svn path=/trunk/; revision=44985
Diffstat (limited to 'epan/dissectors/packet-ieee80211-radiotap.c')
-rw-r--r--epan/dissectors/packet-ieee80211-radiotap.c503
1 files changed, 501 insertions, 2 deletions
diff --git a/epan/dissectors/packet-ieee80211-radiotap.c b/epan/dissectors/packet-ieee80211-radiotap.c
index ee61bbae9d..fdc7b604ad 100644
--- a/epan/dissectors/packet-ieee80211-radiotap.c
+++ b/epan/dissectors/packet-ieee80211-radiotap.c
@@ -130,6 +130,32 @@ static int hf_radiotap_ampdu_flags_last_known = -1;
static int hf_radiotap_ampdu_flags_is_last = -1;
static int hf_radiotap_ampdu_flags_delim_crc_error = -1;
static int hf_radiotap_ampdu_delim_crc = -1;
+static int hf_radiotap_vht = -1;
+static int hf_radiotap_vht_known = -1;
+static int hf_radiotap_vht_have_stbc = -1;
+static int hf_radiotap_vht_have_txop_ps = -1;
+static int hf_radiotap_vht_have_gi = -1;
+static int hf_radiotap_vht_have_sgi_nsym_da = -1;
+static int hf_radiotap_vht_have_ldpc_extra = -1;
+static int hf_radiotap_vht_have_bf = -1;
+static int hf_radiotap_vht_have_bw = -1;
+static int hf_radiotap_vht_have_gid = -1;
+static int hf_radiotap_vht_have_p_aid = -1;
+static int hf_radiotap_vht_stbc = -1;
+static int hf_radiotap_vht_txop_ps = -1;
+static int hf_radiotap_vht_gi = -1;
+static int hf_radiotap_vht_sgi_nsym_da = -1;
+static int hf_radiotap_vht_ldpc_extra = -1;
+static int hf_radiotap_vht_bf = -1;
+static int hf_radiotap_vht_bw = -1;
+static int hf_radiotap_vht_nsts[4] = { -1, -1, -1, -1 };
+static int hf_radiotap_vht_mcs[4] = { -1, -1, -1, -1 };
+static int hf_radiotap_vht_nss[4] = { -1, -1, -1, -1 };
+static int hf_radiotap_vht_coding[4] = { -1, -1, -1, -1 };
+static int hf_radiotap_vht_datarate[4] = { -1, -1, -1, -1 };
+static int hf_radiotap_vht_gid = -1;
+static int hf_radiotap_vht_p_aid = -1;
+static int hf_radiotap_vht_user = -1;
/* "Present" flags */
static int hf_radiotap_present_tsft = -1;
@@ -151,6 +177,7 @@ static int hf_radiotap_present_rxflags = -1;
static int hf_radiotap_present_xchannel = -1;
static int hf_radiotap_present_mcs = -1;
static int hf_radiotap_present_ampdu = -1;
+static int hf_radiotap_present_vht = -1;
static int hf_radiotap_present_reserved = -1;
static int hf_radiotap_present_rtap_ns = -1;
static int hf_radiotap_present_vendor_ns = -1;
@@ -182,6 +209,9 @@ static gint ett_radiotap_mcs = -1;
static gint ett_radiotap_mcs_known = -1;
static gint ett_radiotap_ampdu = -1;
static gint ett_radiotap_ampdu_flags = -1;
+static gint ett_radiotap_vht = -1;
+static gint ett_radiotap_vht_known = -1;
+static gint ett_radiotap_vht_user = -1;
static dissector_handle_t ieee80211_handle;
static dissector_handle_t ieee80211_datapad_handle;
@@ -237,6 +267,137 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree);
#define IEEE80211_CHAN_108PUREG \
(IEEE80211_CHAN_PUREG | IEEE80211_CHAN_TURBO)
+#define MAX_MCS_VHT_INDEX 9
+
+/*
+ * Maps a VHT bandwidth index to ieee80211_vhtinfo.rates index.
+ */
+static const int ieee80211_vht_bw2rate_index[] = {
+ /* 20Mhz total */ 0,
+ /* 40Mhz total */ 1, 0, 0,
+ /* 80Mhz total */ 2, 1, 1, 0, 0, 0, 0,
+ /* 160Mhz total */ 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+struct mcs_vht_info {
+ char *modulation;
+ char *coding_rate;
+ float rates[4][2];
+};
+
+static const struct mcs_vht_info ieee80211_vhtinfo[MAX_MCS_VHT_INDEX+1] = {
+ /* MCS 0 */
+ { "BPSK", "1/2",
+ { /* 20 Mhz */ { 6.5f, /* SGI */ 7.2f, },
+ /* 40 Mhz */ { 13.5f, /* SGI */ 15.0f, },
+ /* 80 Mhz */ { 29.3f, /* SGI */ 32.5f, },
+ /* 160 Mhz */ { 58.5f, /* SGI */ 65.0f, }
+ }
+ },
+ /* MCS 1 */
+ { "QPSK", "1/2",
+ { /* 20 Mhz */ { 13.0f, /* SGI */ 14.4f, },
+ /* 40 Mhz */ { 27.0f, /* SGI */ 30.0f, },
+ /* 80 Mhz */ { 58.5f, /* SGI */ 65.0f, },
+ /* 160 Mhz */ { 117.0f, /* SGI */ 130.0f, }
+ }
+ },
+ /* MCS 2 */
+ { "QPSK", "3/4",
+ { /* 20 Mhz */ { 19.5f, /* SGI */ 21.7f, },
+ /* 40 Mhz */ { 40.5f, /* SGI */ 45.0f, },
+ /* 80 Mhz */ { 87.8f, /* SGI */ 97.5f, },
+ /* 160 Mhz */ { 175.5f, /* SGI */ 195.0f, }
+ }
+ },
+ /* MCS 3 */
+ { "16-QAM", "1/2",
+ { /* 20 Mhz */ { 26.0f, /* SGI */ 28.9f, },
+ /* 40 Mhz */ { 54.0f, /* SGI */ 60.0f, },
+ /* 80 Mhz */ { 117.0f, /* SGI */ 130.0f, },
+ /* 160 Mhz */ { 234.0f, /* SGI */ 260.0f, }
+ }
+ },
+ /* MCS 4 */
+ { "16-QAM", "3/4",
+ { /* 20 Mhz */ { 39.0f, /* SGI */ 43.3f, },
+ /* 40 Mhz */ { 81.0f, /* SGI */ 90.0f, },
+ /* 80 Mhz */ { 175.5f, /* SGI */ 195.0f, },
+ /* 160 Mhz */ { 351.0f, /* SGI */ 390.0f, }
+ }
+ },
+ /* MCS 5 */
+ { "64-QAM", "2/3",
+ { /* 20 Mhz */ { 52.0f, /* SGI */ 57.8f, },
+ /* 40 Mhz */ { 108.0f, /* SGI */ 120.0f, },
+ /* 80 Mhz */ { 234.0f, /* SGI */ 260.0f, },
+ /* 160 Mhz */ { 468.0f, /* SGI */ 520.0f, }
+ }
+ },
+ /* MCS 6 */
+ { "64-QAM", "3/4",
+ { /* 20 Mhz */ { 58.5f, /* SGI */ 65.0f, },
+ /* 40 Mhz */ { 121.5f, /* SGI */ 135.0f, },
+ /* 80 Mhz */ { 263.3f, /* SGI */ 292.5f, },
+ /* 160 Mhz */ { 526.5f, /* SGI */ 585.0f, }
+ }
+ },
+ /* MCS 7 */
+ { "64-QAM", "5/6",
+ { /* 20 Mhz */ { 65.0f, /* SGI */ 72.2f, },
+ /* 40 Mhz */ { 135.0f, /* SGI */ 150.0f, },
+ /* 80 Mhz */ { 292.5f, /* SGI */ 325.0f, },
+ /* 160 Mhz */ { 585.0f, /* SGI */ 650.0f, }
+ }
+ },
+ /* MCS 8 */
+ { "256-QAM", "3/4",
+ { /* 20 Mhz */ { 78.0f, /* SGI */ 86.7f, },
+ /* 40 Mhz */ { 162.0f, /* SGI */ 180.0f, },
+ /* 80 Mhz */ { 351.0f, /* SGI */ 390.0f, },
+ /* 160 Mhz */ { 702.0f, /* SGI */ 780.0f, }
+ }
+ },
+ /* MCS 9 */
+ { "256-QAM", "5/6",
+ { /* 20 Mhz */ { 0.0f, /* SGI */ 0.0f, },
+ /* 40 Mhz */ { 180.0f, /* SGI */ 200.0f, },
+ /* 80 Mhz */ { 390.0f, /* SGI */ 433.3f, },
+ /* 160 Mhz */ { 780.0f, /* SGI */ 866.7f, }
+ }
+ }
+};
+
+static const value_string vht_bandwidth[] = {
+ { IEEE80211_RADIOTAP_VHT_BW_20, "20 MHz" },
+ { IEEE80211_RADIOTAP_VHT_BW_20L, "20 MHz lower" },
+ { IEEE80211_RADIOTAP_VHT_BW_20U, "20 MHz upper" },
+ { IEEE80211_RADIOTAP_VHT_BW_40, "40 MHz" },
+ { IEEE80211_RADIOTAP_VHT_BW_20LL, "20 MHz, channel 1/4" },
+ { IEEE80211_RADIOTAP_VHT_BW_20LU, "20 MHz, channel 2/4" },
+ { IEEE80211_RADIOTAP_VHT_BW_20UL, "20 MHz, channel 3/4" },
+ { IEEE80211_RADIOTAP_VHT_BW_20UU, "20 MHz, channel 4/4" },
+ { IEEE80211_RADIOTAP_VHT_BW_40L, "40 MHz lower" },
+ { IEEE80211_RADIOTAP_VHT_BW_40U, "40 MHz upper" },
+ { IEEE80211_RADIOTAP_VHT_BW_80, "80 MHz" },
+ { IEEE80211_RADIOTAP_VHT_BW_20LLL, "20 MHz, channel 1/8" },
+ { IEEE80211_RADIOTAP_VHT_BW_20LLU, "20 MHz, channel 2/8" },
+ { IEEE80211_RADIOTAP_VHT_BW_20LUL, "20 MHz, channel 3/8" },
+ { IEEE80211_RADIOTAP_VHT_BW_20LUU, "20 MHz, channel 4/8" },
+ { IEEE80211_RADIOTAP_VHT_BW_20ULL, "20 MHz, channel 5/8" },
+ { IEEE80211_RADIOTAP_VHT_BW_20ULU, "20 MHz, channel 6/8" },
+ { IEEE80211_RADIOTAP_VHT_BW_20UUL, "20 MHz, channel 7/8" },
+ { IEEE80211_RADIOTAP_VHT_BW_20UUU, "20 MHz, channel 8/8" },
+ { IEEE80211_RADIOTAP_VHT_BW_40LL, "40 MHz, channel 1/4" },
+ { IEEE80211_RADIOTAP_VHT_BW_40LU, "40 MHz, channel 2/4" },
+ { IEEE80211_RADIOTAP_VHT_BW_40UL, "40 MHz, channel 3/4" },
+ { IEEE80211_RADIOTAP_VHT_BW_40UU, "40 MHz, channel 4/4" },
+ { IEEE80211_RADIOTAP_VHT_BW_80L, "80 MHz lower" },
+ { IEEE80211_RADIOTAP_VHT_BW_80U, "80 MHz upper" },
+ { IEEE80211_RADIOTAP_VHT_BW_160, "160 MHz" },
+ { 0, NULL }
+};
+
#define MAX_MCS_INDEX 76
/*
@@ -815,7 +976,7 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
int hdr_fcs_offset = 0;
guint32 sent_fcs = 0;
guint32 calc_fcs;
- gint err;
+ gint err = -ENOENT;
struct ieee80211_radiotap_iterator iter;
void *data;
struct _radiotap_info *radiotap_info;
@@ -981,6 +1142,9 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
proto_tree_add_item(present_tree,
hf_radiotap_present_ampdu, tvb,
offset + 4, 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(present_tree,
+ hf_radiotap_present_vht, tvb,
+ offset + 4, 4, ENC_LITTLE_ENDIAN);
ti = proto_tree_add_item(present_tree,
hf_radiotap_present_reserved, tvb,
offset + 4, 4, ENC_LITTLE_ENDIAN);
@@ -1532,7 +1696,6 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
proto_item *it;
proto_tree *ampdu_tree = NULL, *ampdu_flags_tree;
guint16 flags;
-
flags = tvb_get_letohs(tvb, offset + 4);
if (tree) {
@@ -1564,6 +1727,171 @@ dissect_radiotap(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
}
break;
}
+ case IEEE80211_RADIOTAP_VHT: {
+ proto_item *it, *it_root = NULL;
+ proto_tree *vht_tree = NULL, *vht_known_tree = NULL, *user_tree = NULL;
+ guint16 known, nsts;
+ guint8 flags, bw, mcs_nss;
+ guint bandwidth = 0;
+ guint gi_length = 0;
+ guint nss = 0;
+ guint mcs = 0;
+ gboolean can_calculate_rate;
+ guint i;
+
+ /*
+ * Start out assuming that we can calculate the rate;
+ * if we are missing any of the MCS index, channel
+ * width, or guard interval length, we can't.
+ */
+ can_calculate_rate = TRUE;
+
+ known = tvb_get_letohs(tvb, offset);
+ flags = tvb_get_guint8(tvb, offset + 2);
+ bw = tvb_get_guint8(tvb, offset + 3);
+
+ if (tree) {
+ it_root = proto_tree_add_item(radiotap_tree, hf_radiotap_vht,
+ tvb, offset, 12, ENC_NA);
+ vht_tree = proto_item_add_subtree(it_root, ett_radiotap_vht);
+ it = proto_tree_add_item(vht_tree, hf_radiotap_vht_known,
+ tvb, offset, 2, known);
+ vht_known_tree = proto_item_add_subtree(it, ett_radiotap_vht_known);
+
+ proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_stbc,
+ tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_txop_ps,
+ tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_gi,
+ tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_sgi_nsym_da,
+ tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_ldpc_extra,
+ tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_bf,
+ tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_bw,
+ tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_gid,
+ tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(vht_known_tree, hf_radiotap_vht_have_p_aid,
+ tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ }
+
+ if (known & IEEE80211_RADIOTAP_VHT_HAVE_STBC) {
+ if (vht_tree)
+ proto_tree_add_item(vht_tree, hf_radiotap_vht_stbc,
+ tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
+ }
+
+ if (known & IEEE80211_RADIOTAP_VHT_HAVE_TXOP_PS) {
+ if (vht_tree)
+ proto_tree_add_item(vht_tree, hf_radiotap_vht_txop_ps,
+ tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
+ }
+
+ if (known & IEEE80211_RADIOTAP_VHT_HAVE_GI) {
+ gi_length = (flags & IEEE80211_RADIOTAP_VHT_SGI) ? 1 : 0;
+ if (vht_tree) {
+ proto_tree_add_item(vht_tree, hf_radiotap_vht_gi,
+ tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(vht_tree, hf_radiotap_vht_sgi_nsym_da,
+ tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
+ }
+ } else {
+ can_calculate_rate = FALSE; /* no GI width */
+ }
+
+ if (known & IEEE80211_RADIOTAP_VHT_HAVE_LDPC_EXTRA) {
+ if (vht_tree) {
+ proto_tree_add_item(vht_tree, hf_radiotap_vht_ldpc_extra,
+ tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
+ }
+ }
+
+ if (known & IEEE80211_RADIOTAP_VHT_HAVE_BF) {
+ if (vht_tree)
+ proto_tree_add_item(vht_tree, hf_radiotap_vht_bf,
+ tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
+ }
+
+ if (known & IEEE80211_RADIOTAP_VHT_HAVE_BW) {
+ if (bw <= sizeof(ieee80211_vht_bw2rate_index)/sizeof(ieee80211_vht_bw2rate_index[0]))
+ bandwidth = ieee80211_vht_bw2rate_index[bw];
+ else
+ can_calculate_rate = FALSE; /* unknown bandwidth */
+
+ if (vht_tree)
+ proto_tree_add_item(vht_tree, hf_radiotap_vht_bw,
+ tvb, offset + 3, 1, ENC_LITTLE_ENDIAN);
+ } else {
+ can_calculate_rate = FALSE; /* no bandwidth */
+ }
+
+ for(i=0; i<4; i++) {
+ mcs_nss = tvb_get_guint8(tvb, offset + 4 + i);
+ nss = (mcs_nss & IEEE80211_RADIOTAP_VHT_NSS);
+ mcs = (mcs_nss & IEEE80211_RADIOTAP_VHT_MCS) >> 4;
+
+ if ((known & IEEE80211_RADIOTAP_VHT_HAVE_STBC) && (flags & IEEE80211_RADIOTAP_VHT_STBC))
+ nsts = 2 * nss;
+ else
+ nsts = nss;
+
+ if (nss) {
+ if (vht_tree) {
+ it = proto_tree_add_item(vht_tree, hf_radiotap_vht_user,
+ tvb, offset + 4, 5, ENC_NA);
+ proto_item_append_text(it, " %d: MCS %u", i, mcs);
+ user_tree = proto_item_add_subtree(it, ett_radiotap_vht_user);
+
+ it = proto_tree_add_item(user_tree, hf_radiotap_vht_mcs[i],
+ tvb, offset + 4 + i, 1,
+ ENC_LITTLE_ENDIAN);
+ if (mcs > MAX_MCS_VHT_INDEX) {
+ proto_item_append_text(it, " (invalid)");
+ } else {
+ proto_item_append_text(it, " (%s %s)",
+ ieee80211_vhtinfo[mcs].modulation,
+ ieee80211_vhtinfo[mcs].coding_rate);
+ }
+
+ proto_tree_add_item(user_tree, hf_radiotap_vht_nss[i],
+ tvb, offset + 4 + i, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_uint(user_tree, hf_radiotap_vht_nsts[i],
+ tvb, offset + 4 + i, 1, nsts);
+ proto_tree_add_item(user_tree, hf_radiotap_vht_coding[i],
+ tvb, offset + 8, 1,ENC_LITTLE_ENDIAN);
+ }
+
+ if (can_calculate_rate) {
+ 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,
+ hf_radiotap_vht_datarate[i],
+ tvb, offset, 12, rate,
+ "Data Rate: %.1f Mb/s", rate);
+ PROTO_ITEM_SET_GENERATED(rate_ti);
+ }
+ }
+ }
+ }
+
+ if (known & IEEE80211_RADIOTAP_VHT_HAVE_GID) {
+ if (vht_tree)
+ proto_tree_add_item(vht_tree, hf_radiotap_vht_gid,
+ tvb, offset+9, 1, ENC_LITTLE_ENDIAN);
+ }
+
+ if (known & IEEE80211_RADIOTAP_VHT_HAVE_PAID) {
+ if (vht_tree) {
+ proto_tree_add_item(vht_tree, hf_radiotap_vht_p_aid,
+ tvb, offset+10, 2, ENC_LITTLE_ENDIAN);
+ }
+ }
+
+ break;
+ }
}
}
@@ -1761,6 +2089,11 @@ void proto_register_radiotap(void)
FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(AMPDU_STATUS),
"Specifies if the A-MPDU status field is present", HFILL}},
+ {&hf_radiotap_present_vht,
+ {"VHT information", "radiotap.present.vht",
+ FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(VHT),
+ "Specifies if the VHT field is present", HFILL}},
+
{&hf_radiotap_present_reserved,
{"Reserved", "radiotap.present.reserved",
FT_UINT32, BASE_HEX, NULL, IEEE80211_RADIOTAP_NOTDEFINED,
@@ -2155,6 +2488,169 @@ void proto_register_radiotap(void)
{"A-MPDU subframe delimiter CRC", "radiotap.ampdu.delim_crc",
FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
+ {&hf_radiotap_vht,
+ {"VHT information", "radiotap.vht",
+ FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
+ {&hf_radiotap_vht_known,
+ {"Known VHT information", "radiotap.vht.known",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ "Bit mask indicating what VHT information is present", HFILL}},
+ {&hf_radiotap_vht_user,
+ {"User", "radiotap.vht.user",
+ FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
+ {&hf_radiotap_vht_have_stbc,
+ {"STBC", "radiotap.vht.have_stbc",
+ FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_VHT_HAVE_STBC,
+ "Space Time Block Coding information present", HFILL}},
+ {&hf_radiotap_vht_have_txop_ps,
+ {"TXOP_PS_NOT_ALLOWED", "radiotap.vht.have_txop_ps",
+ FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_VHT_HAVE_TXOP_PS,
+ "TXOP_PS_NOT_ALLOWED information present", HFILL}},
+ {&hf_radiotap_vht_have_gi,
+ {"Guard interval", "radiotap.vht.have_gi",
+ FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_VHT_HAVE_GI,
+ "Short/Long guard interval information present", HFILL}},
+ {&hf_radiotap_vht_have_sgi_nsym_da,
+ {"SGI Nsym disambiguation", "radiotap.vht.have_sgi_nsym_da",
+ FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_VHT_HAVE_SGI_NSYM_DA,
+ "Short guard interval Nsym disambiguation information present", HFILL}},
+ {&hf_radiotap_vht_have_ldpc_extra,
+ {"LDPC extra OFDM symbol", "radiotap.vht.ldpc_extra",
+ FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_VHT_HAVE_LDPC_EXTRA,
+ NULL, HFILL}},
+ {&hf_radiotap_vht_have_bf,
+ {"Beamformed", "radiotap.vht.have_beamformed",
+ FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_VHT_HAVE_BF,
+ NULL, HFILL}},
+ {&hf_radiotap_vht_have_bw,
+ {"Bandwidth", "radiotap.mcs.have_bw",
+ FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_VHT_HAVE_BW,
+ NULL, HFILL}},
+ {&hf_radiotap_vht_have_gid,
+ {"Group ID", "radiotap.mcs.have_gid",
+ FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_VHT_HAVE_GID,
+ NULL, HFILL}},
+ {&hf_radiotap_vht_have_p_aid,
+ {"Partial AID", "radiotap.mcs.have_paid",
+ FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_VHT_HAVE_PAID,
+ NULL, HFILL}},
+ {&hf_radiotap_vht_stbc,
+ {"STBC", "radiotap.vht.stbc",
+ FT_BOOLEAN, 8, TFS(&tfs_on_off), IEEE80211_RADIOTAP_VHT_STBC,
+ "Space Time Block Coding flag", HFILL}},
+ {&hf_radiotap_vht_txop_ps,
+ {"TXOP_PS_NOT_ALLOWED", "radiotap.vht.txop_ps",
+ FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_VHT_TXOP_PS,
+ "Flag indicating whether STAs may doze during TXOP", HFILL}},
+ {&hf_radiotap_vht_gi,
+ {"Guard interval", "radiotap.vht.gi",
+ FT_UINT8, BASE_DEC, VALS(mcs_gi), IEEE80211_RADIOTAP_VHT_SGI,
+ "Short/Long guard interval", HFILL}},
+ {&hf_radiotap_vht_sgi_nsym_da,
+ {"SGI Nsym disambiguation", "radiotap.vht.sgi_nsym_da",
+ FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_VHT_SGI_NSYM_DA,
+ "Short Guard Interval Nsym disambiguation", HFILL}},
+ {&hf_radiotap_vht_ldpc_extra,
+ {"LDPC extra OFDM symbol", "radiotap.vht.ldpc_extra",
+ FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_VHT_LDPC_EXTRA,
+ NULL, HFILL}},
+ {&hf_radiotap_vht_bf,
+ {"Beamformed", "radiotap.vht.beamformed",
+ FT_BOOLEAN, 8, NULL, IEEE80211_RADIOTAP_VHT_BF,
+ NULL, HFILL}},
+ {&hf_radiotap_vht_bw,
+ {"Bandwidth", "radiotap.vht.bw",
+ FT_UINT8, BASE_DEC, VALS(vht_bandwidth), 0x0,
+ NULL, HFILL}},
+ {&hf_radiotap_vht_nsts[0],
+ {"Space-time streams 0", "radiotap.vht.nsts.0",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ "Number of Space-time streams", HFILL}},
+ {&hf_radiotap_vht_nsts[1],
+ {"Space-time streams 1", "radiotap.vht.nsts.1",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ "Number of Space-time streams", HFILL}},
+ {&hf_radiotap_vht_nsts[2],
+ {"Space-time streams 2", "radiotap.vht.nsts.2",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ "Number of Space-time streams", HFILL}},
+ {&hf_radiotap_vht_nsts[3],
+ {"Space-time streams 3", "radiotap.vht.nsts.3",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ "Number of Space-time streams", HFILL}},
+ {&hf_radiotap_vht_mcs[0],
+ {"MCS index 0", "radiotap.vht.mcs.0",
+ FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_VHT_MCS,
+ "MCS index", HFILL}},
+ {&hf_radiotap_vht_mcs[1],
+ {"MCS index 1", "radiotap.vht.mcs.1",
+ FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_VHT_MCS,
+ "MCS index", HFILL}},
+ {&hf_radiotap_vht_mcs[2],
+ {"MCS index 2", "radiotap.vht.mcs.2",
+ FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_VHT_MCS,
+ "MCS index", HFILL}},
+ {&hf_radiotap_vht_mcs[3],
+ {"MCS index 3", "radiotap.vht.mcs.3",
+ FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_VHT_MCS,
+ "MCS index", HFILL}},
+ {&hf_radiotap_vht_nss[0],
+ {"Spatial streams 0", "radiotap.vht.nss.0",
+ FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_VHT_NSS,
+ "Number of spatial streams", HFILL}},
+ {&hf_radiotap_vht_nss[1],
+ {"Spatial streams 1", "radiotap.vht.nss.1",
+ FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_VHT_NSS,
+ "Number of spatial streams", HFILL}},
+ {&hf_radiotap_vht_nss[2],
+ {"Spatial streams 2", "radiotap.vht.nss.2",
+ FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_VHT_NSS,
+ "Number of spatial streams", HFILL}},
+ {&hf_radiotap_vht_nss[3],
+ {"Spatial streams 3", "radiotap.vht.nss.3",
+ FT_UINT8, BASE_DEC, NULL, IEEE80211_RADIOTAP_VHT_NSS,
+ "Number of spatial streams", HFILL}},
+ {&hf_radiotap_vht_coding[0],
+ {"Coding 0", "radiotap.vht.coding.0",
+ FT_UINT8, BASE_DEC, VALS(mcs_fec), 0x0,
+ "Coding", HFILL}},
+ {&hf_radiotap_vht_coding[1],
+ {"Coding 1", "radiotap.vht.coding.1",
+ FT_UINT8, BASE_DEC, VALS(mcs_fec), 0x0,
+ "Coding", HFILL}},
+ {&hf_radiotap_vht_coding[2],
+ {"Coding 2", "radiotap.vht.coding.2",
+ FT_UINT8, BASE_DEC, VALS(mcs_fec), 0x0,
+ "Coding", HFILL}},
+ {&hf_radiotap_vht_coding[3],
+ {"Coding 3", "radiotap.vht.coding.3",
+ FT_UINT8, BASE_DEC, VALS(mcs_fec), 0x0,
+ "Coding", HFILL}},
+ {&hf_radiotap_vht_datarate[0],
+ {"Data rate (Mb/s) 0", "radiotap.vht.datarate.0",
+ FT_FLOAT, BASE_NONE, NULL, 0x0,
+ "Speed this frame was sent/received at", HFILL}},
+ {&hf_radiotap_vht_datarate[1],
+ {"Data rate (Mb/s) 1", "radiotap.vht.datarate.1",
+ FT_FLOAT, BASE_NONE, NULL, 0x0,
+ "Speed this frame was sent/received at", HFILL}},
+ {&hf_radiotap_vht_datarate[2],
+ {"Data rate (Mb/s) 2", "radiotap.vht.datarate.2",
+ FT_FLOAT, BASE_NONE, NULL, 0x0,
+ "Speed this frame was sent/received at", HFILL}},
+ {&hf_radiotap_vht_datarate[3],
+ {"Data rate (Mb/s) 3", "radiotap.vht.datarate.3",
+ FT_FLOAT, BASE_NONE, NULL, 0x0,
+ "Speed this frame was sent/received at", HFILL}},
+ {&hf_radiotap_vht_gid,
+ {"Group Id", "radiotap.vht.gid",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL}},
+ {&hf_radiotap_vht_p_aid,
+ {"Partial AID", "radiotap.vht.paid",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL}},
+
{&hf_radiotap_vendor_ns,
{"Vendor namespace", "radiotap.vendor_namespace",
FT_BYTES, BASE_NONE, NULL, 0x0,
@@ -2200,6 +2696,9 @@ void proto_register_radiotap(void)
&ett_radiotap_mcs_known,
&ett_radiotap_ampdu,
&ett_radiotap_ampdu_flags,
+ &ett_radiotap_vht,
+ &ett_radiotap_vht_known,
+ &ett_radiotap_vht_user
};
module_t *radiotap_module;