aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/packet-ieee80211.c4959
-rw-r--r--epan/dissectors/packet-ieee80211.h9
2 files changed, 2566 insertions, 2402 deletions
diff --git a/epan/dissectors/packet-ieee80211.c b/epan/dissectors/packet-ieee80211.c
index 8f87fbdcf7..6e38b7aa87 100644
--- a/epan/dissectors/packet-ieee80211.c
+++ b/epan/dissectors/packet-ieee80211.c
@@ -5093,6 +5093,8 @@ static dissector_handle_t eth_withoutfcs_handle;
static capture_dissector_handle_t llc_cap_handle;
static capture_dissector_handle_t ipx_cap_handle;
+dissector_table_t tagged_field_table;
+
static int wlan_tap = -1;
static const value_string access_network_type_vals[] = {
@@ -5815,7 +5817,7 @@ dissect_vendor_action_marvell(proto_tree *tree, tvbuff_t *tvb, int offset)
}
static guint
-dissect_advertisement_protocol(packet_info *pinfo, proto_tree *tree,
+dissect_advertisement_protocol_common(packet_info *pinfo, proto_tree *tree,
tvbuff_t *tvb, int offset, gboolean *anqp)
{
guint8 tag_no, tag_len, left;
@@ -5903,6 +5905,12 @@ dissect_advertisement_protocol(packet_info *pinfo, proto_tree *tree,
return 2 + tag_len;
}
+static int
+dissect_advertisement_protocol(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+{
+ return dissect_advertisement_protocol_common(pinfo, tree, tvb, 0, NULL);
+}
+
static void
dissect_anqp_query_list(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset, int end)
{
@@ -7917,7 +7925,7 @@ add_ff_action_public_fields(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
break;
case PA_GAS_INITIAL_REQUEST:
offset += add_ff_dialog_token(tree, tvb, pinfo, offset);
- offset += dissect_advertisement_protocol(pinfo, tree, tvb, offset,
+ offset += dissect_advertisement_protocol_common(pinfo, tree, tvb, offset,
&anqp);
offset += dissect_gas_initial_request(tree, tvb, pinfo, offset, anqp);
break;
@@ -7925,7 +7933,7 @@ add_ff_action_public_fields(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
offset += add_ff_dialog_token(tree, tvb, pinfo, offset);
offset += add_ff_status_code(tree, tvb, pinfo, offset);
offset += add_ff_gas_comeback_delay(tree, tvb, pinfo, offset);
- offset += dissect_advertisement_protocol(pinfo, tree, tvb, offset,
+ offset += dissect_advertisement_protocol_common(pinfo, tree, tvb, offset,
&anqp);
offset += dissect_gas_initial_response(tree, tvb, pinfo, offset, anqp);
break;
@@ -7940,7 +7948,7 @@ add_ff_action_public_fields(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
more = (tvb_get_guint8(tvb, offset) & 0x80) != 0;
offset += add_ff_gas_fragment_id(tree, tvb, pinfo, offset);
offset += add_ff_gas_comeback_delay(tree, tvb, pinfo, offset);
- offset += dissect_advertisement_protocol(pinfo, tree, tvb, offset,
+ offset += dissect_advertisement_protocol_common(pinfo, tree, tvb, offset,
&anqp);
offset += dissect_gas_comeback_response(tree, tvb, pinfo, offset, anqp, frag,
more, dialog_token);
@@ -8819,25 +8827,26 @@ add_ff_oct_mmpdu(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_, int of
return offset - start;
}
-static void
-add_tag_relay_capabilities(packet_info *pinfo, proto_item *item, gint32 tag_len, proto_tree *tree, tvbuff_t *tvb, gint32 *offset) {
+static int
+add_tag_relay_capabilities(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
if (tag_len < 2) {
- expert_add_info_format(pinfo, item, &ei_ieee80211_tag_length, "Tag length must be 2");
- return;
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag length must be 2");
+ return 1;
}
- *offset += 2;
-
- proto_tree_add_item(tree, hf_ieee80211_tag_relay_support, tvb, *offset, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_relay_use, tvb, *offset, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_relay_permission, tvb, *offset, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_AC_power, tvb, *offset, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_relay_prefer, tvb, *offset, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_duplex, tvb, *offset, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_cooperation, tvb, *offset, 1, ENC_NA);
- *offset += 2;
- return;
+ proto_tree_add_item(tree, hf_ieee80211_tag_relay_support, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ieee80211_tag_relay_use, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ieee80211_tag_relay_permission, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ieee80211_tag_AC_power, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ieee80211_tag_relay_prefer, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ieee80211_tag_duplex, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ieee80211_tag_cooperation, tvb, offset, 1, ENC_NA);
+ return tvb_captured_length(tvb);
}
#if 0
@@ -10865,21 +10874,23 @@ dissect_rsn_ie(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
return offset;
}
+
+/* 7.3.2.27 Extended Capabilities information element (127) */
static int
-dissect_extended_capabilities_ie(packet_info *pinfo, proto_tree *tree,
- proto_item *ti, proto_item *ti_len,
- guint32 tag_len, tvbuff_t *tvb,
- int offset, int tag_end)
+dissect_extended_capabilities_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
proto_item *ti_ex_cap;
proto_tree *ex_cap_tree;
if (tag_len < 1)
{
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag length %u too short, must be greater than 0", tag_len);
- return offset;
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag length %u too short, must be greater than 0", tag_len);
+ return 1;
}
- proto_item_append_text(ti, " (%u octet%s)", tag_len, plurality(tag_len, "", "s"));
+ proto_item_append_text(field_data->item_tag, " (%u octet%s)", tag_len, plurality(tag_len, "", "s"));
/* Extended Capability octet 1 */
ti_ex_cap = proto_tree_add_item(tree, hf_ieee80211_tag_extended_capabilities, tvb, offset, 1, ENC_NA);
@@ -10896,7 +10907,7 @@ dissect_extended_capabilities_ie(packet_info *pinfo, proto_tree *tree,
offset += 1;
/* Extended Capability octet 2 */
- if (offset >= tag_end) {
+ if (offset >= tag_len) {
return offset;
}
ti_ex_cap = proto_tree_add_item(tree, hf_ieee80211_tag_extended_capabilities, tvb, offset, 1, ENC_NA);
@@ -10913,7 +10924,7 @@ dissect_extended_capabilities_ie(packet_info *pinfo, proto_tree *tree,
offset += 1;
/* Extended Capability octet 3 */
- if (offset >= tag_end) {
+ if (offset >= tag_len) {
return offset;
}
ti_ex_cap = proto_tree_add_item(tree, hf_ieee80211_tag_extended_capabilities, tvb, offset, 1, ENC_NA);
@@ -10930,7 +10941,7 @@ dissect_extended_capabilities_ie(packet_info *pinfo, proto_tree *tree,
offset += 1;
/* Extended Capability octet 4 */
- if (offset >= tag_end) {
+ if (offset >= tag_len) {
return offset;
}
ti_ex_cap = proto_tree_add_item(tree, hf_ieee80211_tag_extended_capabilities, tvb, offset, 1, ENC_NA);
@@ -10947,7 +10958,7 @@ dissect_extended_capabilities_ie(packet_info *pinfo, proto_tree *tree,
offset += 1;
/* Extended Capability octet 5 */
- if (offset >= tag_end) {
+ if (offset >= tag_len) {
return offset;
}
ti_ex_cap = proto_tree_add_item(tree, hf_ieee80211_tag_extended_capabilities, tvb, offset, 1, ENC_NA);
@@ -10964,7 +10975,7 @@ dissect_extended_capabilities_ie(packet_info *pinfo, proto_tree *tree,
offset += 1;
/* Extended Capability octet 6 */
- if (offset >= tag_end) {
+ if (offset >= tag_len) {
return offset;
}
ti_ex_cap = proto_tree_add_item(tree, hf_ieee80211_tag_extended_capabilities, tvb, offset, 1, ENC_NA);
@@ -10980,7 +10991,7 @@ dissect_extended_capabilities_ie(packet_info *pinfo, proto_tree *tree,
/* Extended Capability octet 7 */
- if (offset >= tag_end) {
+ if (offset >= tag_len) {
return offset;
}
ti_ex_cap = proto_tree_add_item(tree, hf_ieee80211_tag_extended_capabilities, tvb, offset, 1, ENC_NA);
@@ -10991,7 +11002,7 @@ dissect_extended_capabilities_ie(packet_info *pinfo, proto_tree *tree,
offset += 1;
/* Extended Capability octet 8 */
- if (offset >= tag_end) {
+ if (offset >= tag_len) {
return offset;
}
ti_ex_cap = proto_tree_add_item(tree, hf_ieee80211_tag_extended_capabilities, tvb, offset, 1, ENC_NA);
@@ -11002,7 +11013,7 @@ dissect_extended_capabilities_ie(packet_info *pinfo, proto_tree *tree,
/* Std802.11ac-2013, b63-64 indicate the Max Number of MSDUs in AMSDU. */
ti_ex_cap = proto_tree_add_item(ex_cap_tree, hf_ieee80211_tag_extended_capabilities_b63, tvb, offset, 1, ENC_NA);
- if (offset+1 < tag_end) {
+ if (offset+1 < tag_len) {
proto_item_append_text(ti_ex_cap, " (b63-64 Max Number of MSDUs in AMSDU: %s)",
val_to_str((tvb_get_guint8(tvb, offset) & 0x80) + ((tvb_get_guint8(tvb, offset+1) & 0x1) << 1),
@@ -11013,7 +11024,7 @@ dissect_extended_capabilities_ie(packet_info *pinfo, proto_tree *tree,
offset += 1;
/* Extended Capability octet 9 */
- if (offset >= tag_end) {
+ if (offset >= tag_len) {
return offset;
}
ti_ex_cap = proto_tree_add_item(tree, hf_ieee80211_tag_extended_capabilities, tvb, offset, 1, ENC_NA);
@@ -11080,16 +11091,18 @@ dissect_vht_mcs_set(proto_tree *tree, tvbuff_t *tvb, int offset)
}
static int
-dissect_vht_capability_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
- guint32 tag_len, proto_item *ti_len)
+dissect_vht_capability_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
proto_item *cap_item;
proto_tree *cap_tree;
if (tag_len != 12) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"VHT Capabilities IE length %u wrong, must be = 12", tag_len);
- return offset;
+ return 1;
}
/* 4 byte VHT Capabilities Info*/
@@ -11154,16 +11167,18 @@ dissect_vht_capability_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
}
static int
-dissect_vht_operation_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
- guint32 tag_len, proto_item *ti_len)
+dissect_vht_operation_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
proto_item *op_item, *ti;
proto_tree *op_tree, *basic_mcs_tree;
if (tag_len != 5) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"VHT Operation IE length %u wrong, must be = 5", tag_len);
- return offset;
+ return 1;
}
/* 3 byte VHT Operation Info*/
@@ -11192,18 +11207,20 @@ dissect_vht_operation_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
}
static int
-dissect_vht_tx_pwr_envelope(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
- guint32 tag_len, proto_item *ti_len)
+dissect_vht_tx_pwr_envelope(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
proto_item *tx_pwr_item, *ti;
proto_tree *tx_pwr_info_tree;
guint8 opt_ie_cnt=0;
guint8 i;
if (tag_len < 2 || tag_len > 5) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"VHT TX PWR Envelope IE length %u wrong, must be >= 2 and <= 5", tag_len);
- return offset;
+ return 1;
}
tx_pwr_item = proto_tree_add_item(tree, hf_ieee80211_vht_tpe_pwr_info, tvb, offset, 1, ENC_NA);
@@ -11248,18 +11265,21 @@ dissect_vht_tx_pwr_envelope(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
return offset;
}
-static void
-dissect_mobility_domain(proto_tree *tree, tvbuff_t *tvb, int offset,
- guint32 tag_len, association_sanity_check_t *association_sanity_check)
+static int
+dissect_mobility_domain(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
- if (association_sanity_check != NULL) {
- association_sanity_check->association_has_mobility_domain_element = TRUE;
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+
+ if (field_data->sanity_check != NULL) {
+ field_data->sanity_check->association_has_mobility_domain_element = TRUE;
}
if (tag_len < 3) {
- proto_tree_add_string(tree, hf_ieee80211_tag_interpretation, tvb, offset, tag_len,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"MDIE content length must be at least 3 bytes");
- return;
+ return 1;
}
proto_tree_add_item(tree, hf_ieee80211_tag_mobility_domain_mdid,
@@ -11270,17 +11290,19 @@ dissect_mobility_domain(proto_tree *tree, tvbuff_t *tvb, int offset,
tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_item(tree, hf_ieee80211_tag_mobility_domain_ft_capab_resource_req,
tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
+ return tvb_captured_length(tvb);
}
-static void
-dissect_fast_bss_transition(proto_tree *tree, tvbuff_t *tvb, int offset,
- guint32 tag_len)
+static int
+dissect_fast_bss_transition(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
- int end = offset + tag_len;
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
if (tag_len < 82) {
- proto_tree_add_string(tree, hf_ieee80211_tag_interpretation, tvb, offset, tag_len,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"FTIE content length must be at least 82 bytes");
- return;
+ return 1;
}
proto_tree_add_item(tree, hf_ieee80211_tag_ft_mic_control,
@@ -11298,7 +11320,7 @@ dissect_fast_bss_transition(proto_tree *tree, tvbuff_t *tvb, int offset,
tvb, offset, 32, ENC_NA);
offset += 32;
- while (offset + 2 <= end) {
+ while (offset + 2 <= tag_len) {
guint8 id, len;
int s_end;
proto_tree_add_item(tree, hf_ieee80211_tag_ft_subelem_id,
@@ -11311,10 +11333,10 @@ dissect_fast_bss_transition(proto_tree *tree, tvbuff_t *tvb, int offset,
len = tvb_get_guint8(tvb, offset);
offset += 1;
- if (offset + len > end) {
+ if (offset + len > tag_len) {
proto_tree_add_string(tree, hf_ieee80211_tag_interpretation, tvb, offset,
- end - offset, "Invalid FTIE subelement");
- return;
+ tag_len - offset, "Invalid FTIE subelement");
+ return offset;
}
s_end = offset + len;
@@ -11374,15 +11396,21 @@ dissect_fast_bss_transition(proto_tree *tree, tvbuff_t *tvb, int offset,
}
offset = s_end;
}
+
+ return tvb_captured_length(tvb);
}
-static void
-dissect_mmie(proto_tree *tree, tvbuff_t *tvb, int offset, guint32 tag_len)
+static int
+dissect_mmie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+
if (tag_len < 16) {
- proto_tree_add_string(tree, hf_ieee80211_tag_interpretation, tvb, offset, tag_len,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"MMIE content length must be at least 16 bytes");
- return;
+ return 1;
}
proto_tree_add_item(tree, hf_ieee80211_tag_mmie_keyid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
@@ -11390,20 +11418,22 @@ dissect_mmie(proto_tree *tree, tvbuff_t *tvb, int offset, guint32 tag_len)
ENC_NA);
proto_tree_add_item(tree, hf_ieee80211_tag_mmie_mic, tvb, offset + 8, 8,
ENC_NA);
+ return tvb_captured_length(tvb);
}
-static void
-dissect_ssid_list(proto_tree *tree, tvbuff_t *tvb, int offset, guint32 tag_len)
+static int
+dissect_ssid_list(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
{
- int end = offset + tag_len;
+ int tag_len = tvb_reported_length(tvb);
+ int offset = 0;
proto_tree *entry;
gboolean first = TRUE;
- while (offset + 1 <= end) {
+ while (offset + 1 <= tag_len) {
guint8 len = tvb_get_guint8(tvb, offset + 1);
guint8 *str;
- if (offset + 2 + len > end)
+ if (offset + 2 + len > tag_len)
break;
str = tvb_format_text(tvb, offset + 2, len);
@@ -11419,17 +11449,22 @@ dissect_ssid_list(proto_tree *tree, tvbuff_t *tvb, int offset, guint32 tag_len)
ENC_ASCII|ENC_NA);
offset += len;
}
+
+ return tvb_captured_length(tvb);
}
-static void
-dissect_link_identifier(proto_tree *tree, tvbuff_t *tvb, int offset,
- guint32 tag_len)
+static int
+dissect_link_identifier(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+
if (tag_len < 18) {
- proto_tree_add_string(tree, hf_ieee80211_tag_interpretation, tvb, offset, tag_len,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"Link Identifier content length must be at least "
"18 bytes");
- return;
+ return tvb_captured_length(tvb);
}
proto_tree_add_item(tree, hf_ieee80211_tag_link_id_bssid, tvb,
@@ -11438,17 +11473,21 @@ dissect_link_identifier(proto_tree *tree, tvbuff_t *tvb, int offset,
offset + 6, 6, ENC_NA);
proto_tree_add_item(tree, hf_ieee80211_tag_link_id_resp_sta, tvb,
offset + 12, 6, ENC_NA);
+ return tvb_captured_length(tvb);
}
-static void
-dissect_wakeup_schedule(proto_tree *tree, tvbuff_t *tvb, int offset,
- guint32 tag_len)
+static int
+dissect_wakeup_schedule(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+
if (tag_len < 18) {
- proto_tree_add_string(tree, hf_ieee80211_tag_interpretation, tvb, offset, tag_len,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"Wakeup Schedule content length must be at least "
"18 bytes");
- return;
+ return tvb_captured_length(tvb);
}
proto_tree_add_item(tree, hf_ieee80211_tag_wakeup_schedule_offset, tvb,
@@ -11470,17 +11509,21 @@ dissect_wakeup_schedule(proto_tree *tree, tvbuff_t *tvb, int offset,
proto_tree_add_item(tree, hf_ieee80211_tag_wakeup_schedule_idle_count, tvb,
offset, 2, ENC_LITTLE_ENDIAN);
+ return tvb_captured_length(tvb);
}
-static void
-dissect_channel_switch_timing(proto_tree *tree, tvbuff_t *tvb, int offset,
- guint32 tag_len)
+static int
+dissect_channel_switch_timing(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+
if (tag_len < 4) {
- proto_tree_add_string(tree, hf_ieee80211_tag_interpretation, tvb, offset, tag_len,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"Channel Switch Timing content length must be at "
"least 4 bytes");
- return;
+ return tvb_captured_length(tvb);
}
proto_tree_add_item(tree, hf_ieee80211_tag_channel_switch_timing_switch_time,
@@ -11490,17 +11533,19 @@ dissect_channel_switch_timing(proto_tree *tree, tvbuff_t *tvb, int offset,
proto_tree_add_item(tree,
hf_ieee80211_tag_channel_switch_timing_switch_timeout,
tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ return tvb_captured_length(tvb);
}
-static void
-dissect_pti_control(proto_tree *tree, tvbuff_t *tvb, int offset,
- guint32 tag_len)
+static int
+dissect_pti_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+
if (tag_len < 3) {
- proto_tree_add_string(tree, hf_ieee80211_tag_interpretation, tvb, offset, tag_len,
- "PTI Control content length must be at least "
- "3 bytes");
- return;
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "PTI Control content length must be at least 3 bytes");
+ return tvb_captured_length(tvb);
}
proto_tree_add_item(tree, hf_ieee80211_tag_pti_control_tid, tvb,
@@ -11509,17 +11554,19 @@ dissect_pti_control(proto_tree *tree, tvbuff_t *tvb, int offset,
proto_tree_add_item(tree, hf_ieee80211_tag_pti_control_sequence_control, tvb,
offset, 2, ENC_LITTLE_ENDIAN);
+ return tvb_captured_length(tvb);
}
-static void
-dissect_pu_buffer_status(proto_tree *tree, tvbuff_t *tvb, int offset,
- guint32 tag_len)
+static int
+dissect_pu_buffer_status(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+
if (tag_len < 1) {
- proto_tree_add_string(tree, hf_ieee80211_tag_interpretation, tvb, offset, tag_len,
- "PU Buffer Status content length must be at least "
- "1 byte");
- return;
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "PU Buffer Status content length must be at least 1 byte");
+ return tvb_captured_length(tvb);
}
proto_tree_add_item(tree, hf_ieee80211_tag_pu_buffer_status_ac_bk, tvb,
@@ -11530,12 +11577,14 @@ dissect_pu_buffer_status(proto_tree *tree, tvbuff_t *tvb, int offset,
offset, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_item(tree, hf_ieee80211_tag_pu_buffer_status_ac_vo, tvb,
offset, 1, ENC_LITTLE_ENDIAN);
+ return tvb_captured_length(tvb);
}
-static void
-dissect_timeout_interval(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset,
- guint32 tag_len)
+static int
+dissect_timeout_interval(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
+ int tag_len = tvb_reported_length(tvb);
+ int offset = 0;
proto_item *pi;
pi = proto_tree_add_item(tree, hf_ieee80211_tag_timeout_int_type, tvb,
@@ -11544,26 +11593,28 @@ dissect_timeout_interval(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, in
expert_add_info_format(pinfo, pi, &ei_ieee80211_tag_length,
"Timeout Interval content length must be at least "
"5 bytes");
- return;
+ return 1;
}
proto_tree_add_item(tree, hf_ieee80211_tag_timeout_int_value, tvb,
offset + 1, 4, ENC_LITTLE_ENDIAN);
+ return tvb_captured_length(tvb);
}
static int
-dissect_ric_data(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset,
- guint32 tag_len, proto_item *ti, proto_item *ti_len, int ftype)
+dissect_ric_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
-
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
proto_tree *sub_tree;
guint8 desc_cnt = 0;
guint32 next_ie;
int offset_r = 0;
const guint8 ids[] = { TAG_RIC_DESCRIPTOR };
- if (tag_len != 4) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length,
+ if (tag_len != 4) {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"RIC Data Length must be 4 bytes");
return 0;
}
@@ -11587,17 +11638,17 @@ dissect_ric_data(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset
*/
sub_tree = proto_item_add_subtree(tree, ett_tag_ric_data_desc_ie);
- proto_item_append_text(ti, " :Resource Descriptor List");
+ proto_item_append_text(field_data->item_tag, " :Resource Descriptor List");
if (desc_cnt == 0) {
- proto_item_append_text(ti, " :0 (Weird?)");
+ proto_item_append_text(field_data->item_tag, " :0 (Weird?)");
}
- while ( desc_cnt !=0 ) {
+ while ( desc_cnt != 0 ) {
next_ie = tvb_get_guint8(tvb, offset);
- proto_item_append_text(ti, " :(%d:%s)", desc_cnt, val_to_str_ext(next_ie, &tag_num_vals_ext, "Reserved (%d)"));
+ proto_item_append_text(field_data->item_tag, " :(%d:%s)", desc_cnt, val_to_str_ext(next_ie, &tag_num_vals_ext, "Reserved (%d)"));
/* Recursive call to avoid duplication of code*/
- offset_r = add_tagged_field(pinfo, sub_tree, tvb, offset, ftype, ids, G_N_ELEMENTS(ids), NULL);
+ offset_r = add_tagged_field(pinfo, sub_tree, tvb, offset, field_data->ftype, ids, G_N_ELEMENTS(ids), NULL);
if (offset_r == 0 )/* should never happen, returns a min of 2*/
break;
/* This will ensure that the IE after RIC is processed
@@ -11607,18 +11658,21 @@ dissect_ric_data(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset
desc_cnt--;
}
- return tag_len;
+ return tvb_captured_length(tvb);
}
+/* Overlapping BSS Scan Parameters (74) */
static int
-dissect_overlap_bss_scan_par(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset,
- guint32 tag_len, proto_item *ti _U_, proto_item *ti_len)
+dissect_overlap_bss_scan_par(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int offset = 0;
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int tag_len = tvb_reported_length(tvb);
- if (tag_len != 14) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length,
+ if (tag_len != 14) {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"OBSS Length must be 14 bytes");
- return 0;
+ return 1;
}
proto_tree_add_item(tree, hf_ieee80211_tag_obss_spd, tvb, offset, 2, ENC_LITTLE_ENDIAN);
@@ -11645,17 +11699,19 @@ dissect_overlap_bss_scan_par(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb
return offset;
}
+/* RIC Descriptor (75) */
static int
-dissect_ric_descriptor(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset,
- guint32 tag_len, proto_item *ti, proto_item *ti_len)
+dissect_ric_descriptor(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
-
+ int offset = 0;
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int tag_len = tvb_reported_length(tvb);
guint8 rsrc_type = 0;
if (tag_len < 1) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"RIC Data Length must be at least 1 byte");
- return 0;
+ return 1;
}
rsrc_type = tvb_get_guint8(tvb, offset);
@@ -11673,21 +11729,22 @@ dissect_ric_descriptor(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int
/* TODO: Still figuring out how to parse these ones,
* need a sample capture with at least HEX Dump
*/
- proto_item_append_text(ti, " : Block ACK Params");
+ proto_item_append_text(field_data->item_tag, " : Block ACK Params");
proto_tree_add_item(tree, hf_ieee80211_tag_ric_desc_var_params, tvb,
offset, tag_len-1, ENC_NA);
offset += tag_len -1;
}else {
/* 0, 2-255 are reserved*/
- proto_item_append_text(ti, " :Reserved (type != 1)");
+ proto_item_append_text(field_data->item_tag, " :Reserved (type != 1)");
}
return offset;
}
static int
-dissect_ext_bss_load(proto_tree *tree, tvbuff_t *tvb, int offset)
+dissect_ext_bss_load(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
{
+ int offset = 0;
proto_tree_add_item(tree, hf_ieee80211_ext_bss_mu_mimo_capable_sta_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
offset += 2;
proto_tree_add_item(tree, hf_ieee80211_ext_bss_ss_underutilization, tvb, offset, 1, ENC_LITTLE_ENDIAN);
@@ -11702,10 +11759,10 @@ dissect_ext_bss_load(proto_tree *tree, tvbuff_t *tvb, int offset)
return offset;
}
-
static int
-dissect_wide_bw_channel_switch(proto_tree *tree, tvbuff_t *tvb, int offset)
+dissect_wide_bw_channel_switch(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
{
+ int offset = 0;
proto_tree_add_item(tree, hf_ieee80211_wide_bw_new_channel_width, tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
@@ -11716,10 +11773,12 @@ dissect_wide_bw_channel_switch(proto_tree *tree, tvbuff_t *tvb, int offset)
return offset;
}
+
static int
-dissect_channel_switch_wrapper(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset,
- guint32 tag_len)
+dissect_channel_switch_wrapper(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
{
+ int tag_len = tvb_reported_length(tvb);
+ int offset = 0;
int tmp_sublen;
const guint8 ids[] = { TAG_COUNTRY_INFO, TAG_WIDE_BW_CHANNEL_SWITCH,
TAG_VHT_TX_PWR_ENVELOPE };
@@ -11742,8 +11801,9 @@ dissect_channel_switch_wrapper(packet_info *pinfo, proto_tree *tree, tvbuff_t *t
}
static int
-dissect_operating_mode_notification(proto_tree *tree, tvbuff_t *tvb, int offset)
+dissect_operating_mode_notification(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
{
+ int offset = 0;
proto_item *ti;
proto_tree *bit_tree;
@@ -11756,7 +11816,6 @@ dissect_operating_mode_notification(proto_tree *tree, tvbuff_t *tvb, int offset)
proto_tree_add_item(bit_tree, hf_ieee80211_operat_mode_field_rxnsstype, tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
-
return offset;
}
@@ -11908,21 +11967,20 @@ dissect_mcs_set(proto_tree *tree, tvbuff_t *tvb, int offset, gboolean basic, gbo
/* 802.11n D1.10 - HT Information IE */
static int
-dissect_ht_info_ie_1_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
- guint32 tag_len, proto_item *ti_len)
+dissect_ht_info_ie_1_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
proto_item *cap_item;
- proto_tree *cap_tree;
-
- cap_tree = tree;
+ proto_tree *cap_tree = tree;
if (tag_len < 22) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"HT Information IE content length %u wrong, must be at least 22 bytes", tag_len);
- return offset;
+ return 1;
}
-
proto_tree_add_item(cap_tree, hf_ieee80211_ht_info_primary_channel, tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
@@ -12090,8 +12148,9 @@ dissect_wapi_param_set(tvbuff_t *tvb, packet_info *pinfo,
}
static int
-dissect_bss_max_idle_period(proto_tree *tree, tvbuff_t *tvb, int offset)
+dissect_bss_max_idle_period(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
{
+ int offset = 0;
proto_tree_add_item(tree, hf_ieee80211_tag_bss_max_idle_period,
tvb, offset, 2, ENC_LITTLE_ENDIAN);
offset += 2;
@@ -12113,10 +12172,11 @@ static const value_string tfs_request_subelem_ids[] = {
};
static int
-dissect_tfs_request(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset,
- guint32 tag_len, int ftype)
+dissect_tfs_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
- int end = offset + tag_len;
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
const guint8 ids[] = {
1, /* TFS Subelement */
TAG_VENDOR_SPECIFIC_IE
@@ -12130,13 +12190,13 @@ dissect_tfs_request(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int off
proto_tree_add_item(tree, hf_ieee80211_tag_tfs_request_ac_notify,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset++;
- if (offset + 1 >= end) {
+ if (offset + 1 >= tag_len) {
expert_add_info_format(pinfo, tree, &ei_ieee80211_missing_data,
"No TFS Request subelements in TFS Request");
- return end;
+ return tvb_captured_length(tvb);
}
- while (offset + 1 < end) {
+ while (offset + 1 < tag_len) {
guint8 id, len;
int s_offset, s_end;
@@ -12148,10 +12208,10 @@ dissect_tfs_request(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int off
proto_tree_add_item(tree, hf_ieee80211_tag_tfs_request_subelem_len,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset++;
- if (offset + len > end) {
+ if (offset + len > tag_len) {
expert_add_info_format(pinfo, tree, &ei_ieee80211_tag_length,
"Not enough data for TFS Request subelement");
- return end;
+ return tvb_captured_length(tvb);
}
switch (id) {
case TFS_REQ_SUBELEM_TFS:
@@ -12159,7 +12219,7 @@ dissect_tfs_request(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int off
s_end = offset + len;
while (s_offset < s_end) {
/* TODO 1 is interpreted as TAG_SUPP_RATES, fix this! */
- int tlen = add_tagged_field(pinfo, tree, tvb, s_offset, ftype, ids, G_N_ELEMENTS(ids), NULL);
+ int tlen = add_tagged_field(pinfo, tree, tvb, s_offset, field_data->ftype, ids, G_N_ELEMENTS(ids), NULL);
if (tlen==0)
break;
s_offset += tlen;
@@ -12173,12 +12233,12 @@ dissect_tfs_request(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int off
offset += len;
}
- if (offset < end) {
+ if (offset < tag_len) {
proto_tree_add_expert_format(tree, pinfo, &ei_ieee80211_extra_data,
- tvb, offset, end - offset, "Extra data after TFS Subelements");
+ tvb, offset, tag_len - offset, "Extra data after TFS Subelements");
}
- return end;
+ return tvb_captured_length(tvb);
}
enum tfs_response_subelem_id {
@@ -12195,17 +12255,18 @@ static const value_string tfs_response_subelem_ids[] = {
};
static int
-dissect_tfs_response(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
- int offset, guint32 tag_len, int ftype)
+dissect_tfs_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
- int end = offset + tag_len;
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
const guint8 ids[] = {
1, /* TFS Status subelement*/
2, /* TFS subelement */
TAG_VENDOR_SPECIFIC_IE
};
- while (offset + 3 <= end) {
+ while (offset + 3 <= tag_len) {
guint8 id, len;
int s_offset, s_end;
@@ -12217,10 +12278,10 @@ dissect_tfs_response(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
proto_tree_add_item(tree, hf_ieee80211_tag_tfs_response_subelem_len,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset++;
- if (offset + len > end) {
+ if (offset + len > tag_len) {
expert_add_info_format(pinfo, tree, &ei_ieee80211_tag_length,
"Not enough data for TFS Request subelement");
- return end;
+ return tvb_captured_length(tvb);
}
switch (id) {
case TFS_RESP_SUBELEM_TFS_STATUS:
@@ -12234,7 +12295,7 @@ dissect_tfs_response(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
s_end = offset + len;
while (s_offset < s_end) {
/* TODO Element IDs 1 and 2 are misinterpreted! */
- int tlen = add_tagged_field(pinfo, tree, tvb, s_offset, ftype, ids, G_N_ELEMENTS(ids), NULL);
+ int tlen = add_tagged_field(pinfo, tree, tvb, s_offset, field_data->ftype, ids, G_N_ELEMENTS(ids), NULL);
if (tlen==0)
break;
s_offset += tlen;
@@ -12249,12 +12310,12 @@ dissect_tfs_response(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
offset += len;
}
- if (offset < end) {
+ if (offset < tag_len) {
proto_tree_add_expert_format(tree, pinfo, &ei_ieee80211_extra_data,
- tvb, offset, end - offset, "Extra data after TFS Subelements");
+ tvb, offset, tag_len - offset, "Extra data after TFS Subelements");
}
- return end;
+ return tvb_captured_length(tvb);
}
static const value_string wnm_sleep_mode_action_types[] = {
@@ -12277,8 +12338,9 @@ static const value_string wnm_sleep_mode_response_status_vals[] = {
};
static int
-dissect_wnm_sleep_mode(proto_tree *tree, tvbuff_t *tvb, int offset)
+dissect_wnm_sleep_mode(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
{
+ int offset = 0;
proto_tree_add_item(tree, hf_ieee80211_tag_wnm_sleep_mode_action_type,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset++;
@@ -12299,8 +12361,9 @@ static const value_string time_adv_timing_capab_vals[] = {
};
static int
-dissect_time_adv(proto_tree *tree, tvbuff_t *tvb, int offset)
+dissect_time_adv(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
{
+ int offset = 0;
guint8 capab;
proto_item *item;
proto_tree *subtree;
@@ -12386,125 +12449,127 @@ dissect_time_adv(proto_tree *tree, tvbuff_t *tvb, int offset)
}
static int
-dissect_time_zone(proto_tree *tree, tvbuff_t *tvb, int offset,
- guint32 tag_len)
+dissect_time_zone(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
{
+ int tag_len = tvb_reported_length(tvb);
+ int offset = 0;
+
proto_tree_add_item(tree, hf_ieee80211_tag_time_zone, tvb, offset, tag_len,
ENC_ASCII|ENC_NA);
- return offset + tag_len;
+ return tvb_captured_length(tvb);
}
static int
-dissect_ap_channel_report(tvbuff_t *tvb, packet_info *pinfo,
- proto_tree *tree, int offset, guint32 tag_len, proto_item *ti_len,
- int tag_end, proto_item *ti)
+dissect_ap_channel_report(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+
if (tag_len < 1) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"AP Channel Report length %u wrong, must be > 1", tag_len);
- return offset;
+ return tvb_captured_length(tvb);
}
proto_tree_add_item(tree, hf_ieee80211_tag_ap_channel_report_operating_class, tvb,
offset, 1, ENC_LITTLE_ENDIAN);
- proto_item_append_text(ti, ": Operating Class %u, Channel List :", tvb_get_guint8(tvb, offset));
+ proto_item_append_text(field_data->item_tag, ": Operating Class %u, Channel List :", tvb_get_guint8(tvb, offset));
offset += 1;
- while (offset < tag_end)
+ while (offset < tag_len)
{
proto_tree_add_item(tree, hf_ieee80211_tag_ap_channel_report_channel_list, tvb, offset, 1, ENC_NA);
- proto_item_append_text(ti, " %u,", tvb_get_guint8(tvb, offset));
+ proto_item_append_text(field_data->item_tag, " %u,", tvb_get_guint8(tvb, offset));
offset += 1;
}
- return offset;
+ return tvb_captured_length(tvb);
}
-
static int
-dissect_secondary_channel_offset_ie(tvbuff_t *tvb, packet_info *pinfo,
- proto_tree *tree, int offset, guint32 tag_len, proto_item *ti_len)
+dissect_secondary_channel_offset_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
-
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
if (tag_len != 1) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"Secondary Channel Offset length %u wrong, must be = 1", tag_len);
- return offset;
+ return 1;
}
proto_tree_add_item(tree, hf_ieee80211_tag_secondary_channel_offset, tvb,
offset, 1, ENC_LITTLE_ENDIAN);
-
- offset += 1;
-
- return offset;
+ return tvb_captured_length(tvb);
}
+/* BSS Average Access Delay element (63) */
static int
-dissect_bss_avg_access_delay_ie(tvbuff_t *tvb, packet_info *pinfo,
- proto_tree *tree, int offset, guint32 tag_len, proto_item *ti_len)
+dissect_bss_avg_access_delay_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
-
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
if (tag_len != 1) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"BSS Average Access Delay length %u wrong, must be = 1", tag_len);
- return offset;
+ return 1;
}
proto_tree_add_item(tree, hf_ieee80211_tag_bss_ap_avg_access_delay, tvb,
offset, 1, ENC_LITTLE_ENDIAN);
-
- offset += 1;
-
- return offset;
+ return tvb_captured_length(tvb);
}
static int
-dissect_antenna_ie(tvbuff_t *tvb, packet_info *pinfo,
- proto_tree *tree, int offset, guint32 tag_len, proto_item *ti_len)
+dissect_antenna_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
if (tag_len != 1) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"Antenna length %u wrong, must be = 1", tag_len);
- return offset;
+ return 1;
}
proto_tree_add_item(tree, hf_ieee80211_tag_antenna_id, tvb,
offset, 1, ENC_LITTLE_ENDIAN);
- offset += 1;
-
- return offset;
+ return tvb_captured_length(tvb);
}
static int
-dissect_rsni_ie(tvbuff_t *tvb, packet_info *pinfo,
- proto_tree *tree, int offset, guint32 tag_len, proto_item *ti_len)
+dissect_rsni_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
if (tag_len != 1) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"RSNI length %u wrong, must be = 1", tag_len);
- return offset;
+ return 1;
}
proto_tree_add_item(tree, hf_ieee80211_tag_rsni, tvb,
offset, 1, ENC_LITTLE_ENDIAN);
- offset += 1;
-
- return offset;
+ return tvb_captured_length(tvb);
}
static int
-dissect_bss_available_admission_capacity_ie(tvbuff_t *tvb, packet_info *pinfo,
- proto_tree *tree, int offset, guint32 tag_len, proto_item *ti_len)
+dissect_bss_available_admission_capacity_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
proto_item *ti;
proto_tree *btree;
guint16 bitmask;
if (tag_len < 2) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"BSS Available Admission Capacity length %u wrong, must > = 2", tag_len);
return offset;
}
@@ -12618,21 +12683,22 @@ dissect_bss_ac_access_delay_ie(tvbuff_t *tvb, packet_info *pinfo,
return offset;
}
+/* RM Enabled Capabilities (70) */
static int
-dissect_rm_enabled_capabilities_ie(packet_info *pinfo, proto_tree *tree,
- proto_item *ti, proto_item *ti_len,
- guint32 tag_len, tvbuff_t *tvb,
- int offset, int tag_end _U_)
+dissect_rm_enabled_capabilities_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
proto_item *ti_ex_cap;
proto_tree *ex_cap_tree;
if (tag_len != 5)
{
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "RM Enabled Capabilities length %u wrong, must = 5", tag_len);
- return offset;
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "RM Enabled Capabilities length %u wrong, must = 5", tag_len);
+ return 1;
}
- proto_item_append_text(ti, " (%d octets)", tag_len);
+ proto_item_append_text(field_data->item_tag, " (%d octets)", tag_len);
/* RM Enabled Capability octet 1 */
ti_ex_cap = proto_tree_add_item(tree, hf_ieee80211_tag_rm_enabled_capabilities, tvb, offset, 1, ENC_NA);
@@ -12696,12 +12762,13 @@ dissect_rm_enabled_capabilities_ie(packet_info *pinfo, proto_tree *tree,
return offset;
}
+/* 20/40 BSS Coexistence (72) */
static int
-dissect_20_40_bss_coexistence(packet_info *pinfo, proto_tree *tree,
- proto_item *ti_len, guint32 tag_len,
- tvbuff_t *tvb, int offset)
+dissect_20_40_bss_coexistence(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
-
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
static const int *ieee80211_20_40_bss_coexistence_fields[] = {
&hf_ieee80211_tag_20_40_bc_information_request,
&hf_ieee80211_tag_20_40_bc_forty_mhz_intolerant,
@@ -12712,11 +12779,10 @@ dissect_20_40_bss_coexistence(packet_info *pinfo, proto_tree *tree,
NULL
};
-
if (tag_len != 1)
{
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "20/40 BSS Coexistence length %u wrong, must = 1", tag_len);
- return offset;
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "20/40 BSS Coexistence length %u wrong, must = 1", tag_len);
+ return 1;
}
proto_tree_add_bitmask_with_flags(tree, tvb, offset, hf_ieee80211_tag_20_40_bc,
@@ -12729,7 +12795,7 @@ dissect_20_40_bss_coexistence(packet_info *pinfo, proto_tree *tree,
}
static int
-dissect_ht_capability_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
+dissect_ht_capability_ie_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
guint32 tag_len, proto_item *ti_len, gboolean vendorspecific)
{
proto_item *cap_item, *ti;
@@ -12738,11 +12804,11 @@ dissect_ht_capability_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
if (tag_len != 26) {
expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length,
"HT Capabilities IE length %u wrong, must be = 26", tag_len);
- return offset;
+ return (offset > 0) ? offset : 1;
}
if (wlan_ignore_draft_ht && vendorspecific)
- return offset;
+ return (offset > 0) ? offset : 1;
/* 2 byte HT Capabilities Info*/
if (vendorspecific)
@@ -12865,6 +12931,15 @@ dissect_ht_capability_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
}
static int
+dissect_ht_capability_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+
+ return dissect_ht_capability_ie_common(tvb, pinfo, tree, 0, tvb_reported_length(tvb),
+ field_data->item_tag_length, FALSE);
+}
+
+static int
dissect_ht_info_ie_1_0(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
guint32 tag_len, proto_item *ti_len)
{
@@ -13173,7 +13248,7 @@ dissect_vendor_ie_ht(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
switch(type){
case 51:
- dissect_ht_capability_ie(tvb, pinfo, tree, offset, tag_len, ti_len, TRUE);
+ dissect_ht_capability_ie_common(tvb, pinfo, tree, offset, tag_len, ti_len, TRUE);
proto_item_append_text(item, ": HT Capabilities (802.11n D1.10)");
break;
@@ -13189,21 +13264,12 @@ dissect_vendor_ie_ht(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
}
-static guint
-dissect_interworking(packet_info *pinfo, proto_tree *tree, proto_item *item,
- tvbuff_t *tvb, int offset)
+static int
+dissect_interworking(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
- guint8 len;
-
- offset += 1;
- len = tvb_get_guint8(tvb, offset);
- offset += 1;
-
- if ((tvb_reported_length_remaining(tvb, offset) < len) || (len == 0)) {
- expert_add_info_format(pinfo, item, &ei_ieee80211_tag_length,
- "Truncated Interworking element");
- return offset;
- }
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
proto_tree_add_item(tree, hf_ieee80211_tag_interworking_access_network_type,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
@@ -13217,46 +13283,44 @@ dissect_interworking(packet_info *pinfo, proto_tree *tree, proto_item *item,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
- if ((len == (1 + 2)) || (len == (1 + 2 + 6))) {
+ if ((tag_len == (1 + 2)) || (tag_len == (1 + 2 + 6))) {
dissect_venue_info(tree, tvb, offset);
offset += 2;
}
- if ((len == (1 + 6)) || (len == (1 + 2 + 6))) {
+ if ((tag_len == (1 + 6)) || (tag_len == (1 + 2 + 6))) {
proto_tree_add_item(tree, hf_ieee80211_tag_interworking_hessid,
tvb, offset, 6, ENC_NA);
offset += 6;
}
- if ((len != 1) && (len != (1 + 2)) && (len != (1 + 6)) && (len != (1 + 2 + 6))) {
- expert_add_info_format(pinfo, item, &ei_ieee80211_tag_length,
+ if ((tag_len != 1) && (tag_len != (1 + 2)) && (tag_len != (1 + 6)) && (tag_len != (1 + 2 + 6))) {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"Invalid Interworking element length");
}
return offset;
}
-static guint
-dissect_qos_map_set(packet_info *pinfo, proto_tree *tree, proto_item *item,
- tvbuff_t *tvb, int offset)
+static int
+dissect_qos_map_set(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
- guint8 len, left;
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ guint8 left;
guint8 val, val2;
int i;
- proto_item *dscp_item;
+ proto_item *dscp_item, *item;
proto_tree *dscp_tree;
- offset++;
- len = tvb_get_guint8(tvb, offset);
- offset++;
-
- if (tvb_reported_length_remaining(tvb, offset) < len || len < 16 || len & 1) {
- expert_add_info_format(pinfo, item, &ei_ieee80211_bad_length,
+ if (tag_len < 16 || tag_len & 1) {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_bad_length,
"Truncated QoS Map Set element");
- return 2 + len;
+ return tvb_captured_length(tvb);
}
- left = len - 16;
+ left = tag_len - 16;
while (left >= 2) {
dscp_item = proto_tree_add_item(tree, hf_ieee80211_tag_qos_map_set_dscp_exc,
tvb, offset, 2, ENC_NA);
@@ -13319,26 +13383,17 @@ dissect_qos_map_set(packet_info *pinfo, proto_tree *tree, proto_item *item,
}
}
- return 2 + len;
+ return tvb_captured_length(tvb);
}
-static guint
-dissect_roaming_consortium(packet_info *pinfo, proto_tree *tree,
- proto_item *item, tvbuff_t *tvb, int offset)
+static int
+dissect_roaming_consortium(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
- guint8 len, oi_lens, oi1_len, oi2_len;
- int end;
-
- offset += 1;
- len = tvb_get_guint8(tvb, offset);
- offset += 1;
- end = offset + len;
-
- if ((tvb_reported_length_remaining(tvb, offset) < len) || (len < 2)) {
- expert_add_info_format(pinfo, item, &ei_ieee80211_tag_length,
- "Truncated Roaming Consortium element");
- return 2 + len;
- }
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ proto_item* item;
+ guint8 oi_lens, oi1_len, oi2_len;
proto_tree_add_item(tree, hf_ieee80211_tag_roaming_consortium_num_anqp_oi,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
@@ -13353,10 +13408,10 @@ dissect_roaming_consortium(packet_info *pinfo, proto_tree *tree,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
- if (offset + oi1_len > end) {
- expert_add_info_format(pinfo, item, &ei_ieee80211_tag_length,
+ if (offset + oi1_len > tag_len) {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"Truncated Roaming Consortium element");
- return 2 + len;
+ return tvb_captured_length(tvb);
}
item = proto_tree_add_item(tree, hf_ieee80211_tag_roaming_consortium_oi1,
@@ -13364,10 +13419,10 @@ dissect_roaming_consortium(packet_info *pinfo, proto_tree *tree,
add_manuf(item, tvb, offset);
offset += oi1_len;
- if (offset + oi2_len > end) {
- expert_add_info_format(pinfo, item, &ei_ieee80211_tag_length,
+ if (offset + oi2_len > tag_len) {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"Truncated Roaming Consortium element");
- return 2 + len;
+ return tvb_captured_length(tvb);
}
if (oi2_len > 0) {
@@ -13376,12 +13431,12 @@ dissect_roaming_consortium(packet_info *pinfo, proto_tree *tree,
offset += oi2_len;
}
- if (end > offset) {
+ if (tag_len > offset) {
proto_tree_add_item(tree, hf_ieee80211_tag_roaming_consortium_oi3,
- tvb, offset, end - offset, ENC_NA);
+ tvb, offset, tag_len - offset, ENC_NA);
}
- return 2 + len;
+ return tvb_captured_length(tvb);
}
@@ -13392,10 +13447,11 @@ dissect_roaming_consortium(packet_info *pinfo, proto_tree *tree,
static int beacon_padding = 0; /* beacon padding bug */
static int
-ieee80211_tag_ssid(packet_info *pinfo, proto_tree *tree,
- proto_item *ti, proto_item *ti_len,
- guint32 tag_len, tvbuff_t *tvb, int offset)
+ieee80211_tag_ssid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
/* 7.3.2.1 SSID element (0) */
gchar *ssid; /* The SSID may consist of arbitrary bytes */
gint ssid_len = tag_len;
@@ -13404,7 +13460,7 @@ ieee80211_tag_ssid(packet_info *pinfo, proto_tree *tree,
return offset;
if (ssid_len > MAX_SSID_LEN) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"SSID length (%u) greater than maximum (%u)",
ssid_len, MAX_SSID_LEN);
ssid_len = MAX_SSID_LEN;
@@ -13471,7 +13527,7 @@ ieee80211_tag_ssid(packet_info *pinfo, proto_tree *tree,
if (ssid_len > 0) {
gchar* s = format_text(wmem_packet_scope(), ssid, ssid_len);
- proto_item_append_text(ti, ": %s", s);
+ proto_item_append_text(field_data->item_tag, ": %s", s);
col_append_fstr(pinfo->cinfo, COL_INFO, ", SSID=%s", s);
@@ -13479,7 +13535,7 @@ ieee80211_tag_ssid(packet_info *pinfo, proto_tree *tree,
memcpy(wlan_stats.ssid, ssid, MIN(ssid_len, MAX_SSID_LEN));
wlan_stats.ssid_len = ssid_len;
} else {
- proto_item_append_text(ti, ": Broadcast");
+ proto_item_append_text(field_data->item_tag, ": Broadcast");
col_append_str(pinfo->cinfo, COL_INFO, ", SSID=Broadcast");
}
@@ -13490,11 +13546,11 @@ ieee80211_tag_ssid(packet_info *pinfo, proto_tree *tree,
}
static int
-dissect_neighbor_report(tvbuff_t *tvb, packet_info *pinfo,
- proto_tree *tree, int offset, guint32 tag_len, proto_item *ti_len,
- int tag_end, proto_item *ti _U_)
+dissect_neighbor_report(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
-
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
guint8 sub_tag_id;
guint32 sub_tag_length;
proto_item *parent_item;
@@ -13502,13 +13558,11 @@ dissect_neighbor_report(tvbuff_t *tvb, packet_info *pinfo,
tvbuff_t *sub_tag_tvb = NULL;
if (tag_len < 13) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"Neighbor Report length %u wrong, must be > 13", tag_len);
- return offset;
+ return tvb_captured_length(tvb);
}
- /* tag_offset = offset; */
-
proto_tree_add_item(tree, hf_ieee80211_tag_neighbor_report_bssid, tvb, offset, 6, ENC_NA);
offset += 6;
@@ -13544,10 +13598,10 @@ dissect_neighbor_report(tvbuff_t *tvb, packet_info *pinfo,
/* The Optional Subelements field format contains zero or more subelements */
if (tag_len == 13){ /* tag_len == 13 => no Subelements */
- return offset;
+ return tvb_captured_length(tvb);
}
- while (offset < tag_end)
+ while (offset < tag_len)
{
sub_tag_id = tvb_get_guint8(tvb, offset);
@@ -13569,74 +13623,71 @@ dissect_neighbor_report(tvbuff_t *tvb, packet_info *pinfo,
case NR_SUB_ID_HT_CAPABILITIES:
sub_tag_tree = proto_tree_add_subtree(tree, tvb, offset, sub_tag_length,
ett_tag_neighbor_report_sub_tag_tree, NULL, "HT Capabilities");
- dissect_ht_capability_ie(sub_tag_tvb, pinfo, sub_tag_tree, 0, sub_tag_length, ti_len, FALSE);
+ dissect_ht_capability_ie_common(sub_tag_tvb, pinfo, sub_tag_tree, 0, sub_tag_length, field_data->item_tag_length, FALSE);
break;
case NR_SUB_ID_HT_OPERATION:
sub_tag_tree = proto_tree_add_subtree(tree, tvb, offset, sub_tag_length,
ett_tag_neighbor_report_sub_tag_tree, NULL, "HT Information");
- dissect_ht_info_ie_1_1(sub_tag_tvb, pinfo, sub_tag_tree, 0, sub_tag_length, ti_len);
+ dissect_ht_info_ie_1_1(sub_tag_tvb, pinfo, sub_tag_tree, data);
break;
case NR_SUB_ID_SEC_CHANNEL_OFFSET:
sub_tag_tree = proto_tree_add_subtree(tree, tvb, offset, sub_tag_length,
ett_tag_neighbor_report_sub_tag_tree, NULL, "Secondary Channel Offset");
- dissect_secondary_channel_offset_ie(sub_tag_tvb, pinfo, sub_tag_tree, 0, sub_tag_length, ti_len);
+ dissect_secondary_channel_offset_ie(sub_tag_tvb, pinfo, sub_tag_tree, data);
break;
case NR_SUB_ID_VENDOR_SPECIFIC:
- default:
+ default:
break;
}
- offset += sub_tag_length;
-}
+ offset += sub_tag_length;
+ }
return offset;
}
static int
-ieee80211_tag_supp_rates(packet_info *pinfo, proto_tree *tree,
- proto_item *ti, proto_item *ti_len,
- guint32 tag_len, tvbuff_t *tvb,
- int offset, int tag_end)
+ieee80211_tag_supp_rates(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
/* 7.3.2.2 Supported Rates element (1) */
if (tag_len < 1) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"Tag length %u too short, must be greater than 0",
tag_len);
return offset;
}
- offset += 2;
-
- while (offset < tag_end) {
+ while (offset < tag_len) {
proto_tree_add_item(tree, hf_ieee80211_tag_supp_rates, tvb, offset, 1,
ENC_LITTLE_ENDIAN);
- proto_item_append_text(ti, " %s,",
+ proto_item_append_text(field_data->item_tag, " %s,",
val_to_str_ext_const(tvb_get_guint8(tvb, offset),
&ieee80211_supported_rates_vals_ext,
"Unknown Rate"));
offset += 1;
}
- proto_item_append_text(ti, " [Mbit/sec]");
+ proto_item_append_text(field_data->item_tag, " [Mbit/sec]");
return offset;
}
static int
-ieee80211_tag_fh_parameter(packet_info *pinfo, proto_tree *tree,
- proto_item *ti_len, guint32 tag_len,
- tvbuff_t *tvb, int offset)
+ieee80211_tag_fh_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
/* 7.3.2.3 FH Parameter Set element (2) */
if (tag_len < 5) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"Tag length %u too short, must be >= 5", tag_len);
- return offset;
+ return 1;
}
- offset += 2;
-
proto_tree_add_item(tree, hf_ieee80211_tag_fh_dwell_time,
tvb, offset, 2, ENC_LITTLE_ENDIAN);
offset += 2;
@@ -13657,24 +13708,22 @@ ieee80211_tag_fh_parameter(packet_info *pinfo, proto_tree *tree,
}
static int
-ieee80211_tag_ds_parameter(packet_info *pinfo, proto_tree *tree,
- proto_item *ti, proto_item *ti_len,
- guint32 tag_len, tvbuff_t *tvb,
- int offset)
+ieee80211_tag_ds_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
/* 7.3.2.4 DS Parameter Set element (3) */
if (tag_len != 1) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"Tag length %u wrong, must be = 1", tag_len);
- return offset;
+ return 1;
}
- offset += 2;
-
proto_tree_add_item(tree, hf_ieee80211_tag_ds_param_channel,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_item_append_text(ti, ": Current Channel: %u",
+ proto_item_append_text(field_data->item_tag, ": Current Channel: %u",
tvb_get_guint8(tvb, offset));
wlan_stats.channel = tvb_get_guint8(tvb, offset);
@@ -13684,39 +13733,37 @@ ieee80211_tag_ds_parameter(packet_info *pinfo, proto_tree *tree,
}
static int
-ieee80211_tag_cf_parameter(packet_info *pinfo, proto_tree *tree,
- proto_item *ti, proto_item *ti_len,
- guint32 tag_len, tvbuff_t *tvb,
- int offset)
+ieee80211_tag_cf_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
/* 7.3.2.5 CF Parameter Set element (4) */
if (tag_len != 6) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"Tag length %u wrong, must be = 6", tag_len);
return offset;
}
- offset += 2;
-
proto_tree_add_item(tree, hf_ieee80211_tag_cfp_count,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_item_append_text(ti, ": CFP count %u", tvb_get_guint8(tvb, offset));
+ proto_item_append_text(field_data->item_tag, ": CFP count %u", tvb_get_guint8(tvb, offset));
offset += 1;
proto_tree_add_item(tree, hf_ieee80211_tag_cfp_period,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_item_append_text(ti, ": CFP Period %u", tvb_get_guint8(tvb, offset));
+ proto_item_append_text(field_data->item_tag, ": CFP Period %u", tvb_get_guint8(tvb, offset));
offset += 1;
proto_tree_add_item(tree, hf_ieee80211_tag_cfp_max_duration,
tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_item_append_text(ti, ": CFP Max Duration %u",
+ proto_item_append_text(field_data->item_tag, ": CFP Max Duration %u",
tvb_get_letohs(tvb, offset));
offset += 2;
proto_tree_add_item(tree, hf_ieee80211_tag_cfp_dur_remaining,
tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_item_append_text(ti, ": CFP Dur Remaining %u",
+ proto_item_append_text(field_data->item_tag, ": CFP Dur Remaining %u",
tvb_get_letohs(tvb, offset));
offset += 1;
@@ -13724,31 +13771,30 @@ ieee80211_tag_cf_parameter(packet_info *pinfo, proto_tree *tree,
}
static int
-ieee80211_tag_tim(packet_info *pinfo, proto_tree *tree,
- proto_item *ti, proto_item *ti_len,
- guint32 tag_len, tvbuff_t *tvb, int offset)
+ieee80211_tag_tim(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
proto_tree *bmapctl_tree;
proto_item *bmapctl_item;
guint aid, pvb_len, n1, i, j, byte;
/* 802.11-2012: 8.4.2.7 TIM element (5) */
if (tag_len < 4) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"Tag length %u too short, must be >= 4", tag_len);
- return offset;
+ return 1;
}
- offset += 2;
-
proto_tree_add_item(tree, hf_ieee80211_tim_dtim_count,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_item_append_text(ti, ": DTIM %u of", tvb_get_guint8(tvb, offset));
+ proto_item_append_text(field_data->item_tag, ": DTIM %u of", tvb_get_guint8(tvb, offset));
offset += 1;
proto_tree_add_item(tree, hf_ieee80211_tim_dtim_period,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_item_append_text(ti, " %u bitmap", tvb_get_guint8(tvb, offset + 1));
+ proto_item_append_text(field_data->item_tag, " %u bitmap", tvb_get_guint8(tvb, offset + 1));
offset += 1;
bmapctl_item = proto_tree_add_item(tree, hf_ieee80211_tim_bmapctl,
@@ -13780,24 +13826,22 @@ ieee80211_tag_tim(packet_info *pinfo, proto_tree *tree,
}
static int
-ieee80211_tag_ibss_parameter(packet_info *pinfo, proto_tree *tree,
- proto_item *ti, proto_item *ti_len,
- guint32 tag_len, tvbuff_t *tvb,
- int offset)
+ieee80211_tag_ibss_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
/* 7.3.2.7 IBSS Parameter Set element (6) */
if (tag_len != 2) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"Tag length %u wrong, must be = 2", tag_len);
- return offset;
+ return 1;
}
- offset += 2;
-
proto_tree_add_item(tree, hf_ieee80211_tag_ibss_atim_window,
tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_item_append_text(ti, ": ATIM window 0x%x",
+ proto_item_append_text(field_data->item_tag, ": ATIM window 0x%x",
tvb_get_letohs(tvb, offset));
offset += 2;
@@ -13812,39 +13856,37 @@ static const value_string environment_vals[] = {
};
static int
-ieee80211_tag_country_info(packet_info *pinfo, proto_tree *tree,
- proto_item *ti, proto_item *ti_len,
- guint32 tag_len, tvbuff_t *tvb,
- int offset, int tag_end)
+ieee80211_tag_country_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
/* 7.3.2.9 Country information element (7) */
proto_tree *sub_tree;
proto_item *sub_item;
const guint8* country_code;
if (tag_len < 6) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"Tag length %u too short, must be >= 6", tag_len);
- return offset;
+ return 1;
}
- offset += 2;
-
proto_tree_add_item_ret_string(tree, hf_ieee80211_tag_country_info_code,
tvb, offset, 2, ENC_ASCII|ENC_NA, wmem_packet_scope(), &country_code);
- proto_item_append_text(ti, ": Country Code %s", country_code);
+ proto_item_append_text(field_data->item_tag, ": Country Code %s", country_code);
offset += 2;
proto_tree_add_item(tree, hf_ieee80211_tag_country_info_env,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_item_append_text(ti, ", Environment %s",
+ proto_item_append_text(field_data->item_tag, ", Environment %s",
val_to_str(tvb_get_guint8(tvb, offset),
environment_vals, "Unknown (0x%02x)"));
offset += 1;
- while (offset < tag_end) {
+ while (offset < tag_len) {
/* Padding ? */
- if ((tag_end - offset) < 3) {
+ if ((tag_len - offset) < 3) {
proto_tree_add_item(tree, hf_ieee80211_tag_country_info_pad,
tvb, offset, 1, ENC_NA);
offset += 1;
@@ -13899,30 +13941,27 @@ ieee80211_tag_country_info(packet_info *pinfo, proto_tree *tree,
}
static int
-ieee80211_tag_fh_hopping_parameter(packet_info *pinfo,
- proto_tree *tree,
- proto_item *ti,
- proto_item *ti_len,
- guint32 tag_len, tvbuff_t *tvb,
- int offset)
+ieee80211_tag_fh_hopping_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+
/* 7.3.2.10 Hopping Pattern Parameters information element (8) */
if (tag_len < 2) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"Tag length %u too short, must be >= 2", tag_len);
- return offset;
+ return 1;
}
- offset += 2;
-
proto_tree_add_item(tree, hf_ieee80211_tag_fh_hopping_parameter_prime_radix,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_item_append_text(ti, ": Prime Radix: %u", tvb_get_guint8(tvb, offset));
+ proto_item_append_text(field_data->item_tag, ": Prime Radix: %u", tvb_get_guint8(tvb, offset));
offset += 1;
proto_tree_add_item(tree, hf_ieee80211_tag_fh_hopping_parameter_nb_channels,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_item_append_text(ti, ", Number of Channels: %u",
+ proto_item_append_text(field_data->item_tag, ", Number of Channels: %u",
tvb_get_guint8(tvb, offset));
offset += 1;
@@ -13930,20 +13969,19 @@ ieee80211_tag_fh_hopping_parameter(packet_info *pinfo,
}
static int
-ieee80211_tag_fh_hopping_table(packet_info *pinfo, proto_tree *tree,
- proto_item *ti_len,
- guint32 tag_len, tvbuff_t *tvb,
- int offset, int tag_end)
+ieee80211_tag_fh_hopping_table(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+
/* 7.3.2.11 Hopping Pattern Table information element (9) */
if (tag_len < 4) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length,
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length,
"Tag length %u too short, must be >= 4", tag_len);
- return offset;
+ return 1;
}
- offset += 2;
-
proto_tree_add_item(tree, hf_ieee80211_tag_fh_hopping_table_flag,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
@@ -13960,7 +13998,7 @@ ieee80211_tag_fh_hopping_table(packet_info *pinfo, proto_tree *tree,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
- while (offset < tag_end) {
+ while (offset < tag_len) {
proto_tree_add_item(tree, hf_ieee80211_tag_fh_hopping_random_table,
tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
@@ -13974,16 +14012,12 @@ add_tagged_field(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset
const guint8 *valid_element_ids, guint valid_element_ids_count,
association_sanity_check_t *association_sanity_check)
{
- guint32 oui;
tvbuff_t *tag_tvb;
- const guint8 *tag_data_ptr;
guint32 tag_no, tag_len;
- int n, ret;
- char print_buff[SHORT_STR];
proto_tree *orig_tree = tree;
proto_item *ti = NULL;
proto_item *ti_len, *ti_tag;
- int tag_end;
+ ieee80211_tagged_field_data_t field_data;
gboolean isDMG;
gboolean *p_isDMG = ((gboolean*)(p_get_proto_data(wmem_file_scope(), pinfo, proto_wlan, IS_DMG_KEY)));
@@ -13991,7 +14025,6 @@ add_tagged_field(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset
isDMG = p_isDMG ? *p_isDMG : FALSE;
tag_no = tvb_get_guint8(tvb, offset);
tag_len = tvb_get_guint8(tvb, offset + 1);
- tag_end = offset + 2 + tag_len;
if (tree) {
ti = proto_tree_add_item(orig_tree, hf_ieee80211_tag, tvb, offset, 2 + tag_len , ENC_NA);
@@ -14023,2291 +14056,2289 @@ add_tagged_field(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset
if (!valid_tag_no) {
expert_add_info_format(pinfo, ti_tag, &ei_ieee80211_tag_number,
"Unexpected Element ID %d", tag_no);
- goto end_of_tag;
+ return tag_len + 1 + 1;
}
}
- switch (tag_no) {
- case TAG_SSID:
- offset += ieee80211_tag_ssid(pinfo, tree, ti, ti_len, tag_len, tvb,
- offset);
- break;
- case TAG_SUPP_RATES:
- offset += ieee80211_tag_supp_rates(pinfo, tree, ti, ti_len, tag_len, tvb,
- offset, tag_end);
- break;
- case TAG_FH_PARAMETER:
- offset += ieee80211_tag_fh_parameter(pinfo, tree, ti_len, tag_len, tvb,
- offset);
- break;
- case TAG_DS_PARAMETER:
- offset += ieee80211_tag_ds_parameter(pinfo, tree, ti, ti_len, tag_len, tvb,
- offset);
- break;
- case TAG_CF_PARAMETER:
- offset += ieee80211_tag_cf_parameter(pinfo, tree, ti, ti_len, tag_len, tvb,
- offset);
- break;
- case TAG_TIM:
- offset += ieee80211_tag_tim(pinfo, tree, ti, ti_len, tag_len, tvb, offset);
- break;
- case TAG_IBSS_PARAMETER:
- offset += ieee80211_tag_ibss_parameter(pinfo, tree, ti, ti_len, tag_len,
- tvb, offset);
- break;
- case TAG_COUNTRY_INFO:
- offset += ieee80211_tag_country_info(pinfo, tree, ti, ti_len, tag_len, tvb,
- offset, tag_end);
- break;
- case TAG_FH_HOPPING_PARAMETER:
- offset += ieee80211_tag_fh_hopping_parameter(pinfo, tree, ti, ti_len,
- tag_len, tvb, offset);
- break;
- case TAG_FH_HOPPING_TABLE:
- offset += ieee80211_tag_fh_hopping_table(pinfo, tree, ti_len, tag_len,
- tvb, offset, tag_end);
- break;
+ tag_tvb = tvb_new_subset_length(tvb, offset+2, tag_len);
+ field_data.sanity_check = association_sanity_check;
+ field_data.ftype = ftype;
+ field_data.isDMG = isDMG;
+ field_data.item_tag = ti;
+ field_data.item_tag_length = ti_len;
+ if (!dissector_try_uint_new(tagged_field_table, tag_no, tag_tvb, pinfo, tree, FALSE, &field_data))
+ {
+ proto_tree_add_item(tree, hf_ieee80211_tag_data, tvb, offset + 1 + 1, tag_len, ENC_NA);
+ expert_add_info_format(pinfo, ti_tag, &ei_ieee80211_tag_data,
+ "Dissector for 802.11 IE Tag"
+ " (%s) code not implemented, Contact"
+ " Wireshark developers if you want this supported", val_to_str_ext(tag_no,
+ &tag_num_vals_ext, "(%d)"));
+ proto_item_append_text(ti, ": Undecoded");
+ }
- case TAG_REQUEST: /* 7.3.2.12 Request information element (10) */
- while (offset < tag_end)
- {
- proto_tree_add_item(tree, hf_ieee80211_tag_request, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- offset += 1;
- }
- break;
+ return tag_len + 1 + 1;
+}
- case TAG_QBSS_LOAD: /* 7.3.2.28 BSS Load element (11) */
- /* 8.4.2.30 in 802.11-2012 */
- if ((tag_len < 4) || (tag_len > 5))
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 4 or 5", tag_len);
- break;
- }
+/* 7.3.2.12 Request information element (10) */
+static int
+ieee80211_tag_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
+{
+ int tag_len = tvb_reported_length(tvb);
+ int offset = 0;
- if (tag_len == 4)
- {
- /* QBSS Version 1 */
- proto_item_append_text(ti, " Cisco QBSS Version 1 - non CCA");
-
- /* Extract Values */
- proto_tree_add_uint(tree, hf_ieee80211_qbss_version, tvb, offset + 2, tag_len, 1);
- proto_tree_add_item(tree, hf_ieee80211_qbss_scount, tvb, offset + 2, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_qbss_cu, tvb, offset + 4, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_qbss_adc, tvb, offset + 5, 1, ENC_LITTLE_ENDIAN);
- }
- else if (tag_len == 5)
+ while (offset < tag_len)
+ {
+ proto_tree_add_item(tree, hf_ieee80211_tag_request, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
+ }
+ return ((tag_len > 0) ? tag_len : 1);
+}
- {
- proto_item *base_item;
-
- /* QBSS Version 2 */
- proto_item_append_text(ti, " 802.11e CCA Version");
-
- /* Extract Values */
- proto_tree_add_uint(tree, hf_ieee80211_qbss_version, tvb, offset + 2, tag_len, 2);
- proto_tree_add_item(tree, hf_ieee80211_qbss_scount, tvb, offset + 2, 2, ENC_LITTLE_ENDIAN);
- base_item = proto_tree_add_item(tree, hf_ieee80211_qbss_cu, tvb, offset + 4, 1, ENC_LITTLE_ENDIAN);
- proto_item_append_text(base_item, " (%d%%)", 100*tvb_get_guint8(tvb, offset + 4)/255);
- base_item = proto_tree_add_item(tree, hf_ieee80211_qbss_adc, tvb, offset + 5, 2, ENC_LITTLE_ENDIAN);
- proto_item_append_text(base_item, " (%d us/s)", tvb_get_letohs(tvb, offset + 5)*32);
- }
- break;
+/* 7.3.2.28 BSS Load element (11) */
+/* 8.4.2.30 in 802.11-2012 */
+static int
+ieee80211_tag_qbss_load(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+
+ if ((tag_len < 4) || (tag_len > 5))
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 4 or 5", tag_len);
+ return tvb_captured_length(tvb);
+ }
+
+ if (tag_len == 4)
+ {
+ /* QBSS Version 1 */
+ proto_item_append_text(field_data->item_tag, " Cisco QBSS Version 1 - non CCA");
+
+ /* Extract Values */
+ proto_tree_add_uint(tree, hf_ieee80211_qbss_version, tvb, offset, tag_len, 1);
+ proto_tree_add_item(tree, hf_ieee80211_qbss_scount, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_qbss_cu, tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_qbss_adc, tvb, offset + 3, 1, ENC_LITTLE_ENDIAN);
+ }
+ else if (tag_len == 5)
+ {
+ proto_item *base_item;
+
+ /* QBSS Version 2 */
+ proto_item_append_text(field_data->item_tag, " 802.11e CCA Version");
+
+ /* Extract Values */
+ proto_tree_add_uint(tree, hf_ieee80211_qbss_version, tvb, offset, tag_len, 2);
+ proto_tree_add_item(tree, hf_ieee80211_qbss_scount, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ base_item = proto_tree_add_item(tree, hf_ieee80211_qbss_cu, tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(base_item, " (%d%%)", 100*tvb_get_guint8(tvb, offset + 2)/255);
+ base_item = proto_tree_add_item(tree, hf_ieee80211_qbss_adc, tvb, offset + 3, 2, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(base_item, " (%d us/s)", tvb_get_letohs(tvb, offset + 3)*32);
+ }
+
+ return tvb_captured_length(tvb);
+}
#if 0 /* ToDo */
- case TAG_EDCA_PARAM_SET: /* 8.4.2.31 in 802-11-2012 */
- offset += add_ff_qos_info_ap(tree, tvb, pinfo, offset);
- offset += 1; /* reserved */
- offset += 4; /* AC_BE */
- offset += 4; /* AC_BK */
- offset += 4; /* AC_VI */
- offset += 4; /* AC_VO */
- break;
+/* 8.4.2.31 in 802-11-2012 */
+static int
+ieee80211_tag_edca_param_set(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int offset = 0;
+ offset += add_ff_qos_info_ap(tree, tvb, pinfo, offset);
+ offset += 1; /* reserved */
+ offset += 4; /* AC_BE */
+ offset += 4; /* AC_BK */
+ offset += 4; /* AC_VI */
+ offset += 4; /* AC_VO */
+ return tvb_captured_length(tvb);
+}
#endif
- case TAG_TSPEC: /* TSPEC element (13) */
- if (isDMG == FALSE && tag_len != 55)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 55", tag_len);
- break;
- }
- if (isDMG == TRUE && tag_len != 57)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 57", tag_len);
- break;
- }
- offset += 2;
+/* TSPEC element (13) */
+static int
+ieee80211_tag_tspec(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
- add_ff_qos_ts_info(tree, tvb, pinfo, offset);
- offset += 3;
+ if (field_data->isDMG == FALSE && tag_len != 55)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 55", tag_len);
+ return tvb_captured_length(tvb);
+ }
+ if (field_data->isDMG == TRUE && tag_len != 57)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 57", tag_len);
+ return tvb_captured_length(tvb);
+ }
- proto_tree_add_item(tree, hf_ieee80211_tspec_nor_msdu, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
+ add_ff_qos_ts_info(tree, tvb, pinfo, offset);
+ offset += 3;
- proto_tree_add_item(tree, hf_ieee80211_tspec_max_msdu, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
+ proto_tree_add_item(tree, hf_ieee80211_tspec_nor_msdu, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tspec_min_srv, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
+ proto_tree_add_item(tree, hf_ieee80211_tspec_max_msdu, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tspec_max_srv, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
+ proto_tree_add_item(tree, hf_ieee80211_tspec_min_srv, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
- proto_tree_add_item(tree, hf_ieee80211_tspec_inact_int, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
+ proto_tree_add_item(tree, hf_ieee80211_tspec_max_srv, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
- proto_tree_add_item(tree, hf_ieee80211_tspec_susp_int, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
+ proto_tree_add_item(tree, hf_ieee80211_tspec_inact_int, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
- proto_tree_add_item(tree, hf_ieee80211_tspec_srv_start, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
+ proto_tree_add_item(tree, hf_ieee80211_tspec_susp_int, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
- proto_tree_add_item(tree, hf_ieee80211_tspec_min_data, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
+ proto_tree_add_item(tree, hf_ieee80211_tspec_srv_start, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
- proto_tree_add_item(tree, hf_ieee80211_tspec_mean_data, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
+ proto_tree_add_item(tree, hf_ieee80211_tspec_min_data, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
- proto_tree_add_item(tree, hf_ieee80211_tspec_peak_data, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
+ proto_tree_add_item(tree, hf_ieee80211_tspec_mean_data, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
- proto_tree_add_item(tree, hf_ieee80211_tspec_burst_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
+ proto_tree_add_item(tree, hf_ieee80211_tspec_peak_data, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
- proto_tree_add_item(tree, hf_ieee80211_tspec_delay_bound, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
+ proto_tree_add_item(tree, hf_ieee80211_tspec_burst_size, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
- proto_tree_add_item(tree, hf_ieee80211_tspec_min_phy, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
+ proto_tree_add_item(tree, hf_ieee80211_tspec_delay_bound, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
- proto_tree_add_item(tree, hf_ieee80211_tspec_surplus, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
+ proto_tree_add_item(tree, hf_ieee80211_tspec_min_phy, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
- proto_tree_add_item(tree, hf_ieee80211_tspec_medium, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
+ proto_tree_add_item(tree, hf_ieee80211_tspec_surplus, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
- if(isDMG == TRUE) {
- proto_tree_add_item(tree, hf_ieee80211_tspec_dmg, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset +=2;
- }
+ proto_tree_add_item(tree, hf_ieee80211_tspec_medium, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
- break;
+ if(field_data->isDMG == TRUE) {
+ proto_tree_add_item(tree, hf_ieee80211_tspec_dmg, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ /*offset +=2;*/
+ }
- case TAG_TCLAS: /* 7.3.2.31 TCLAS element (14) */
- if (tag_len < 6)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag length %u too short, must be >= 6", tag_len);
- break;
- }
- {
- guint8 type;
- guint8 version;
- proto_item *class_mask;
- proto_tree *mask_tree;
+ return tvb_captured_length(tvb);
+}
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tclas_up, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- offset += 1;
+/* 7.3.2.31 TCLAS element (14) */
+static int
+ieee80211_tag_tclas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ guint8 type;
+ guint8 version;
+ proto_item *class_mask;
+ proto_tree *mask_tree;
+ if (tag_len < 6)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag length %u too short, must be >= 6", tag_len);
+ return 1;
+ }
- type = tvb_get_guint8(tvb, offset);
- proto_tree_add_item(tree, hf_ieee80211_tclas_class_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_tclas_up, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
+
+ type = tvb_get_guint8(tvb, offset);
+ proto_tree_add_item(tree, hf_ieee80211_tclas_class_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
- class_mask = proto_tree_add_item(tree, hf_ieee80211_tclas_class_mask,
+ class_mask = proto_tree_add_item(tree, hf_ieee80211_tclas_class_mask,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
- offset += 1;
+ offset += 1;
- switch (type)
- {
- case 0:
- offset--;
- mask_tree = proto_item_add_subtree(class_mask,
- ett_tag_tclas_mask_tree);
- proto_tree_add_item(mask_tree,
- hf_ieee80211_tclas_class_mask0_src_addr,
+ switch (type)
+ {
+ case 0:
+ offset--;
+ mask_tree = proto_item_add_subtree(class_mask, ett_tag_tclas_mask_tree);
+ proto_tree_add_item(mask_tree, hf_ieee80211_tclas_class_mask0_src_addr,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(mask_tree,
- hf_ieee80211_tclas_class_mask0_dst_addr,
+ proto_tree_add_item(mask_tree, hf_ieee80211_tclas_class_mask0_dst_addr,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(mask_tree,
- hf_ieee80211_tclas_class_mask0_type,
+ proto_tree_add_item(mask_tree, hf_ieee80211_tclas_class_mask0_type,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
- offset++;
+ offset++;
- proto_tree_add_item(tree, hf_ieee80211_tclas_src_mac_addr, tvb, offset, 6, ENC_NA);
- offset += 6;
+ proto_tree_add_item(tree, hf_ieee80211_tclas_src_mac_addr, tvb, offset, 6, ENC_NA);
+ offset += 6;
- proto_tree_add_item(tree, hf_ieee80211_tclas_dst_mac_addr, tvb, offset, 6, ENC_NA);
- offset += 6;
+ proto_tree_add_item(tree, hf_ieee80211_tclas_dst_mac_addr, tvb, offset, 6, ENC_NA);
+ offset += 6;
- proto_tree_add_item(tree, hf_ieee80211_tclas_ether_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- break;
+ proto_tree_add_item(tree, hf_ieee80211_tclas_ether_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ /*offset += 2;*/
+ break;
- case 1:
- version = tvb_get_guint8(tvb, offset);
- offset--;
+ case 1:
+ version = tvb_get_guint8(tvb, offset);
+ offset--;
- mask_tree = proto_item_add_subtree(class_mask,
- ett_tag_tclas_mask_tree);
- proto_tree_add_item(mask_tree,
- hf_ieee80211_tclas_class_mask1_ver,
- tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(mask_tree,
- hf_ieee80211_tclas_class_mask1_src_ip,
- tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(mask_tree,
- hf_ieee80211_tclas_class_mask1_dst_ip,
- tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(mask_tree,
- hf_ieee80211_tclas_class_mask1_src_port,
+ mask_tree = proto_item_add_subtree(class_mask, ett_tag_tclas_mask_tree);
+ proto_tree_add_item(mask_tree, hf_ieee80211_tclas_class_mask1_ver,
+ tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(mask_tree, hf_ieee80211_tclas_class_mask1_src_ip,
+ tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(mask_tree, hf_ieee80211_tclas_class_mask1_dst_ip,
+ tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(mask_tree, hf_ieee80211_tclas_class_mask1_src_port,
+ tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(mask_tree, hf_ieee80211_tclas_class_mask1_dst_port,
+ tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ if (version == 4) {
+ proto_tree_add_item(mask_tree, hf_ieee80211_tclas_class_mask1_ipv4_dscp,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(mask_tree,
- hf_ieee80211_tclas_class_mask1_dst_port,
+ proto_tree_add_item(mask_tree, hf_ieee80211_tclas_class_mask1_ipv4_proto,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
- if (version == 4) {
- proto_tree_add_item(mask_tree,
- hf_ieee80211_tclas_class_mask1_ipv4_dscp,
- tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(mask_tree,
- hf_ieee80211_tclas_class_mask1_ipv4_proto,
- tvb, offset, 1, ENC_LITTLE_ENDIAN);
- } else {
- proto_tree_add_item(mask_tree,
- hf_ieee80211_tclas_class_mask1_ipv6_flow,
- tvb, offset, 1, ENC_LITTLE_ENDIAN);
- }
- offset += 1;
-
- proto_tree_add_item(tree, hf_ieee80211_tclas_version, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- offset += 1;
- if (version == 4)
- {
- proto_tree_add_item(tree, hf_ieee80211_tclas_ipv4_src, tvb, offset, 4, ENC_BIG_ENDIAN);
- offset += 4;
- proto_tree_add_item(tree, hf_ieee80211_tclas_ipv4_dst, tvb, offset, 4, ENC_BIG_ENDIAN);
- offset += 4;
- proto_tree_add_item(tree, hf_ieee80211_tclas_src_port, tvb, offset, 2, ENC_BIG_ENDIAN);
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tclas_dst_port, tvb, offset, 2, ENC_BIG_ENDIAN);
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tclas_dscp, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_tclas_protocol, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- offset += 1;
- }
- else if (version == 6)
- {
- proto_tree_add_item(tree, hf_ieee80211_tclas_ipv6_src, tvb, offset, 16, ENC_NA);
- offset += 16;
- proto_tree_add_item(tree, hf_ieee80211_tclas_ipv6_dst, tvb, offset, 16, ENC_NA);
- offset += 16;
- proto_tree_add_item(tree, hf_ieee80211_tclas_src_port, tvb, offset, 2, ENC_BIG_ENDIAN);
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tclas_dst_port, tvb, offset, 2, ENC_BIG_ENDIAN);
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tclas_flow, tvb, offset, 3, ENC_BIG_ENDIAN);
- offset += 3;
- }
- break;
-
- case 2:
- offset--;
- mask_tree = proto_item_add_subtree(class_mask,
- ett_tag_tclas_mask_tree);
- proto_tree_add_item(mask_tree,
- hf_ieee80211_tclas_class_mask2_tci,
+ } else {
+ proto_tree_add_item(mask_tree, hf_ieee80211_tclas_class_mask1_ipv6_flow,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
- offset++;
-
- proto_tree_add_item(tree, hf_ieee80211_tclas_tag_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- break;
-
- default:
- break;
- }
- }
- break;
-
- case TAG_SCHEDULE: /* 7.3.2.34 Schedule element (15) */
- if (tag_len != 14)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 14", tag_len);
- break;
- }
- offset += 2;
-
- add_ff_schedule_info(tree, tvb, pinfo, offset);
- offset += 2;
+ }
+ offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_sched_srv_start, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tclas_version, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
+ if (version == 4)
+ {
+ proto_tree_add_item(tree, hf_ieee80211_tclas_ipv4_src, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
-
- proto_tree_add_item(tree, hf_ieee80211_sched_srv_int, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tclas_ipv4_dst, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
-
- proto_tree_add_item(tree, hf_ieee80211_sched_spec_int, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- break;
-
- case TAG_CHALLENGE_TEXT: /* 7.3.2.8 Challenge Text element (16) */
+ proto_tree_add_item(tree, hf_ieee80211_tclas_src_port, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_challenge_text, tvb, offset, tag_len, ENC_NA);
- break;
-
- case TAG_POWER_CONSTRAINT: /* 7.3.2.15 Power Constraint element (32) */
- {
- if (tag_len != 1)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 1", tag_len);
- break;
- }
+ proto_tree_add_item(tree, hf_ieee80211_tclas_dst_port, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
-
- proto_tree_add_item(tree, hf_ieee80211_tag_power_constraint_local, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_item_append_text(ti, ": %d", tvb_get_guint8(tvb, offset));
+ proto_tree_add_item(tree, hf_ieee80211_tclas_dscp, tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
-
- break;
+ proto_tree_add_item(tree, hf_ieee80211_tclas_protocol, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ /*offset += 1;*/
}
-
- case TAG_POWER_CAPABILITY: /* 7.3.2.16 Power Capability element (33) */
+ else if (version == 6)
{
- if (tag_len != 2)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 2", tag_len);
- break;
- }
+ proto_tree_add_item(tree, hf_ieee80211_tclas_ipv6_src, tvb, offset, 16, ENC_NA);
+ offset += 16;
+ proto_tree_add_item(tree, hf_ieee80211_tclas_ipv6_dst, tvb, offset, 16, ENC_NA);
+ offset += 16;
+ proto_tree_add_item(tree, hf_ieee80211_tclas_src_port, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
+ proto_tree_add_item(tree, hf_ieee80211_tclas_dst_port, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(tree, hf_ieee80211_tclas_flow, tvb, offset, 3, ENC_BIG_ENDIAN);
+ /*offset += 3;*/
+ }
+ break;
- proto_tree_add_item(tree, hf_ieee80211_tag_power_capability_min, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_item_append_text(ti, " Min: %d", tvb_get_guint8(tvb, offset));
- offset += 1;
+ case 2:
+ offset--;
+ mask_tree = proto_item_add_subtree(class_mask, ett_tag_tclas_mask_tree);
+ proto_tree_add_item(mask_tree, hf_ieee80211_tclas_class_mask2_tci,
+ tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset++;
- proto_tree_add_item(tree, hf_ieee80211_tag_power_capability_max, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_item_append_text(ti, ", Max :%d", tvb_get_guint8(tvb, offset));
- offset += 1;
- break;
- }
+ proto_tree_add_item(tree, hf_ieee80211_tclas_tag_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ /*offset += 2;*/
+ break;
- case TAG_TPC_REQUEST: /* 7.3.2.18 TPC Request element (34) */
- {
- if (tag_len != 0)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 0", tag_len);
- break;
- }
- offset += 2;
+ default:
+ break;
+ }
- /* No Data */
- break;
- }
+ return tvb_captured_length(tvb);
+}
- case TAG_TPC_REPORT: /* 7.3.2.18 TPC Report element (35) */
- {
- if (tag_len != 2)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 2", tag_len);
- break;
- }
- offset += 2;
+/* 7.3.2.34 Schedule element (15) */
+static int
+ieee80211_tag_schedule(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ if (tag_len != 14)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 14", tag_len);
+ return 1;
+ }
- proto_tree_add_item(tree, hf_ieee80211_tag_tpc_report_trsmt_pow, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_item_append_text(ti, " Transmit Power: %d", tvb_get_guint8(tvb, offset));
- offset += 1;
+ add_ff_schedule_info(tree, tvb, pinfo, offset);
+ offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_tpc_report_link_mrg, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_item_append_text(ti, ", Link Margin: %d", tvb_get_guint8(tvb, offset));
- offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_sched_srv_start, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
- break;
- }
+ proto_tree_add_item(tree, hf_ieee80211_sched_srv_int, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
- case TAG_SUPPORTED_CHANNELS: /* 7.3.2.19 Supported Channels element (36) */
- {
- proto_item *chan_item;
- proto_tree *chan_tree;
- guint i = 1;
+ proto_tree_add_item(tree, hf_ieee80211_sched_spec_int, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ return tvb_captured_length(tvb);
+}
- offset += 2;
- if (tag_len % 2 == 1) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag length %u must be even", tag_len);
- break;
- }
- while (offset < tag_end)
- {
- chan_item = proto_tree_add_item(tree, hf_ieee80211_tag_supported_channels, tvb, offset, 2, ENC_NA);
- proto_item_append_text(chan_item, " #%d", i);
- i += 1;
+/* 7.3.2.8 Challenge Text element (16) */
+static int
+ieee80211_tag_challenge_text(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
+{
+ int tag_len = tvb_reported_length(tvb);
+ int offset = 0;
- chan_tree = proto_item_add_subtree(chan_item , ett_tag_supported_channels);
+ proto_tree_add_item(tree, hf_ieee80211_tag_challenge_text, tvb, offset, tag_len, ENC_NA);
- proto_tree_add_item(chan_tree, hf_ieee80211_tag_supported_channels_first, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_item_append_text(chan_item, " First: %d", tvb_get_guint8(tvb, offset));
- offset += 1;
+ return ((tag_len > 0) ? tag_len : 1);
+}
- proto_tree_add_item(chan_tree, hf_ieee80211_tag_supported_channels_range, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_item_append_text(chan_item, ", Range: %d ", tvb_get_guint8(tvb, offset));
- offset += 1;
+/* 7.3.2.15 Power Constraint element (32) */
+static int
+ieee80211_tag_power_constraint(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ if (tag_len != 1)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 1", tag_len);
+ return 1;
+ }
- }
- break;
- }
- case TAG_CHANNEL_SWITCH_ANN: /* 7.3.2.20 Channel Switch Announcement element (37) */
- {
- if (tag_len != 3)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 3", tag_len);
- break;
- }
- offset += 2;
+ proto_tree_add_item(tree, hf_ieee80211_tag_power_constraint_local, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(field_data->item_tag, ": %d", tvb_get_guint8(tvb, offset));
+ return tvb_captured_length(tvb);
+}
- proto_tree_add_item(tree, hf_ieee80211_csa_channel_switch_mode, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_item_append_text(ti, " Mode: %d", tvb_get_guint8(tvb, offset));
- offset += 1;
+/* 7.3.2.16 Power Capability element (33) */
+static int
+ieee80211_tag_power_capability(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ if (tag_len != 2)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 2", tag_len);
+ return 1;
+ }
- proto_tree_add_item(tree, hf_ieee80211_csa_new_channel_number, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_item_append_text(ti, ", Number: %d ", tvb_get_guint8(tvb, offset));
- offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_power_capability_min, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(field_data->item_tag, " Min: %d", tvb_get_guint8(tvb, offset));
+ offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_csa_channel_switch_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_item_append_text(ti, ", Count: %d ", tvb_get_guint8(tvb, offset));
- offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_power_capability_max, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(field_data->item_tag, ", Max :%d", tvb_get_guint8(tvb, offset));
+ return tvb_captured_length(tvb);
+}
- break;
- }
+/* 7.3.2.18 TPC Request element (34) */
+static int
+ieee80211_tag_tpc_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ if (tag_len != 0)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 0", tag_len);
+ return 1; /* Even with no data, we can't return 0 */
+ }
- case TAG_MEASURE_REQ: /* 7.3.2.21 Measurement Request element (38) with update from 802.11k-2008 */
- if (tag_len < 3)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag length %u too short, must be >= 3", tag_len);
- break;
- }
- {
- guint8 request_type;
- proto_item *parent_item;
- proto_tree *sub_tree;
+ return 1; /* Even with no data, we can't return 0 */
+}
- offset += 2;
+/* 7.3.2.18 TPC Report element (35) */
+static int
+ieee80211_tag_tpc_report(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
- proto_tree_add_item(tree, hf_ieee80211_tag_measure_request_token, tvb, offset, 1, ENC_NA);
- offset += 1;
+ if (tag_len != 2)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 2", tag_len);
+ return 1;
+ }
- parent_item = proto_tree_add_item(tree, hf_ieee80211_tag_measure_request_mode, tvb, offset, 1, ENC_NA);
- sub_tree = proto_item_add_subtree(parent_item, ett_tag_measure_request_mode_tree);
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_mode_parallel, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_mode_enable, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_mode_request, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_mode_report, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_mode_duration_mandatory, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_mode_reserved, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_tpc_report_trsmt_pow, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(field_data->item_tag, " Transmit Power: %d", tvb_get_guint8(tvb, offset));
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_tpc_report_link_mrg, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(field_data->item_tag, ", Link Margin: %d", tvb_get_guint8(tvb, offset));
+ return tvb_captured_length(tvb);
+}
- parent_item = proto_tree_add_item(tree, hf_ieee80211_tag_measure_request_type, tvb, offset, 1, ENC_NA);
- sub_tree = proto_item_add_subtree(parent_item, ett_tag_measure_request_type_tree);
- request_type = tvb_get_guint8(tvb, offset);
- offset += 1;
+/* 7.3.2.19 Supported Channels element (36) */
+static int
+ieee80211_tag_supported_channels(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
- switch (request_type) {
- case 0: /* Basic Request */
- case 1: /* Clear channel assessment (CCA) request */
- case 2: /* Receive power indication (RPI) histogram request */
- {
+ proto_item *chan_item;
+ proto_tree *chan_tree;
+ guint i = 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_channel_number, tvb, offset, 1, ENC_NA);
- offset += 1;
+ if (tag_len % 2 == 1) {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag length %u must be even", tag_len);
+ return tvb_captured_length(tvb);
+ }
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_start_time, tvb, offset, 8, ENC_LITTLE_ENDIAN);
- offset += 8;
+ while (offset < tag_len)
+ {
+ chan_item = proto_tree_add_item(tree, hf_ieee80211_tag_supported_channels, tvb, offset, 2, ENC_NA);
+ proto_item_append_text(chan_item, " #%d", i);
+ i += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- break;
- }
- case 3: /* Channel Load Request */
- {
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_operating_class, tvb, offset, 1, ENC_NA);
- offset += 1;
+ chan_tree = proto_item_add_subtree(chan_item , ett_tag_supported_channels);
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_channel_number, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(chan_tree, hf_ieee80211_tag_supported_channels_first, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(chan_item, " First: %d", tvb_get_guint8(tvb, offset));
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_randomization_interval, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
+ proto_tree_add_item(chan_tree, hf_ieee80211_tag_supported_channels_range, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(chan_item, ", Range: %d ", tvb_get_guint8(tvb, offset));
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
+ }
+ return tvb_captured_length(tvb);
+}
- while (offset < tag_end)
- {
- guint8 sub_id;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_channel_load_sub_id, tvb, offset, 1, ENC_NA);
- sub_id = tvb_get_guint8(tvb, offset);
- offset += 1;
+/* 7.3.2.20 Channel Switch Announcement element (37) */
+static int
+ieee80211_tag_switch_ann(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ if (tag_len != 3)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 3", tag_len);
+ return 1;
+ }
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_subelement_length, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_csa_channel_switch_mode, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(field_data->item_tag, " Mode: %d", tvb_get_guint8(tvb, offset));
+ offset += 1;
- switch (sub_id) {
- case MEASURE_REQ_CHANNEL_LOAD_SUB_REPORTING_INFO: /* Channel Load Reporting Information (1) */
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_channel_load_sub_reporting_condition, tvb, offset, 1, ENC_NA);
- offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_channel_load_sub_reporting_ref, tvb, offset, 1, ENC_NA);
- offset += 1;
- break;
- default:
- /* no default action */
- break;
- }
- }
- break;
- }
- case 4: /* Noise Histogram Request */
- {
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_operating_class, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_csa_new_channel_number, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(field_data->item_tag, ", Number: %d ", tvb_get_guint8(tvb, offset));
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_channel_number, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_csa_channel_switch_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(field_data->item_tag, ", Count: %d ", tvb_get_guint8(tvb, offset));
+ return tvb_captured_length(tvb);
+}
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_randomization_interval, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
+/* 7.3.2.21 Measurement Request element (38) with update from 802.11k-2008 */
+static int
+ieee80211_tag_measure_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ guint8 request_type;
+ proto_item *parent_item;
+ proto_tree *sub_tree;
+ if (tag_len < 3)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag length %u too short, must be >= 3", tag_len);
+ return tvb_captured_length(tvb);
+ }
+ proto_tree_add_item(tree, hf_ieee80211_tag_measure_request_token, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
+ parent_item = proto_tree_add_item(tree, hf_ieee80211_tag_measure_request_mode, tvb, offset, 1, ENC_NA);
+ sub_tree = proto_item_add_subtree(parent_item, ett_tag_measure_request_mode_tree);
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_mode_parallel, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_mode_enable, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_mode_request, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_mode_report, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_mode_duration_mandatory, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_mode_reserved, tvb, offset, 1, ENC_NA);
+ offset += 1;
- while (offset < tag_end)
- {
- guint8 sub_id;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_noise_histogram_sub_id, tvb, offset, 1, ENC_NA);
- sub_id = tvb_get_guint8(tvb, offset);
- offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_subelement_length, tvb, offset, 1, ENC_NA);
- offset += 1;
+ parent_item = proto_tree_add_item(tree, hf_ieee80211_tag_measure_request_type, tvb, offset, 1, ENC_NA);
+ sub_tree = proto_item_add_subtree(parent_item, ett_tag_measure_request_type_tree);
+ request_type = tvb_get_guint8(tvb, offset);
+ offset += 1;
- switch (sub_id) {
- case MEASURE_REQ_NOISE_HISTOGRAM_SUB_REPORTING_INFO: /* Noise Histogram Reporting Information (1) */
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_noise_histogram_sub_reporting_condition, tvb, offset, 1, ENC_NA);
- offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_noise_histogram_sub_reporting_anpi_ref, tvb, offset, 1, ENC_NA);
- offset += 1;
- break;
- default:
- /* no default action */
- break;
- }
- }
- break;
- }
- case 5: /* Beacon Request */
- {
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_operating_class, tvb, offset, 1, ENC_NA);
- offset += 1;
+ switch (request_type) {
+ case 0: /* Basic Request */
+ case 1: /* Clear channel assessment (CCA) request */
+ case 2: /* Receive power indication (RPI) histogram request */
+ {
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_channel_number, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_channel_number, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_start_time, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ offset += 8;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_randomization_interval, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ break;
+ }
+ case 3: /* Channel Load Request */
+ {
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_operating_class, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_channel_number, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_measurement_mode, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_randomization_interval, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_bssid, tvb, offset, 6, ENC_NA);
- offset += 6;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
- while (offset < tag_end)
- {
- guint8 sub_id, sub_length, sub_tag_end;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_beacon_sub_id, tvb, offset, 1, ENC_NA);
- sub_id = tvb_get_guint8(tvb, offset);
- offset += 1;
+ while (offset < tag_len)
+ {
+ guint8 sub_id;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_channel_load_sub_id, tvb, offset, 1, ENC_NA);
+ sub_id = tvb_get_guint8(tvb, offset);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_subelement_length, tvb, offset, 1, ENC_NA);
- sub_length = tvb_get_guint8(tvb, offset);
- offset += 1;
- sub_tag_end = offset + sub_length;
-
- switch (sub_id) {
- case MEASURE_REQ_BEACON_SUB_SSID: /* SSID (0) */
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_beacon_sub_ssid, tvb, offset, sub_length, ENC_ASCII|ENC_NA);
- offset += sub_length;
- break;
- case MEASURE_REQ_BEACON_SUB_BRI: /* Beacon Reporting Information (1) */
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_beacon_sub_bri_reporting_condition, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_beacon_sub_bri_threshold_offset, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- offset += 1;
- break;
- case MEASURE_REQ_BEACON_SUB_RD: /* Reporting Detail (2) */
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_beacon_sub_reporting_detail, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- offset += 1;
- break;
- case MEASURE_REQ_BEACON_SUB_REQUEST: /* Request (10) */
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_beacon_sub_request, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- offset += 1;
- break;
- case MEASURE_REQ_BEACON_SUB_APCP: /* AP Channel Report (51) */
- /* TODO */
- break;
- default:
- /* no default action */
- break;
- }
- if (offset < sub_tag_end)
- {
- proto_item *tix;
- tix = proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_beacon_unknown, tvb, offset, sub_tag_end - offset, ENC_NA);
- expert_add_info(pinfo, tix, &ei_ieee80211_tag_measure_request_beacon_unknown);
- offset = sub_tag_end;
- }
- }
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_subelement_length, tvb, offset, 1, ENC_NA);
+ offset += 1;
- break;
- }
- case 6: /* Frame Request */
- {
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_operating_class, tvb, offset, 1, ENC_NA);
+ switch (sub_id) {
+ case MEASURE_REQ_CHANNEL_LOAD_SUB_REPORTING_INFO: /* Channel Load Reporting Information (1) */
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_channel_load_sub_reporting_condition, tvb, offset, 1, ENC_NA);
offset += 1;
-
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_channel_number, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_channel_load_sub_reporting_ref, tvb, offset, 1, ENC_NA);
offset += 1;
+ break;
+ default:
+ /* no default action */
+ break;
+ }
+ }
+ break;
+ }
+ case 4: /* Noise Histogram Request */
+ {
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_operating_class, tvb, offset, 1, ENC_NA);
+ offset += 1;
+
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_channel_number, tvb, offset, 1, ENC_NA);
+ offset += 1;
+
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_randomization_interval, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+
+ while (offset < tag_len)
+ {
+ guint8 sub_id;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_noise_histogram_sub_id, tvb, offset, 1, ENC_NA);
+ sub_id = tvb_get_guint8(tvb, offset);
+ offset += 1;
+
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_subelement_length, tvb, offset, 1, ENC_NA);
+ offset += 1;
+
+ switch (sub_id) {
+ case MEASURE_REQ_NOISE_HISTOGRAM_SUB_REPORTING_INFO: /* Noise Histogram Reporting Information (1) */
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_noise_histogram_sub_reporting_condition, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_noise_histogram_sub_reporting_anpi_ref, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ break;
+ default:
+ /* no default action */
+ break;
+ }
+ }
+ break;
+ }
+ case 5: /* Beacon Request */
+ {
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_operating_class, tvb, offset, 1, ENC_NA);
+ offset += 1;
+
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_channel_number, tvb, offset, 1, ENC_NA);
+ offset += 1;
+
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_randomization_interval, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_measurement_mode, tvb, offset, 1, ENC_NA);
+ offset += 1;
+
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_bssid, tvb, offset, 6, ENC_NA);
+ offset += 6;
+
+ while (offset < tag_len)
+ {
+ guint8 sub_id, sub_length, sub_tag_end;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_beacon_sub_id, tvb, offset, 1, ENC_NA);
+ sub_id = tvb_get_guint8(tvb, offset);
+ offset += 1;
+
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_subelement_length, tvb, offset, 1, ENC_NA);
+ sub_length = tvb_get_guint8(tvb, offset);
+ offset += 1;
+ sub_tag_end = offset + sub_length;
+
+ switch (sub_id) {
+ case MEASURE_REQ_BEACON_SUB_SSID: /* SSID (0) */
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_beacon_sub_ssid, tvb, offset, sub_length, ENC_ASCII|ENC_NA);
+ offset += sub_length;
+ break;
+ case MEASURE_REQ_BEACON_SUB_BRI: /* Beacon Reporting Information (1) */
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_beacon_sub_bri_reporting_condition, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_beacon_sub_bri_threshold_offset, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
+ break;
+ case MEASURE_REQ_BEACON_SUB_RD: /* Reporting Detail (2) */
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_beacon_sub_reporting_detail, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
+ break;
+ case MEASURE_REQ_BEACON_SUB_REQUEST: /* Request (10) */
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_beacon_sub_request, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
+ break;
+ case MEASURE_REQ_BEACON_SUB_APCP: /* AP Channel Report (51) */
+ /* TODO */
+ break;
+ default:
+ /* no default action */
+ break;
+ }
+ if (offset < sub_tag_end)
+ {
+ proto_item *tix;
+ tix = proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_beacon_unknown, tvb, offset, sub_tag_end - offset, ENC_NA);
+ expert_add_info(pinfo, tix, &ei_ieee80211_tag_measure_request_beacon_unknown);
+ offset = sub_tag_end;
+ }
+ }
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_randomization_interval, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
+ break;
+ }
+ case 6: /* Frame Request */
+ {
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_operating_class, tvb, offset, 1, ENC_NA);
+ offset += 1;
+
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_channel_number, tvb, offset, 1, ENC_NA);
+ offset += 1;
+
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_randomization_interval, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_frame_request_type, tvb, offset, 1, ENC_NA);
+ offset += 1;
+
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_mac_address, tvb, offset, 6, ENC_NA);
+ offset += 6;
+
+ /* TODO Add Optional Subelements */
+ break;
+ }
+ case 7: /* BSTA Statistics Request */
+ {
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_peer_mac_address, tvb, offset, 6, ENC_NA);
+ offset += 6;
+
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_randomization_interval, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_group_id, tvb, offset, 1, ENC_NA);
+ offset += 1;
+
+ /* TODO Add Optional Subelements */
+ break;
+ }
+ case 8: /* Location Configuration Indication (LCI) Request */
+ /* TODO */
+ case 9: /* Transmit Stream Measurement Request */
+ /* TODO */
+ case 10: /* Multicast diagnostics request */
+ /* TODO */
+ case 11: /* Location Civic request */
+ /* TODO */
+ case 12: /* Location Identifier request */
+ /* TODO */
+ case 13: /* Directional channel quality request */
+ /* TODO */
+ case 14: /* Directional measurement request */
+ /* TODO */
+ case 15: /* Directional statistics request */
+ /* TODO */
+ case 255: /* Measurement Pause Request*/
+ /* TODO */
+ default: /* unknown */
+ break;
+ }
+ if (offset < tag_len)
+ {
+ proto_item *tix;
+ tix = proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_unknown, tvb, offset, tag_len - offset, ENC_NA);
+ expert_add_info(pinfo, tix, &ei_ieee80211_tag_measure_request_unknown);
+ }
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
+ return tvb_captured_length(tvb);
+}
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_frame_request_type, tvb, offset, 1, ENC_NA);
- offset += 1;
+/* 7.3.2.22 Measurement Report element (39) with update from 802.11k-2008 */
+static int
+ieee80211_tag_measure_rep(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ proto_item *parent_item;
+ proto_tree *sub_tree;
+ guint8 report_type;
+ if (tag_len < 3)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag length %u too short, must be >= 3", tag_len);
+ return tvb_captured_length(tvb);
+ }
+ proto_tree_add_item(tree, hf_ieee80211_tag_measure_report_measurement_token, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_mac_address, tvb, offset, 6, ENC_NA);
- offset += 6;
+ parent_item = proto_tree_add_item(tree, hf_ieee80211_tag_measure_report_mode, tvb, offset, 1, ENC_NA);
+ sub_tree = proto_item_add_subtree(parent_item, ett_tag_measure_report_mode_tree);
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_mode_late, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_mode_incapable, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_mode_refused, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_mode_reserved, tvb, offset, 1, ENC_NA);
+ offset += 1;
- /* TODO Add Optional Subelements */
- break;
- }
- case 7: /* BSTA Statistics Request */
- {
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_peer_mac_address, tvb, offset, 6, ENC_NA);
- offset += 6;
+ report_type = tvb_get_guint8(tvb, offset);
+ parent_item = proto_tree_add_item(tree, hf_ieee80211_tag_measure_report_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ sub_tree = proto_item_add_subtree(parent_item, ett_tag_measure_report_type_tree);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_randomization_interval, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
+ if (tag_len == 3)
+ return tvb_captured_length(tvb);
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
+ switch (report_type) {
+ case 0: /* Basic Report */
+ {
+ proto_tree *sub_tree_map_field;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_group_id, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_channel_number, tvb, offset, 1, ENC_NA);
+ offset += 1;
- /* TODO Add Optional Subelements */
- break;
- }
- case 8: /* Location Configuration Indication (LCI) Request */
- /* TODO */
- case 9: /* Transmit Stream Measurement Request */
- /* TODO */
- case 10: /* Multicast diagnostics request */
- /* TODO */
- case 11: /* Location Civic request */
- /* TODO */
- case 12: /* Location Identifier request */
- /* TODO */
- case 13: /* Directional channel quality request */
- /* TODO */
- case 14: /* Directional measurement request */
- /* TODO */
- case 15: /* Directional statistics request */
- /* TODO */
- case 255: /* Measurement Pause Request*/
- /* TODO */
- default: /* unknown */
- break;
- }
- if (offset < tag_end)
- {
- proto_item *tix;
- tix = proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_request_unknown, tvb, offset, tag_end - offset, ENC_NA);
- expert_add_info(pinfo, tix, &ei_ieee80211_tag_measure_request_unknown);
- }
- }
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_start_time, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ offset += 8;
- break;
- case TAG_MEASURE_REP: /* 7.3.2.22 Measurement Report element (39) with update from 802.11k-2008 */
- if (tag_len < 3)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag length %u too short, must be >= 3", tag_len);
- break;
- }
- {
- proto_item *parent_item;
- proto_tree *sub_tree;
- guint8 report_type;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_measure_report_measurement_token, tvb, offset, 1, ENC_NA);
- offset += 1;
+ parent_item = proto_tree_add_item(tree, hf_ieee80211_tag_measure_basic_map_field, tvb, offset, 1, ENC_NA);
+ sub_tree_map_field = proto_item_add_subtree(parent_item, ett_tag_measure_report_basic_map_tree);
+ proto_tree_add_item(sub_tree_map_field, hf_ieee80211_tag_measure_map_field_bss, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(sub_tree_map_field, hf_ieee80211_tag_measure_map_field_odfm, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(sub_tree_map_field, hf_ieee80211_tag_measure_map_field_unident_signal, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(sub_tree_map_field, hf_ieee80211_tag_measure_map_field_radar, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(sub_tree_map_field, hf_ieee80211_tag_measure_map_field_unmeasured, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(sub_tree_map_field, hf_ieee80211_tag_measure_map_field_reserved, tvb, offset, 1, ENC_NA);
+ break;
+ }
+ case 1: /* Clear channel assessment (CCA) report */
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_channel_number, tvb, offset, 1, ENC_NA);
+ offset += 1;
- parent_item = proto_tree_add_item(tree, hf_ieee80211_tag_measure_report_mode, tvb, offset, 1, ENC_NA);
- sub_tree = proto_item_add_subtree(parent_item, ett_tag_measure_report_mode_tree);
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_mode_late, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_mode_incapable, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_mode_refused, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_mode_reserved, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_start_time, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ offset += 8;
- report_type = tvb_get_guint8(tvb, offset);
- parent_item = proto_tree_add_item(tree, hf_ieee80211_tag_measure_report_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- sub_tree = proto_item_add_subtree(parent_item, ett_tag_measure_report_type_tree);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
- if (tag_len == 3)
- break;
- switch (report_type) {
- case 0: /* Basic Report */
- {
- proto_tree *sub_tree_map_field;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_cca_busy_fraction, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ break;
+ case 2: /* Receive power indication (RPI) histogram report */
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_channel_number, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_channel_number, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_start_time, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ offset += 8;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_start_time, tvb, offset, 8, ENC_LITTLE_ENDIAN);
- offset += 8;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
+ parent_item = proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_rpi_histogram_report, tvb, offset, 8, ENC_NA);
+ sub_tree = proto_item_add_subtree(parent_item, ett_tag_measure_report_rpi_tree);
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_rpi_histogram_report_0, tvb, offset, 1, ENC_NA);
+ offset += 1;
- parent_item = proto_tree_add_item(tree, hf_ieee80211_tag_measure_basic_map_field, tvb, offset, 1, ENC_NA);
- sub_tree_map_field = proto_item_add_subtree(parent_item, ett_tag_measure_report_basic_map_tree);
- proto_tree_add_item(sub_tree_map_field, hf_ieee80211_tag_measure_map_field_bss, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(sub_tree_map_field, hf_ieee80211_tag_measure_map_field_odfm, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(sub_tree_map_field, hf_ieee80211_tag_measure_map_field_unident_signal, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(sub_tree_map_field, hf_ieee80211_tag_measure_map_field_radar, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(sub_tree_map_field, hf_ieee80211_tag_measure_map_field_unmeasured, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(sub_tree_map_field, hf_ieee80211_tag_measure_map_field_reserved, tvb, offset, 1, ENC_NA);
- break;
- }
- case 1: /* Clear channel assessment (CCA) report */
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_channel_number, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_rpi_histogram_report_1, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_start_time, tvb, offset, 8, ENC_LITTLE_ENDIAN);
- offset += 8;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_rpi_histogram_report_2, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_rpi_histogram_report_3, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_cca_busy_fraction, tvb, offset, 1, ENC_NA);
- offset += 1;
- break;
- case 2: /* Receive power indication (RPI) histogram report */
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_channel_number, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_rpi_histogram_report_4, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_start_time, tvb, offset, 8, ENC_LITTLE_ENDIAN);
- offset += 8;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_rpi_histogram_report_5, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_rpi_histogram_report_6, tvb, offset, 1, ENC_NA);
+ offset += 1;
- parent_item = proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_rpi_histogram_report, tvb, offset, 8, ENC_NA);
- sub_tree = proto_item_add_subtree(parent_item, ett_tag_measure_report_rpi_tree);
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_rpi_histogram_report_7, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ break;
+ case 3: /* Channel Load Report */
+ {
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_operating_class, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_rpi_histogram_report_0, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_channel_number, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_rpi_histogram_report_1, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_start_time, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ offset += 8;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_rpi_histogram_report_2, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_rpi_histogram_report_3, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_channel_load, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_rpi_histogram_report_4, tvb, offset, 1, ENC_NA);
- offset += 1;
+ /* TODO Add Optional Subelements */
+ break;
+ }
+ case 4: /* Noise Histogram Report */
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_operating_class, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_rpi_histogram_report_5, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_channel_number, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_rpi_histogram_report_6, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_start_time, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ offset += 8;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_rpi_histogram_report_7, tvb, offset, 1, ENC_NA);
- offset += 1;
- break;
- case 3: /* Channel Load Report */
- {
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_operating_class, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_channel_number, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_ant_id, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_start_time, tvb, offset, 8, ENC_LITTLE_ENDIAN);
- offset += 8;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_anpi, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_ipi_density_0, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_channel_load, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_ipi_density_1, tvb, offset, 1, ENC_NA);
+ offset += 1;
- /* TODO Add Optional Subelements */
- break;
- }
- case 4: /* Noise Histogram Report */
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_operating_class, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_ipi_density_2, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_channel_number, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_ipi_density_3, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_start_time, tvb, offset, 8, ENC_LITTLE_ENDIAN);
- offset += 8;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_ipi_density_4, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_ipi_density_5, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_ant_id, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_ipi_density_6, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_anpi, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_ipi_density_7, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_ipi_density_0, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_ipi_density_8, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_ipi_density_1, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_ipi_density_9, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_ipi_density_2, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_ipi_density_10, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_ipi_density_3, tvb, offset, 1, ENC_NA);
- offset += 1;
+ /* TODO Add Optional Subelements */
+ break;
+ case 5: /* Beacon Report */
+ {
+ proto_tree *sub_tree_frame_info;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_ipi_density_4, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_operating_class, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_ipi_density_5, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_channel_number, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_ipi_density_6, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_start_time, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ offset += 8;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_ipi_density_7, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_ipi_density_8, tvb, offset, 1, ENC_NA);
- offset += 1;
+ parent_item = proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_frame_info, tvb, offset, 1, ENC_NA);
+ sub_tree_frame_info = proto_item_add_subtree(parent_item, ett_tag_measure_report_frame_tree);
+ proto_tree_add_item(sub_tree_frame_info, hf_ieee80211_tag_measure_report_frame_info_phy_type, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(sub_tree_frame_info, hf_ieee80211_tag_measure_report_frame_info_frame_type, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_ipi_density_9, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_rcpi, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_ipi_density_10, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_rsni, tvb, offset, 1, ENC_NA);
+ offset += 1;
- /* TODO Add Optional Subelements */
- break;
- case 5: /* Beacon Report */
- {
- proto_tree *sub_tree_frame_info;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_bssid, tvb, offset, 6, ENC_NA);
+ offset += 6;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_operating_class, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_ant_id, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_channel_number, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_parent_tsf, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_start_time, tvb, offset, 8, ENC_LITTLE_ENDIAN);
- offset += 8;
+ while (offset < tag_len)
+ {
+ guint8 sub_id, sub_length;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_beacon_sub_id, tvb, offset, 1, ENC_NA);
+ sub_id = tvb_get_guint8(tvb, offset);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_subelement_length, tvb, offset, 1, ENC_NA);
+ sub_length = tvb_get_guint8(tvb, offset);
+ offset += 1;
- parent_item = proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_frame_info, tvb, offset, 1, ENC_NA);
- sub_tree_frame_info = proto_item_add_subtree(parent_item, ett_tag_measure_report_frame_tree);
- proto_tree_add_item(sub_tree_frame_info, hf_ieee80211_tag_measure_report_frame_info_phy_type, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(sub_tree_frame_info, hf_ieee80211_tag_measure_report_frame_info_frame_type, tvb, offset, 1, ENC_NA);
- offset += 1;
+ switch (sub_id) {
+ case MEASURE_REP_REPORTED_FRAME_BODY: /* Reported Frame Body (1) */
+ {
+ proto_tree *rep_tree;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_rcpi, tvb, offset, 1, ENC_NA);
- offset += 1;
+ rep_tree = proto_tree_add_subtree(sub_tree, tvb, offset, sub_length, ett_tag_measure_reported_frame_tree, NULL, "Reported Frame Body");
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_rsni, tvb, offset, 1, ENC_NA);
- offset += 1;
+ add_ff_timestamp(rep_tree, tvb, pinfo, 0);
+ add_ff_beacon_interval(rep_tree, tvb, pinfo, 8);
+ add_ff_cap_info(rep_tree, tvb, pinfo, 10);
+ offset += 12;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_bssid, tvb, offset, 6, ENC_NA);
- offset += 6;
+ ieee_80211_add_tagged_parameters(tvb, offset, pinfo, rep_tree, sub_length - 12, MGT_PROBE_RESP, NULL);
+ offset += (sub_length - 12);
+ }
+ break;
+ default:
+ /* no default action */
+ break;
+ }
+ }
+ break;
+ }
+ case 6: /* Frame Report */
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_operating_class, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_ant_id, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_channel_number, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_parent_tsf, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_start_time, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ offset += 8;
- while (offset < tag_end)
- {
- guint8 sub_id, sub_length;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_beacon_sub_id, tvb, offset, 1, ENC_NA);
- sub_id = tvb_get_guint8(tvb, offset);
- offset += 1;
+ proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_subelement_length, tvb, offset, 1, ENC_NA);
- sub_length = tvb_get_guint8(tvb, offset);
- offset += 1;
+ /* TODO Add Optional Subelements */
+ break;
+ case 7: /* BSTA Statistics Report */
+ /* TODO */
+ case 8: /* Location Configuration Information Report element */
+ /* TODO */
+ case 9: /* Transmit Stream Measurement Report */
+ /* TODO */
+ case 10: /* Multicast diagnostics Report */
+ /* TODO */
+ case 11: /* Location Civic Report */
+ /* TODO */
+ case 12: /* Location Identifier Report */
+ /* TODO */
+ case 13: /* Directional channel quality Report */
+ /* TODO */
+ case 14: /* Directional measurement Report */
+ /* TODO */
+ case 15: /* Directional statistics Report */
+ /* TODO */
+ default: /* unknown */
+ break;
+ }
+ if (offset < tag_len)
+ {
+ proto_item *tix;
+ tix = proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_unknown, tvb, offset, tag_len - offset, ENC_NA);
+ expert_add_info(pinfo, tix, &ei_ieee80211_tag_measure_report_unknown);
+ }
+ return tvb_captured_length(tvb);
+}
- switch (sub_id) {
- case MEASURE_REP_REPORTED_FRAME_BODY: /* Reported Frame Body (1) */
- {
- proto_tree *rep_tree;
-
- rep_tree = proto_tree_add_subtree(sub_tree, tvb, offset, sub_length, ett_tag_measure_reported_frame_tree, NULL, "Reported Frame Body");
-
- add_ff_timestamp(rep_tree, tvb, pinfo, 0);
- add_ff_beacon_interval(rep_tree, tvb, pinfo, 8);
- add_ff_cap_info(rep_tree, tvb, pinfo, 10);
- offset += 12;
-
- ieee_80211_add_tagged_parameters(tvb, offset, pinfo, rep_tree, sub_length - 12, MGT_PROBE_RESP, NULL);
- offset += (sub_length - 12);
- }
- break;
- default:
- /* no default action */
- break;
- }
- }
- break;
- }
- case 6: /* Frame Report */
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_operating_class, tvb, offset, 1, ENC_NA);
- offset += 1;
+/* 7.3.2.23 Quiet element (40) */
+static int
+ieee80211_tag_quiet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ if (tag_len != 6)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 6", tag_len);
+ return tvb_captured_length(tvb);
+ }
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_channel_number, tvb, offset, 1, ENC_NA);
- offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_quiet_count, tvb, offset, 1, ENC_NA);
+ proto_item_append_text(field_data->item_tag, " Count: %d", tvb_get_guint8(tvb, offset));
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_start_time, tvb, offset, 8, ENC_LITTLE_ENDIAN);
- offset += 8;
+ proto_tree_add_item(tree, hf_ieee80211_tag_quiet_period, tvb, offset, 1, ENC_NA);
+ proto_item_append_text(field_data->item_tag, " Period: %d", tvb_get_guint8(tvb, offset));
+ offset += 1;
- proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
+ proto_tree_add_item(tree, hf_ieee80211_tag_quiet_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(field_data->item_tag, " Duration: %d", tvb_get_letohs(tvb, offset));
+ offset += 2;
- /* TODO Add Optional Subelements */
- break;
- case 7: /* BSTA Statistics Report */
- /* TODO */
- case 8: /* Location Configuration Information Report element */
- /* TODO */
- case 9: /* Transmit Stream Measurement Report */
- /* TODO */
- case 10: /* Multicast diagnostics Report */
- /* TODO */
- case 11: /* Location Civic Report */
- /* TODO */
- case 12: /* Location Identifier Report */
- /* TODO */
- case 13: /* Directional channel quality Report */
- /* TODO */
- case 14: /* Directional measurement Report */
- /* TODO */
- case 15: /* Directional statistics Report */
- /* TODO */
- default: /* unknown */
- break;
- }
- if (offset < tag_end)
- {
- proto_item *tix;
- tix = proto_tree_add_item(sub_tree, hf_ieee80211_tag_measure_report_unknown, tvb, offset, tag_end - offset, ENC_NA);
- expert_add_info(pinfo, tix, &ei_ieee80211_tag_measure_report_unknown);
- }
- }
- break;
+ proto_tree_add_item(tree, hf_ieee80211_tag_quiet_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(field_data->item_tag, " Offset: %d", tvb_get_letohs(tvb, offset));
- case TAG_QUIET: /* 7.3.2.23 Quiet element (40) */
- if (tag_len != 6)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 6", tag_len);
- break;
- }
- offset += 2;
+ return tvb_captured_length(tvb);
+}
- proto_tree_add_item(tree, hf_ieee80211_tag_quiet_count, tvb, offset, 1, ENC_NA);
- proto_item_append_text(ti, " Count: %d", tvb_get_guint8(tvb, offset));
- offset += 1;
+/* 7.3.2.24 IBSS DFS element (41) */
+static int
+ieee80211_tag_ibss_dfs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ proto_item *ti_sup_map;
+ proto_tree *sub_map_tree;
+ if (tag_len < 7)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be >= 7", tag_len);
+ return tvb_captured_length(tvb);
+ }
- proto_tree_add_item(tree, hf_ieee80211_tag_quiet_period, tvb, offset, 1, ENC_NA);
- proto_item_append_text(ti, " Period: %d", tvb_get_guint8(tvb, offset));
- offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_dfs_owner, tvb, offset, 6, ENC_NA);
+ proto_item_append_text(field_data->item_tag, " Owner: %s", tvb_ether_to_str(tvb, offset));
+ offset += 6;
- proto_tree_add_item(tree, hf_ieee80211_tag_quiet_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_item_append_text(ti, " Duration: %d", tvb_get_letohs(tvb, offset));
- offset += 2;
+ proto_tree_add_item(tree, hf_ieee80211_tag_dfs_recovery_interval, tvb, offset, 1, ENC_NA);
+ offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_tag_quiet_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_item_append_text(ti, " Offset: %d", tvb_get_letohs(tvb, offset));
- offset += 2;
- break;
+ while (offset < tag_len)
+ {
+ ti_sup_map = proto_tree_add_item(tree, hf_ieee80211_tag_dfs_channel_map, tvb, offset, 2, ENC_NA);
+ sub_map_tree = proto_item_add_subtree(ti_sup_map, ett_tag_dfs_map_tree);
+ proto_tree_add_item(sub_map_tree, hf_ieee80211_tag_dfs_channel_number, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(sub_map_tree, hf_ieee80211_tag_dfs_map, tvb, offset, 1, ENC_NA);
+ offset += 2;
+ }
+ return tvb_captured_length(tvb);
+}
+/* 7.3.2.13 ERP Information element (42) */
+static int
+ieee80211_tag_erp_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ proto_item *ti_erp;
+ proto_tree *erp_tree;
+ if (tag_len != 1)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 1", tag_len);
+ return tvb_captured_length(tvb);
+ }
- case TAG_IBSS_DFS: /* 7.3.2.24 IBSS DFS element (41) */
- if (tag_len < 7)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be >= 7", tag_len);
- break;
- }
- {
- proto_item *ti_sup_map;
- proto_tree *sub_map_tree;
- offset += 2;
+ ti_erp = proto_tree_add_item(tree, hf_ieee80211_tag_erp_info, tvb, offset, 1, ENC_NA);
+ erp_tree = proto_item_add_subtree(ti_erp, ett_tag_erp_info_tree);
+ proto_tree_add_item(erp_tree, hf_ieee80211_tag_erp_info_erp_present, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(erp_tree, hf_ieee80211_tag_erp_info_use_protection, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(erp_tree, hf_ieee80211_tag_erp_info_barker_preamble_mode, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(erp_tree, hf_ieee80211_tag_erp_info_reserved, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_dfs_owner, tvb, offset, 6, ENC_NA);
- proto_item_append_text(ti, " Owner: %s", tvb_ether_to_str(tvb, offset));
- offset += 6;
+ return tvb_captured_length(tvb);
+}
- proto_tree_add_item(tree, hf_ieee80211_tag_dfs_recovery_interval, tvb, offset, 1, ENC_NA);
- offset += 1;
+/* 7.3.2.32 TS Delay element (43) */
+static int
+ieee80211_tag_ts_delay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ if (tag_len != 4)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 4", tag_len);
+ return tvb_captured_length(tvb);
+ }
- while (offset < tag_end)
- {
- ti_sup_map = proto_tree_add_item(tree, hf_ieee80211_tag_dfs_channel_map, tvb, offset, 2, ENC_NA);
- sub_map_tree = proto_item_add_subtree(ti_sup_map, ett_tag_dfs_map_tree);
- proto_tree_add_item(sub_map_tree, hf_ieee80211_tag_dfs_channel_number, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(sub_map_tree, hf_ieee80211_tag_dfs_map, tvb, offset, 1, ENC_NA);
- offset += 2;
- }
- break;
- }
- case TAG_ERP_INFO: /* 7.3.2.13 ERP Information element (42) */
- case TAG_ERP_INFO_OLD:
- if (tag_len != 1)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 1", tag_len);
- break;
- }
- {
- proto_item *ti_erp;
- proto_tree *erp_tree;
+ proto_tree_add_item(tree, hf_ieee80211_ts_delay, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(field_data->item_tag, " : %d", tvb_get_ntohl(tvb, offset));
+ return tvb_captured_length(tvb);
+}
- offset += 2;
+/* 7.3.2.33 TCLAS Processing element (44) */
+static int
+ieee80211_tag_tclas_process(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ if (tag_len != 1)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 1", tag_len);
+ return tvb_captured_length(tvb);
+ }
- ti_erp = proto_tree_add_item(tree, hf_ieee80211_tag_erp_info, tvb, offset, 1, ENC_NA);
- erp_tree = proto_item_add_subtree(ti_erp, ett_tag_erp_info_tree);
- proto_tree_add_item(erp_tree, hf_ieee80211_tag_erp_info_erp_present, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(erp_tree, hf_ieee80211_tag_erp_info_use_protection, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(erp_tree, hf_ieee80211_tag_erp_info_barker_preamble_mode, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(erp_tree, hf_ieee80211_tag_erp_info_reserved, tvb, offset, 1, ENC_NA);
- offset += 1;
- break;
- }
+ proto_tree_add_item(tree, hf_ieee80211_tclas_process, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(field_data->item_tag, " : %s", val_to_str(tvb_get_guint8(tvb, offset), ieee80211_tclas_process_flag, "Unknown %d"));
+ return tvb_captured_length(tvb);
+}
- case TAG_TS_DELAY: /* 7.3.2.32 TS Delay element (43) */
- if (tag_len != 4)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 4", tag_len);
- break;
- }
- offset += 2;
+/* 802.11-2012 8.4.2.37 QoS Capability element (46) */
+static int
+ieee80211_tag_qos_capability(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ if (tag_len != 1)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 1", tag_len);
+ return tvb_captured_length(tvb);
+ }
+ dissect_qos_capability(tree, tvb, pinfo, offset, field_data->ftype);
+ return tvb_captured_length(tvb);
+}
- proto_tree_add_item(tree, hf_ieee80211_ts_delay, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- proto_item_append_text(ti, " : %d", tvb_get_ntohl(tvb, offset));
- offset += 4;
- break;
+static int
+ieee80211_tag_rsn_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ if (tag_len < 18)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be >= 18", tag_len);
+ return tvb_captured_length(tvb);
+ }
- case TAG_TCLAS_PROCESS: /* 7.3.2.33 TCLAS Processing element (44) */
- if (tag_len != 1)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 1", tag_len);
- break;
- }
- offset += 2;
+ dissect_rsn_ie(pinfo, tree, tvb, offset, tag_len, field_data->sanity_check);
+ return tvb_captured_length(tvb);
+}
- proto_tree_add_item(tree, hf_ieee80211_tclas_process, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_item_append_text(ti, " : %s", val_to_str(tvb_get_guint8(tvb, offset), ieee80211_tclas_process_flag, "Unknown %d"));
- offset += 1;
- break;
+/* 7.3.2.14 Extended Supported Rates element (50) */
+static int
+ieee80211_tag_ext_supp_rates(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ if (tag_len < 1)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag length %u too short, must be greater than 0", tag_len);
+ return tvb_captured_length(tvb);
+ }
- case TAG_QOS_CAPABILITY: /* 802.11-2012 8.4.2.37 QoS Capability element (46) */
- if (tag_len != 1)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 1", tag_len);
- break;
- }
- {
- offset += 2;
- offset = dissect_qos_capability(tree, tvb, pinfo, offset, ftype);
- }
- break;
+ while (offset < tag_len)
+ {
+ proto_tree_add_item(tree, hf_ieee80211_tag_ext_supp_rates, tvb, offset, 1, ENC_NA);
+ proto_item_append_text(field_data->item_tag, " %s,", val_to_str_ext_const(tvb_get_guint8(tvb, offset), &ieee80211_supported_rates_vals_ext, "Unknown Rate"));
+ offset += 1;
+ }
+ proto_item_append_text(field_data->item_tag, " [Mbit/sec]");
+ return tvb_captured_length(tvb);
+}
- case TAG_RSN_IE: /* 7.3.2.25 RSN information element (48) */
- if (tag_len < 18)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be >= 18", tag_len);
- break;
- }
- offset += 2;
+static int
+ieee80211_tag_cisco_ccx1_ckip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ /* From WCS manual:
+ * If Aironet IE support is enabled, the access point sends an Aironet
+ * IE 0x85 (which contains the access point name, load, number of
+ * associated clients, and so on) in the beacon and probe responses of
+ * this WLAN, and the controller sends Aironet IEs 0x85 and 0x95
+ * (which contains the management IP address of the controller and
+ * the IP address of the access point) in the reassociation response
+ * if it receives Aironet IE 0x85 in the reassociation request.
+ */
- offset = dissect_rsn_ie(pinfo, tree, tvb, offset, tag_len, association_sanity_check);
- break;
+ if (tag_len < 26)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u too short, must be >= 26", tag_len);
+ return tvb_captured_length(tvb);
+ }
+ proto_tree_add_item(tree, hf_ieee80211_tag_cisco_ccx1_unknown, tvb, offset, 10, ENC_NA);
+ offset += 10;
- case TAG_EXT_SUPP_RATES: /* 7.3.2.14 Extended Supported Rates element (50) */
- if (tag_len < 1)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag length %u too short, must be greater than 0", tag_len);
- break;
- }
- offset += 2;
+ /* The Name of the sending device starts at offset 10 and is up to
+ 15 or 16 bytes in length, \0 padded */
+ proto_tree_add_item(tree, hf_ieee80211_tag_cisco_ccx1_name, tvb, offset, 16, ENC_ASCII|ENC_NA);
+ offset += 16;
- while (offset < tag_end)
- {
- proto_tree_add_item(tree, hf_ieee80211_tag_ext_supp_rates, tvb, offset, 1, ENC_NA);
- proto_item_append_text(ti, " %s,", val_to_str_ext_const(tvb_get_guint8(tvb, offset), &ieee80211_supported_rates_vals_ext, "Unknown Rate"));
- offset += 1;
- }
- proto_item_append_text(ti, " [Mbit/sec]");
- break;
+ /* Total number off associated clients and repeater access points */
+ proto_tree_add_item(tree, hf_ieee80211_tag_cisco_ccx1_clients, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_cisco_ccx1_unknown2, tvb, offset, 3, ENC_NA);
+ return tvb_captured_length(tvb);
+}
- case TAG_EXTENDED_CAPABILITIES: /* 7.3.2.27 Extended Capabilities information element (127) */
- dissect_extended_capabilities_ie(pinfo, tree, ti, ti_len, tag_len, tvb, offset+2, tag_end);
- break;
+static int
+ieee80211_tag_vendor_specific_ie(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ guint32 tag_vs_len = tag_len;
+ guint32 oui;
- case TAG_CISCO_CCX1_CKIP: /* Cisco CCX1 CKIP + Device Name (133) */
- /* From WCS manual:
- * If Aironet IE support is enabled, the access point sends an Aironet
- * IE 0x85 (which contains the access point name, load, number of
- * associated clients, and so on) in the beacon and probe responses of
- * this WLAN, and the controller sends Aironet IEs 0x85 and 0x95
- * (which contains the management IP address of the controller and
- * the IP address of the access point) in the reassociation response
- * if it receives Aironet IE 0x85 in the reassociation request.
- */
+ if (tag_len < 3)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be >= 3", tag_len);
+ return tvb_captured_length(tvb);
+ }
- if (tag_len < 26)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u too short, must be >= 26", tag_len);
- break;
- }
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_cisco_ccx1_unknown, tvb, offset, 10, ENC_NA);
- offset += 10;
+ oui = tvb_get_ntoh24(tvb, offset);
+ proto_tree_add_item(tree, hf_ieee80211_tag_oui, tvb, offset, 3, ENC_NA);
+ proto_item_append_text(field_data->item_tag, ": %s", uint_get_manuf_name(oui));
+ offset += 3;
+ tag_vs_len -= 3;
- /* The Name of the sending device starts at offset 10 and is up to
- 15 or 16 bytes in length, \0 padded */
- proto_tree_add_item(tree, hf_ieee80211_tag_cisco_ccx1_name, tvb, offset, 16, ENC_ASCII|ENC_NA);
- offset += 16;
+ if (tag_len > 0) {
+ proto_tree_add_item(field_data->item_tag, hf_ieee80211_tag_vendor_oui_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ }
- /* Total number off associated clients and repeater access points */
- proto_tree_add_item(tree, hf_ieee80211_tag_cisco_ccx1_clients, tvb, offset, 1, ENC_NA);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_tag_cisco_ccx1_unknown2, tvb, offset, 3, ENC_NA);
- offset += 3;
+ switch (oui) {
+ /* 802.11 specific vendor ids */
+ case OUI_WPAWME:
+ dissect_vendor_ie_wpawme(tree, tvb, pinfo, offset, tag_vs_len, field_data->ftype);
break;
-
- case TAG_VHT_CAPABILITY:
- dissect_vht_capability_ie(tvb, pinfo, tree, offset+2, tag_len, ti_len);
+ case OUI_RSN:
+ dissect_vendor_ie_rsn(field_data->item_tag, tree, tvb, offset, tag_vs_len);
break;
-
- case TAG_VHT_OPERATION:
- dissect_vht_operation_ie(tvb, pinfo, tree, offset+2, tag_len, ti_len);
+ case OUI_PRE11N:
+ dissect_vendor_ie_ht(tvb, pinfo, tree, offset, field_data->item_tag, field_data->item_tag_length, tag_vs_len);
break;
-
- case TAG_EXT_BSS_LOAD:
- dissect_ext_bss_load(tree, tvb, offset+2);
+ case OUI_WFA:
+ dissect_vendor_ie_wfa(pinfo, field_data->item_tag, tvb);
break;
- case TAG_WIDE_BW_CHANNEL_SWITCH:
- dissect_wide_bw_channel_switch(tree, tvb, offset+2);
+ /* Normal IEEE vendor ids (from oui.h) */
+ case OUI_CISCOWL: /* Cisco Wireless (Aironet) */
+ dissect_vendor_ie_aironet(field_data->item_tag, tree, tvb, offset, tag_vs_len);
break;
-
- case TAG_VHT_TX_PWR_ENVELOPE:
- dissect_vht_tx_pwr_envelope(tvb, pinfo, tree, offset+2, tag_len, ti_len);
+ case OUI_MARVELL:
+ dissect_vendor_ie_marvell(field_data->item_tag, tree, tvb, offset, tag_vs_len);
break;
-
- case TAG_CHANNEL_SWITCH_WRAPPER:
- dissect_channel_switch_wrapper(pinfo, tree, tvb, offset + 2, tag_len);
+ case OUI_ATHEROS:
+ dissect_vendor_ie_atheros(field_data->item_tag, tree, tvb, offset, tag_vs_len, pinfo, field_data->item_tag_length);
break;
-
- case TAG_OPERATING_MODE_NOTIFICATION:
- dissect_operating_mode_notification(tree, tvb, offset + 2);
+ case OUI_ARUBA:
+ dissect_vendor_ie_aruba(field_data->item_tag, tree, tvb, offset, tag_vs_len);
break;
-
- case TAG_VENDOR_SPECIFIC_IE: /* 7.3.2.26 Vendor Specific information element (221) */
- case TAG_CISCO_VENDOR_SPECIFIC: /* This Cisco proprietary IE seems to mimic 221 */
- case TAG_SYMBOL_PROPRIETARY: /* This Symbol proprietary IE seems to mimic 221 */
- if (tag_len < 3)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be >= 3", tag_len);
- break;
- }
- {
- guint32 tag_vs_len = tag_len;
-
- offset += 2;
- oui = tvb_get_ntoh24(tvb, offset);
- tag_tvb = tvb_new_subset_length(tvb, offset, tag_len);
- proto_tree_add_item(tree, hf_ieee80211_tag_oui, tvb, offset, 3, ENC_NA);
- proto_item_append_text(ti, ": %s", uint_get_manuf_name(oui));
- offset += 3;
- tag_vs_len -= 3;
-
- if (tag_len > 0) {
- proto_tree_add_item(ti, hf_ieee80211_tag_vendor_oui_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- }
-
- switch (oui) {
- /* 802.11 specific vendor ids */
- case OUI_WPAWME:
- offset = dissect_vendor_ie_wpawme(tree, tvb, pinfo, offset, tag_vs_len, ftype);
- break;
- case OUI_RSN:
- dissect_vendor_ie_rsn(ti, tree, tvb, offset, tag_vs_len);
- break;
- case OUI_PRE11N:
- dissect_vendor_ie_ht(tvb, pinfo, tree, offset, ti, ti_len, tag_vs_len);
- break;
- case OUI_WFA:
- dissect_vendor_ie_wfa(pinfo, ti, tag_tvb);
- break;
-
- /* Normal IEEE vendor ids (from oui.h) */
- case OUI_CISCOWL: /* Cisco Wireless (Aironet) */
- dissect_vendor_ie_aironet(ti, tree, tvb, offset, tag_vs_len);
- break;
- case OUI_MARVELL:
- dissect_vendor_ie_marvell(ti, tree, tvb, offset, tag_vs_len);
- break;
- case OUI_ATHEROS:
- dissect_vendor_ie_atheros(ti, tree, tvb, offset, tag_vs_len, pinfo, ti_len);
- break;
- case OUI_ARUBA:
- dissect_vendor_ie_aruba(ti, tree, tvb, offset, tag_vs_len);
- break;
- case OUI_NINTENDO:
- dissect_vendor_ie_nintendo(ti, tree, tvb, offset, tag_vs_len);
- break;
- case OUI_MIKROTIK:
- dissect_vendor_ie_mikrotik(ti, tree, tvb, offset, tag_vs_len);
- break;
- case OUI_MERU:
- dissect_vendor_ie_meru(ti, tree, tvb, offset, tag_vs_len, pinfo);
- break;
- case OUI_ZEBRA_EXTREME:
- dissect_vendor_ie_extreme(ti, tree, tvb, offset, tag_vs_len, pinfo);
- break;
- default:
- proto_tree_add_item(tree, hf_ieee80211_tag_vendor_data, tvb, offset, tag_vs_len, ENC_NA);
- break;
- }
-
- }
+ case OUI_NINTENDO:
+ dissect_vendor_ie_nintendo(field_data->item_tag, tree, tvb, offset, tag_vs_len);
break;
-
- case TAG_MOBILITY_DOMAIN:
- dissect_mobility_domain(tree, tvb, offset + 2, tag_len, association_sanity_check);
+ case OUI_MIKROTIK:
+ dissect_vendor_ie_mikrotik(field_data->item_tag, tree, tvb, offset, tag_vs_len);
break;
-
- case TAG_FAST_BSS_TRANSITION:
- dissect_fast_bss_transition(tree, tvb, offset + 2, tag_len);
+ case OUI_MERU:
+ dissect_vendor_ie_meru(field_data->item_tag, tree, tvb, offset, tag_vs_len, pinfo);
break;
-
- case TAG_MMIE:
- dissect_mmie(tree, tvb, offset + 2, tag_len);
+ case OUI_ZEBRA_EXTREME:
+ dissect_vendor_ie_extreme(field_data->item_tag, tree, tvb, offset, tag_vs_len, pinfo);
break;
-
- case TAG_SSID_LIST:
- dissect_ssid_list(tree, tvb, offset + 2, tag_len);
+ default:
+ proto_tree_add_item(tree, hf_ieee80211_tag_vendor_data, tvb, offset, tag_vs_len, ENC_NA);
break;
+ }
- case TAG_TIME_ZONE:
- dissect_time_zone(tree, tvb, offset + 2, tag_len);
- break;
+ return tvb_captured_length(tvb);
+}
- case TAG_TIMEOUT_INTERVAL:
- dissect_timeout_interval(tree, tvb, pinfo, offset + 2, tag_len);
- break;
+/* Conflict: WAPI Vs. IEEE */
+static int
+ieee80211_tag_ie_68_conflict(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ if (tag_len >= 20) { /* It Might be WAPI*/
+ dissect_wapi_param_set(tvb, pinfo, tree, 0, tag_len, field_data->item_tag_length, field_data->item_tag, field_data->ftype);
+ }
+ else { /* BSS AC Access Delay (68) */
+ dissect_bss_ac_access_delay_ie(tvb, pinfo, tree, 0, tag_len, field_data->item_tag_length);
+ }
+ return tvb_captured_length(tvb);
+}
- case TAG_RIC_DATA: /* RIC Data (RDE) (57) */
- /* Assigning the return value will ensure that the IE after RIC is processed
- * only once. This gives us a good looking RIC IE :-)
- */
- tag_len = dissect_ric_data(pinfo, tree, tvb, offset + 2, tag_len, ti, ti_len, ftype);
- break;
+static int
+ieee80211_tag_mesh_peering_mgmt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+{
+ int tag_len = tvb_reported_length(tvb);
+ int offset = 0;
- case TAG_LINK_IDENTIFIER:
- dissect_link_identifier(tree, tvb, offset + 2, tag_len);
+ proto_tree_add_item(tree, hf_ieee80211_mesh_peering_proto, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(tree, hf_ieee80211_mesh_peering_local_link_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ switch (tvb_get_guint8(tvb, 1))
+ { /* Self-protected action field */
+ case SELFPROT_ACTION_MESH_PEERING_OPEN:
break;
- case TAG_WAKEUP_SCHEDULE:
- dissect_wakeup_schedule(tree, tvb, offset + 2, tag_len);
+ case SELFPROT_ACTION_MESH_PEERING_CONFIRM:
+ proto_tree_add_item(tree, hf_ieee80211_mesh_peering_peer_link_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
break;
- case TAG_CHANNEL_SWITCH_TIMING:
- dissect_channel_switch_timing(tree, tvb, offset + 2, tag_len);
+ case SELFPROT_ACTION_MESH_PEERING_CLOSE:
+ if ((tag_len == 8) || (tag_len == 24))
+ {
+ proto_tree_add_item(tree, hf_ieee80211_mesh_peering_peer_link_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ }
+ add_ff_reason_code(tree, tvb, pinfo, offset);
break;
- case TAG_PTI_CONTROL:
- dissect_pti_control(tree, tvb, offset + 2, tag_len);
+ /* unexpected values */
+ default:
+ proto_tree_add_expert(tree, pinfo, &ei_ieee80211_mesh_peering_unexpected , tvb, offset, tag_len);
break;
+ }
+ if (tag_len - offset == 16)
+ {
+ proto_tree_add_item(tree, hf_ieee80211_rsn_pmkid, tvb, offset, 16, ENC_NA);
+ }
+ return tvb_captured_length(tvb);
+}
- case TAG_PU_BUFFER_STATUS:
- dissect_pu_buffer_status(tree, tvb, offset + 2, tag_len);
- break;
+static int
+ieee80211_tag_mesh_configuration(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
+{
+ int offset = 0;
+ proto_item *item;
+ proto_tree *subtree;
+ proto_tree_add_item(tree, hf_ieee80211_mesh_config_path_sel_protocol, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_mesh_config_path_sel_metric, tvb, offset + 1, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_mesh_config_congestion_control, tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_mesh_config_sync_method, tvb, offset + 3, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_mesh_config_auth_protocol, tvb, offset + 4, 1, ENC_LITTLE_ENDIAN);
+ item = proto_tree_add_item(tree, hf_ieee80211_mesh_config_formation_info, tvb, offset + 5, 1, ENC_LITTLE_ENDIAN);
+ subtree = proto_item_add_subtree(item, ett_mesh_formation_info_tree);
+ proto_tree_add_item(subtree, hf_ieee80211_mesh_form_info_num_of_peerings, tvb, offset + 5, 1, ENC_LITTLE_ENDIAN);
+ item = proto_tree_add_item(tree, hf_ieee80211_mesh_config_capability, tvb, offset + 6, 1, ENC_LITTLE_ENDIAN);
+ subtree = proto_item_add_subtree(item, ett_mesh_config_cap_tree);
+ proto_tree_add_item(subtree, hf_ieee80211_mesh_config_cap_accepting, tvb, offset + 6, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(subtree, hf_ieee80211_mesh_config_cap_mcca_support, tvb, offset + 6, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(subtree, hf_ieee80211_mesh_config_cap_mcca_enabled, tvb, offset + 6, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(subtree, hf_ieee80211_mesh_config_cap_forwarding, tvb, offset + 6, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(subtree, hf_ieee80211_mesh_config_cap_mbca_enabled, tvb, offset + 6, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(subtree, hf_ieee80211_mesh_config_cap_tbtt_adjusting, tvb, offset + 6, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(subtree, hf_ieee80211_mesh_config_cap_power_save_level, tvb, offset + 6, 1, ENC_LITTLE_ENDIAN);
+ return tvb_captured_length(tvb);
+}
- case TAG_HT_CAPABILITY:
- dissect_ht_capability_ie(tvb, pinfo, tree, offset+2, tag_len, ti_len, FALSE);
- break;
+static int
+ieee80211_tag_mesh_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int offset = 0;
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int tag_len = tvb_reported_length(tvb);
+ const guint8* mesh_id;
- case TAG_HT_INFO:
- dissect_ht_info_ie_1_1(tvb, pinfo, tree, offset + 2, tag_len, ti_len);
- break;
+ proto_tree_add_item_ret_string(tree, hf_ieee80211_mesh_id, tvb, offset, tag_len, ENC_ASCII|ENC_NA, wmem_packet_scope(), &mesh_id);
+ if (tag_len > 0) {
+ gchar* s = format_text(wmem_packet_scope(), mesh_id, tag_len);
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", MESHID=%s", s);
+ proto_item_append_text(field_data->item_tag, ": %s", s);
+ }
+ /* Make sure dissector is accepted */
+ return ((tag_len > 0) ? tag_len : 1);
+}
- case TAG_SECONDARY_CHANNEL_OFFSET:
- dissect_secondary_channel_offset_ie(tvb, pinfo, tree, offset + 2, tag_len, ti_len);
- break;
+static int
+ieee80211_tag_mesh_preq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
+{
+ int offset = 0;
- case TAG_BSS_AVG_ACCESS_DELAY: /* BSS Average Access Delay element (63) */
- dissect_bss_avg_access_delay_ie(tvb, pinfo, tree, offset + 2, tag_len, ti_len);
- break;
+ guint32 flags;
+ guint8 targs, i;
- case TAG_ANTENNA: /* Antenna element (64) */
- dissect_antenna_ie(tvb, pinfo, tree, offset + 2, tag_len, ti_len);
- break;
+ proto_tree_add_item_ret_uint(tree, hf_ieee80211_ff_hwmp_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN, &flags);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_hopcount, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_ttl, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_pdid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_orig_sta, tvb, offset, 6, ENC_NA);
+ offset += 6;
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_orig_sn, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
- case TAG_RSNI: /* RSNI element (65) */
- dissect_rsni_ie(tvb, pinfo, tree, offset + 2, tag_len, ti_len);
- break;
+ if (flags & (1<<6)) {
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_orig_ext, tvb, offset, 6, ENC_NA);
+ offset += 6;
+ }
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_lifetime, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_metric, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_targ_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ targs = tvb_get_guint8(tvb, offset);
+ offset += 1;
+ for (i = 0; i < targs; i++) {
+ const int * targ_flags[] = {
+ &hf_ieee80211_ff_hwmp_targ_to_flags,
+ &hf_ieee80211_ff_hwmp_targ_usn_flags,
+ NULL
+ };
- case TAG_BSS_AVB_ADM_CAPACITY:
- dissect_bss_available_admission_capacity_ie(tvb, pinfo, tree, offset + 2, tag_len, ti_len);
- break;
+ proto_tree_add_bitmask_with_flags(tree, tvb, offset, hf_ieee80211_ff_hwmp_targ_flags,
+ ett_hwmp_targ_flags_tree, targ_flags, ENC_LITTLE_ENDIAN, BMT_NO_APPEND);
- case TAG_IE_68_CONFLICT: /* Conflict: WAPI Vs. IEEE */
- if (tag_len >= 20) { /* It Might be WAPI*/
- dissect_wapi_param_set(tvb, pinfo, tree, offset + 2, tag_len, ti_len, ti, ftype);
- }
- else { /* BSS AC Access Delay (68) */
- dissect_bss_ac_access_delay_ie(tvb, pinfo, tree, offset + 2, tag_len, ti_len);
- }
- break;
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_targ_sta, tvb, offset, 6, ENC_NA);
+ offset += 6;
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_targ_sn, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ }
- case TAG_BSS_MAX_IDLE_PERIOD:
- dissect_bss_max_idle_period(tree, tvb, offset + 2);
- break;
+ return tvb_captured_length(tvb);
+}
- case TAG_TFS_REQUEST:
- dissect_tfs_request(pinfo, tree, tvb, offset + 2, tag_len, ftype);
- break;
+static int
+ieee80211_tag_mesh_prep(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
+{
+ int offset = 0;
- case TAG_TFS_RESPONSE:
- dissect_tfs_response(pinfo, tree, tvb, offset + 2, tag_len, ftype);
- break;
+ guint32 flags;
+ proto_tree_add_item_ret_uint(tree, hf_ieee80211_ff_hwmp_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN, &flags);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_hopcount, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_ttl, tvb, offset , 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_targ_sta, tvb, offset, 6, ENC_NA);
+ offset += 6;
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_targ_sn, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ if (flags & (1<<6)) {
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_targ_ext, tvb, offset, 6, ENC_NA);
+ offset += 6;
+ }
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_lifetime, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_metric, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_orig_sta, tvb, offset, 6, ENC_NA);
+ offset += 6;
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_orig_sn, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ return tvb_captured_length(tvb);
+}
- case TAG_WNM_SLEEP_MODE:
- dissect_wnm_sleep_mode(tree, tvb, offset + 2);
- break;
+static int
+ieee80211_tag_mesh_perr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+{
+ int offset = 0;
+ guint8 targs, i;
- case TAG_TIME_ADV:
- dissect_time_adv(tree, tvb, offset + 2);
- break;
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_ttl, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_targ_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ targs = tvb_get_guint8(tvb, offset);
+ offset += 1;
+ for (i = 0; i < targs; i++) {
+ guint8 flags = tvb_get_guint8(tvb, offset);
- case TAG_RM_ENABLED_CAPABILITY: /* RM Enabled Capabilities (70) */
- dissect_rm_enabled_capabilities_ie(pinfo, tree, ti, ti_len, tag_len, tvb, offset+2, tag_end);
- break;
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_targ_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_targ_sta, tvb, offset, 6, ENC_NA);
+ offset += 6;
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_targ_sn, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ if (flags & (1<<6)) {
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_targ_ext, tvb, offset, 6, ENC_NA);
+ offset += 6;
+ }
+ offset += add_ff_reason_code(tree, tvb, pinfo, offset);
+ }
+ return tvb_captured_length(tvb);
+}
- case TAG_20_40_BSS_CO_EX: /* 20/40 BSS Coexistence (72) */
- dissect_20_40_bss_coexistence(pinfo, tree, ti_len, tag_len, tvb, offset+2);
- break;
+static int
+ieee80211_tag_rann(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
+{
+ int offset = 0;
+ proto_tree_add_item(tree, hf_ieee80211_rann_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_hopcount, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_ttl, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_rann_root_sta, tvb, offset, 6, ENC_NA);
+ offset += 6;
+ proto_tree_add_item(tree, hf_ieee80211_rann_sn, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(tree, hf_ieee80211_rann_interval, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_metric, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ return tvb_captured_length(tvb);
+}
- case TAG_OVERLAP_BSS_SCAN_PAR: /* Overlapping BSS Scan Parameters (74) */
- dissect_overlap_bss_scan_par(pinfo, tree, tvb, offset + 2, tag_len, ti, ti_len);
- break;
+/* Mesh Channel Switch Parameters (118) */
+static int
+ieee80211_tag_mesh_channel_switch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ proto_item *item;
+ proto_tree *subtree;
+ if (tag_len != 6)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 6", tag_len);
+ return tvb_captured_length(tvb);
+ }
- case TAG_RIC_DESCRIPTOR: /* RIC Descriptor (75) */
- dissect_ric_descriptor(pinfo, tree, tvb, offset + 2, tag_len, ti, ti_len);
- break;
+ proto_tree_add_item(tree, hf_ieee80211_mesh_channel_switch_ttl, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(field_data->item_tag, " TTL: %d", tvb_get_guint8(tvb, offset));
+ offset += 1;
- case TAG_MESH_PEERING_MGMT:
- {
- guint start = offset + 2;
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_mesh_peering_proto, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_mesh_peering_local_link_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- switch (tvb_get_guint8(tvb, 1))
- { /* Self-protected action field */
- case SELFPROT_ACTION_MESH_PEERING_OPEN:
- break;
+ item = proto_tree_add_item(tree, hf_ieee80211_mesh_channel_switch_flag, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ subtree = proto_item_add_subtree(item, ett_mesh_chswitch_flag_tree);
+ proto_tree_add_item(subtree, hf_ieee80211_mesh_chswitch_flag_initiator, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(subtree, hf_ieee80211_mesh_chswitch_flag_txrestrict, tvb, offset, 1, ENC_LITTLE_ENDIAN);
+ offset += 1;
- case SELFPROT_ACTION_MESH_PEERING_CONFIRM:
- proto_tree_add_item(tree, hf_ieee80211_mesh_peering_peer_link_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- break;
+ proto_tree_add_item(tree, hf_ieee80211_mesh_channel_switch_reason_code, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
- case SELFPROT_ACTION_MESH_PEERING_CLOSE:
- if ((tag_len == 8) || (tag_len == 24))
- {
- proto_tree_add_item(tree, hf_ieee80211_mesh_peering_peer_link_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- }
- offset += add_ff_reason_code(tree, tvb, pinfo, offset);
- break;
+ proto_tree_add_item(tree, hf_ieee80211_mesh_channel_switch_precedence_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ return tvb_captured_length(tvb);
+}
- /* unexpected values */
- default:
- proto_tree_add_expert(tree, pinfo, &ei_ieee80211_mesh_peering_unexpected , tvb, offset, tag_len);
- offset += tag_len;
- break;
- }
- if (tag_len - (offset - start) == 16)
- {
- proto_tree_add_item(tree, hf_ieee80211_rsn_pmkid, tvb, offset, 16, ENC_NA);
- offset += 16;
- }
- break;
- }
+static int
+ieee80211_tag_channel_switch_announcement(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ if (tag_len != 4)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 4", tag_len);
+ return tvb_captured_length(tvb);
+ }
- case TAG_MESH_CONFIGURATION:
- {
- proto_item *item;
- proto_tree *subtree;
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_mesh_config_path_sel_protocol, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_mesh_config_path_sel_metric, tvb, offset + 1, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_mesh_config_congestion_control, tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_mesh_config_sync_method, tvb, offset + 3, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_mesh_config_auth_protocol, tvb, offset + 4, 1, ENC_LITTLE_ENDIAN);
- item = proto_tree_add_item(tree, hf_ieee80211_mesh_config_formation_info, tvb, offset + 5, 1, ENC_LITTLE_ENDIAN);
- subtree = proto_item_add_subtree(item, ett_mesh_formation_info_tree);
- proto_tree_add_item(subtree, hf_ieee80211_mesh_form_info_num_of_peerings, tvb, offset + 5, 1, ENC_LITTLE_ENDIAN);
- item = proto_tree_add_item(tree, hf_ieee80211_mesh_config_capability, tvb, offset + 6, 1, ENC_LITTLE_ENDIAN);
- subtree = proto_item_add_subtree(item, ett_mesh_config_cap_tree);
- proto_tree_add_item(subtree, hf_ieee80211_mesh_config_cap_accepting, tvb, offset + 6, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(subtree, hf_ieee80211_mesh_config_cap_mcca_support, tvb, offset + 6, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(subtree, hf_ieee80211_mesh_config_cap_mcca_enabled, tvb, offset + 6, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(subtree, hf_ieee80211_mesh_config_cap_forwarding, tvb, offset + 6, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(subtree, hf_ieee80211_mesh_config_cap_mbca_enabled, tvb, offset + 6, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(subtree, hf_ieee80211_mesh_config_cap_tbtt_adjusting, tvb, offset + 6, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(subtree, hf_ieee80211_mesh_config_cap_power_save_level, tvb, offset + 6, 1, ENC_LITTLE_ENDIAN);
- break;
- }
+ add_ff_extended_channel_switch_announcement(tree, tvb, pinfo, offset);
+ return tvb_captured_length(tvb);
+}
- case TAG_MESH_ID:
- {
- const guint8* mesh_id;
- offset += 2;
+static int
+ieee80211_tag_supported_operating_classes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ const guint8 *tag_data_ptr;
+ int i, n, ret;
+ char print_buff[SHORT_STR];
- proto_tree_add_item_ret_string(tree, hf_ieee80211_mesh_id, tvb, offset, tag_len, ENC_ASCII|ENC_NA, wmem_packet_scope(), &mesh_id);
- if (tag_len > 0) {
- gchar* s = format_text(wmem_packet_scope(), mesh_id, tag_len);
- col_append_fstr(pinfo->cinfo, COL_INFO, ", MESHID=%s", s);
- proto_item_append_text(ti, ": %s", s);
- }
+ if (tag_len < 2) {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be >= 3", tag_len);
+ return tvb_captured_length(tvb);
+ } else if (tag_len > 32) {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be < 32", tag_len);
+ return tvb_captured_length(tvb);
+ }
+
+ proto_tree_add_item(tree, hf_ieee80211_tag_supported_ope_classes_current, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ /* Partially taken from the ssid section */
+ tag_data_ptr = tvb_get_ptr(tvb, offset, tag_len);
+ for (i = 0, n = 0; (i < tag_len) && (n < SHORT_STR); i++) {
+ ret = g_snprintf(print_buff + n, SHORT_STR - n, (i == tag_len-1)?"%d":"%d, ", tag_data_ptr[i]);
+ if (ret >= SHORT_STR - n) {
+ /* ret >= <buf_size> means buffer truncated */
break;
- }
+ }
+ n += ret;
+ }
+ proto_tree_add_string(tree, hf_ieee80211_tag_supported_ope_classes_alternate, tvb, offset, tag_len, print_buff);
+ return tvb_captured_length(tvb);
+}
- case TAG_MESH_PREQ:
- {
- guint8 flags = tvb_get_guint8(tvb, offset + 2);
- guint8 targs, i;
+static int
+ieee80211_tag_bss_parameter_change(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ gboolean size;
+ if (tag_len != 7)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 7", tag_len);
+ return tvb_captured_length(tvb);
+ }
+ size = (tvb_get_guint8(tvb, offset) & 0x02) >> 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_move, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ieee80211_tag_size, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_tbtt_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ if(size == TRUE) { /* if size bit is 0, the field is reserved. */
+ proto_tree_add_item(tree, hf_ieee80211_tag_bi_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ }
+ return tvb_captured_length(tvb);
+}
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_hopcount, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_ttl, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_pdid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_orig_sta, tvb, offset, 6, ENC_NA);
- offset += 6;
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_orig_sn, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
+static int
+ieee80211_tag_dmg_capabilities(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ if (tag_len != 17)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 17", tag_len);
+ return tvb_captured_length(tvb);
+ }
+ proto_tree_add_item(tree, hf_ieee80211_tag_dmg_capa_sta_addr, tvb, offset, 6, ENC_NA);
+ offset += 6;
+ proto_tree_add_item(tree, hf_ieee80211_tag_dmg_capa_aid, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_reverse_direction, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_hlts, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_tpc, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_spsh, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_rx_antenna, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_fast_link, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_num_sectors, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_rxss_length, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_reciprocity, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_max_ampdu_exp, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ offset += 3;
+ proto_tree_add_item(tree, hf_ieee80211_tag_min_mpdu_sapcing, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_ba_flow_control, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_max_sc_rx_mcs, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_max_ofdm_rx_mcs, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_max_sc_tx_mcs, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_max_ofdm_tx_mcs, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ offset += 3;
+ proto_tree_add_item(tree, hf_ieee80211_tag_low_power_supported, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_code_rate, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_dtp, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_appdu_supp, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_heartbeat, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_other_aid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_pattern_recip, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_heartbeat_elapsed, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_grant_ack_supp, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_RXSSTxRate_supp, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(tree, hf_ieee80211_tag_pcp_tddti, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_pcp_PSA, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_pcp_handover, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_pcp_max_assoc, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_pcp_power_src, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_pcp_decenter, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_pcp_forwarding, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_pcp_center, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ return tvb_captured_length(tvb);
+}
- if (flags & (1<<6)) {
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_orig_ext, tvb, offset, 6, ENC_NA);
- offset += 6;
- }
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_lifetime, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_metric, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_targ_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- targs = tvb_get_guint8(tvb, offset);
- offset += 1;
- for (i = 0; i < targs; i++) {
- const int * targ_flags[] = {
- &hf_ieee80211_ff_hwmp_targ_to_flags,
- &hf_ieee80211_ff_hwmp_targ_usn_flags,
- NULL
- };
-
- proto_tree_add_bitmask_with_flags(tree, tvb, offset, hf_ieee80211_ff_hwmp_targ_flags,
- ett_hwmp_targ_flags_tree, targ_flags, ENC_LITTLE_ENDIAN, BMT_NO_APPEND);
+static int
+ieee80211_tag_dmg_operation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ if (tag_len != 10)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 10", tag_len);
+ return tvb_captured_length(tvb);
+ }
+ proto_tree_add_item(tree, hf_ieee80211_tag_pcp_tddti, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ieee80211_tag_pcp_PSA, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ieee80211_tag_pcp_handover, tvb, offset, 1, ENC_NA);
+ offset += 2;
+ proto_tree_add_item(tree, hf_ieee80211_tag_PSRSI, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_min_BHI_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(tree, hf_ieee80211_tag_brdct_sta_info_dur, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_assoc_resp_confirm_time, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_min_pp_duration, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_SP_idle_timeout, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_max_lost_beacons, tvb, offset, 1, ENC_NA);
+ return tvb_captured_length(tvb);
+}
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_targ_sta, tvb, offset, 6, ENC_NA);
- offset += 6;
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_targ_sn, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
- }
- break;
- }
+static int
+ieee80211_tag_antenna_section_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ if (tag_len != 4)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 4", tag_len);
+ return tvb_captured_length(tvb);
+ }
+ proto_tree_add_item(tree, hf_ieee80211_tag_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_tap1, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_state1, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_tap2, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_state2, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ return tvb_captured_length(tvb);
+}
- case TAG_MESH_PREP:
- {
- guint8 flags = tvb_get_guint8(tvb, offset + 2);
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_hopcount, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_ttl, tvb, offset , 1, ENC_LITTLE_ENDIAN);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_targ_sta, tvb, offset, 6, ENC_NA);
- offset += 6;
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_targ_sn, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
- if (flags & (1<<6)) {
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_targ_ext, tvb, offset, 6, ENC_NA);
- offset += 6;
- }
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_lifetime, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_metric, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_orig_sta, tvb, offset, 6, ENC_NA);
- offset += 6;
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_orig_sn, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
- break;
- }
+static int
+ieee80211_tag_extended_schedule(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ int i;
+ gboolean isGrant;
+ proto_tree * alloc_tree;
+ if ((tag_len%15) != 0)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be N*15 where 0<=N<=17", tag_len);
+ return tvb_captured_length(tvb);
+ }
+ isGrant = ((field_data->ftype==CTRL_GRANT)||(field_data->ftype==CTRL_GRANT_ACK));
+ for(i=0; i < tag_len; i+=15) {
+ alloc_tree = proto_tree_add_subtree_format(tree, tvb, offset, 15, ett_allocation_tree, NULL, "Allocation %d", i/15);
+ proto_tree_add_item(alloc_tree, hf_ieee80211_tag_allocation_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(alloc_tree, hf_ieee80211_tag_allocation_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(alloc_tree, hf_ieee80211_tag_pseudo_static, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(alloc_tree, hf_ieee80211_tag_truncatable, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(alloc_tree, hf_ieee80211_tag_extendable, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(alloc_tree, hf_ieee80211_tag_pcp_active, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(alloc_tree, hf_ieee80211_tag_lp_sc_used, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ offset += add_ff_beamforming_ctrl(alloc_tree, tvb, pinfo, offset, isGrant);
+ proto_tree_add_item(alloc_tree, hf_ieee80211_tag_src_aid, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(alloc_tree, hf_ieee80211_tag_dest_aid, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(alloc_tree, hf_ieee80211_tag_alloc_start, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(alloc_tree, hf_ieee80211_tag_alloc_block_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(alloc_tree, hf_ieee80211_tag_num_blocks, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(alloc_tree, hf_ieee80211_tag_alloc_block_period, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ }
+ return tvb_captured_length(tvb);
+}
- case TAG_MESH_PERR:
- {
- guint8 targs, i;
+static int
+ieee80211_tag_sta_availability(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ int i;
+ proto_tree * sta_info_tree;
+ if ((tag_len%2) != 0)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be N*2 where N>=0", tag_len);
+ return tvb_captured_length(tvb);
+ }
+ for(i=0; i < tag_len; i+=2) {
+ sta_info_tree = proto_tree_add_subtree_format(tree, tvb, offset, 2, ett_sta_info, NULL, "STA Info %d", i/2);
+ proto_tree_add_item(sta_info_tree, hf_ieee80211_tag_aid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(sta_info_tree, hf_ieee80211_tag_cbap, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(sta_info_tree, hf_ieee80211_tag_pp_avail, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ }
+ return tvb_captured_length(tvb);
+}
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_ttl, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_targ_count, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- targs = tvb_get_guint8(tvb, offset);
- offset += 1;
- for (i = 0; i < targs; i++) {
- guint8 flags = tvb_get_guint8(tvb, offset);
+static int
+ieee80211_tag_next_dmg_ati(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ if (tag_len != 6)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 6", tag_len);
+ return tvb_captured_length(tvb);
+ }
+ proto_tree_add_item(tree, hf_ieee80211_tag_next_ati_start_time, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(tree, hf_ieee80211_tag_next_ati_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ return tvb_captured_length(tvb);
+}
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_targ_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_targ_sta, tvb, offset, 6, ENC_NA);
- offset += 6;
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_targ_sn, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
- if (flags & (1<<6)) {
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_targ_ext, tvb, offset, 6, ENC_NA);
- offset += 6;
- }
- offset += add_ff_reason_code(tree, tvb, pinfo, offset);
- }
- break;
- }
+static int
+ieee80211_tag_nextpcp_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ int i;
+ if (tag_len < 1)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be at least 1", tag_len);
+ return tvb_captured_length(tvb);
+ }
+ proto_tree_add_item(tree, hf_ieee80211_tag_nextpcp_token, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ for(i=0; i < tag_len-1; i+=1) {
+ proto_tree_add_item(tree, hf_ieee80211_tag_nextpcp_list, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ }
+ return tvb_captured_length(tvb);
+}
- case TAG_RANN:
- {
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_rann_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_hopcount, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_ttl, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_rann_root_sta, tvb, offset, 6, ENC_NA);
- offset += 6;
- proto_tree_add_item(tree, hf_ieee80211_rann_sn, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
- proto_tree_add_item(tree, hf_ieee80211_rann_interval, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
- proto_tree_add_item(tree, hf_ieee80211_ff_hwmp_metric, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
- break;
- }
+static int
+ieee80211_tag_pcp_handover(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ if (tag_len != 13)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be 13", tag_len);
+ return tvb_captured_length(tvb);
+ }
+ proto_tree_add_item(tree, hf_ieee80211_tag_old_bssid, tvb, offset, 6, ENC_NA);
+ offset += 6;
+ proto_tree_add_item(tree, hf_ieee80211_tag_new_pcp_addr, tvb, offset, 6, ENC_NA);
+ offset += 6;
+ proto_tree_add_item(tree, hf_ieee80211_tag_reamaining_BI, tvb, offset, 1, ENC_NA);
+ return tvb_captured_length(tvb);
+}
- case TAG_MESH_CHANNEL_SWITCH: /* Mesh Channel Switch Parameters (118) */
- {
- proto_item *item;
- proto_tree *subtree;
- if (tag_len != 6)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 6", tag_len);
- break;
- }
- offset += 2;
+static int
+ieee80211_tag_beamlink_maintenance(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ if (tag_len != 1)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be 1", tag_len);
+ return tvb_captured_length(tvb);
+ }
+ add_ff_beamformed_link(tree, tvb, pinfo, offset);
+ return tvb_captured_length(tvb);
+}
- proto_tree_add_item(tree, hf_ieee80211_mesh_channel_switch_ttl, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_item_append_text(ti, " TTL: %d", tvb_get_guint8(tvb, offset));
- offset += 1;
+static int
+ieee80211_tag_quiet_period_res(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ if (tag_len != 10)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be 10", tag_len);
+ return tvb_captured_length(tvb);
+ }
+ proto_tree_add_item(tree, hf_ieee80211_tag_request_token, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(tree, hf_ieee80211_tag_bssid, tvb, offset, 6, ENC_NA);
+ offset += 6;
+ add_ff_sta_address(tree, tvb, pinfo, offset);
+ return tvb_captured_length(tvb);
+}
- item = proto_tree_add_item(tree, hf_ieee80211_mesh_channel_switch_flag, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- subtree = proto_item_add_subtree(item, ett_mesh_chswitch_flag_tree);
- proto_tree_add_item(subtree, hf_ieee80211_mesh_chswitch_flag_initiator, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(subtree, hf_ieee80211_mesh_chswitch_flag_txrestrict, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- offset += 1;
+static int
+ieee80211_tag_relay_transfer_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
- proto_tree_add_item(tree, hf_ieee80211_mesh_channel_switch_reason_code, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
+ if (tag_len != 8)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be 8", tag_len);
+ return tvb_captured_length(tvb);
+ }
+ proto_tree_add_item(tree, hf_ieee80211_tag_duplex_relay, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ieee80211_tag_cooperation_relay, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ieee80211_tag_tx_mode, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ieee80211_tag_link_change_interval, tvb, offset+1, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ieee80211_tag_data_sensing_time, tvb, offset+2, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ieee80211_tag_first_period, tvb, offset+3, 2, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_second_period, tvb, offset+5, 2, ENC_LITTLE_ENDIAN);
+ return tvb_captured_length(tvb);
+}
- proto_tree_add_item(tree, hf_ieee80211_mesh_channel_switch_precedence_value, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- break;
- }
+static int
+ieee80211_tag_dmg_beam_refinement(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
- case TAG_INTERWORKING:
- dissect_interworking(pinfo, tree, ti, tvb, offset);
- break;
- case TAG_ADVERTISEMENT_PROTOCOL:
- {
- dissect_advertisement_protocol(pinfo, tree, tvb, offset, NULL);
- break;
- }
- case TAG_QOS_MAP_SET:
- dissect_qos_map_set(pinfo, tree, ti, tvb, offset);
- break;
- case TAG_ROAMING_CONSORTIUM:
- dissect_roaming_consortium(pinfo, tree, ti, tvb, offset);
- break;
- case TAG_AP_CHANNEL_REPORT: /* 7.3.2.36 AP Channel Report element */
- dissect_ap_channel_report(tvb, pinfo, tree, offset + 2, tag_len, ti_len, tag_end, ti);
- break;
- case TAG_NEIGHBOR_REPORT:
- dissect_neighbor_report(tvb, pinfo, tree, offset + 2, tag_len, ti_len, tag_end, ti);
- break;
+ if (tag_len != 5)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be 5", tag_len);
+ return tvb_captured_length(tvb);
+ }
+ proto_tree_add_item(tree, hf_ieee80211_tag_initiator, tvb, offset, 5, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_tx_train_res, tvb, offset, 5, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_rx_train_res, tvb, offset, 5, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_tx_trn_ok, tvb, offset, 5, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_txss_fbck_req, tvb, offset, 5, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_bs_fbck, tvb, offset, 5, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_bs_fbck_antenna_id, tvb, offset, 5, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_snr_requested, tvb, offset, 5, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_channel_measurement_requested, tvb, offset, 5, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_number_of_taps_requested, tvb, offset, 5, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_sector_id_order_req, tvb, offset, 5, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_snr_present, tvb, offset, 5, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_channel_measurement_present, tvb, offset, 5, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_tap_delay_present, tvb, offset, 5, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_number_of_taps_present, tvb, offset, 5, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_number_of_measurement, tvb, offset, 5, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_sector_id_order_present, tvb, offset, 5, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_number_of_beams, tvb, offset, 5, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_mid_extension, tvb, offset, 5, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_capability_request, tvb, offset, 5, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_beam_refine_reserved, tvb, offset, 5, ENC_LITTLE_ENDIAN);
+ return tvb_captured_length(tvb);
+}
- case TAG_EXTENDED_CHANNEL_SWITCH_ANNOUNCEMENT:
- {
- if (tag_len != 4)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 4", tag_len);
- break;
- }
+static int
+ieee80211_tag_wakeup_schedule_ad(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
- offset += 2;
+ if (tag_len != 8)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be 8", tag_len);
+ return tvb_captured_length(tvb);
+ }
+ proto_tree_add_item(tree, hf_ieee80211_tag_bi_start_time, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(tree, hf_ieee80211_tag_sleep_cycle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(tree, hf_ieee80211_tag_num_awake_bis, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ return tvb_captured_length(tvb);
+}
- offset += add_ff_extended_channel_switch_announcement(tree, tvb, pinfo, offset);
+static int
+ieee80211_tag_dmg_tspec(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
- break;
- }
- case TAG_SUPPORTED_OPERATING_CLASSES:
- {
- guint i;
+ gboolean isGrant;
+ int num_constraints;
+ if (tag_len < 14)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be at least 14", tag_len);
+ return tvb_captured_length(tvb);
+ }
+ proto_tree_add_item(tree, hf_ieee80211_tag_tspec_allocation_id, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_tspec_allocation_type, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_tspec_allocation_format, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_tspec_pseudo_static, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_tspec_truncatable, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_tspec_extendable, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_tspec_lp_sc_used, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_tspec_up, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(tree, hf_ieee80211_tag_tspec_dest_aid, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ offset += 3;
+ isGrant = ((field_data->ftype==CTRL_GRANT)||(field_data->ftype==CTRL_GRANT_ACK));
+ offset += add_ff_beamforming_ctrl(tree, tvb, pinfo, 2, isGrant);
+ proto_tree_add_item(tree, hf_ieee80211_tag_tspec_allocation_period, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(tree, hf_ieee80211_tag_tspec_min_allocation, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(tree, hf_ieee80211_tag_tspec_max_allocation, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(tree, hf_ieee80211_tag_tspec_min_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ num_constraints = tvb_get_guint8(tvb, offset);
+ proto_tree_add_item(tree, hf_ieee80211_tag_tspec_num_of_constraints, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ while(num_constraints > 0) {
+ proto_tree_add_item(tree, hf_ieee80211_tag_tspec_tsconst_start_time, tvb, offset, 4, ENC_LITTLE_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(tree, hf_ieee80211_tag_tspec_tsconst_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(tree, hf_ieee80211_tag_tspec_tsconst_period, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(tree, hf_ieee80211_tag_tspec_tsconst_interferer_mac, tvb, offset, 2, ENC_NA);
+ offset += 6;
+ num_constraints--;
+ }
+ return tvb_captured_length(tvb);
+}
- if (tag_len < 2) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be >= 3", tag_len);
- break;
- } else if (tag_len > 32) {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be < 32", tag_len);
- break;
- }
+static int
+ieee80211_tag_channel_measurement_fb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
- offset += 2;
+ int num_measurement;
+ if (tag_len%5 != 0)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be multiple of 5", tag_len);
+ return tvb_captured_length(tvb);
+ }
+ num_measurement = tvb_get_guint8(tvb, offset+1);
+ offset += 2;
+ while(num_measurement > 0) {
+ proto_tree_add_item(tree, hf_ieee80211_ff_snr, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_channel_measurement_feedback_realtive_I, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_channel_measurement_feedback_realtive_Q, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_channel_measurement_feedback_tap_delay, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_channel_measurement_feedback_sector_id, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ieee80211_tag_channel_measurement_feedback_antenna_id, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ num_measurement--;
+ }
+ return tvb_captured_length(tvb);
+}
- proto_tree_add_item(tree, hf_ieee80211_tag_supported_ope_classes_current, tvb, offset, 1, ENC_NA);
+static int
+ieee80211_tag_awake_window(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
- offset += 1;
- /* Partially taken from the ssid section */
- tag_data_ptr = tvb_get_ptr(tvb, offset, tag_len);
- for (i = 0, n = 0; (i < tag_len) && (n < SHORT_STR); i++) {
- ret = g_snprintf(print_buff + n, SHORT_STR - n, (i == tag_len-1)?"%d":"%d, ", tag_data_ptr[i]);
- if (ret >= SHORT_STR - n) {
- /* ret >= <buf_size> means buffer truncated */
- break;
- }
- n += ret;
- }
- proto_tree_add_string(tree, hf_ieee80211_tag_supported_ope_classes_alternate, tvb, offset, tag_len, print_buff);
+ if (tag_len != 2)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be 2", tag_len);
+ }
+ else
+ {
+ proto_tree_add_item(tree, hf_ieee80211_tag_awake_window, tvb, 0, 2, ENC_LITTLE_ENDIAN);
+ }
+ return tvb_captured_length(tvb);
+}
- break;
- }
- case TAG_RELAY_CAPABILITIES:
- {
- add_tag_relay_capabilities(pinfo, ti_len, tag_len, tree, tvb, &offset);
- break;
- }
- case TAG_DMG_BSS_PARAMETER_CHANGE:
- {
- gboolean size;
- if (tag_len != 7)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 7", tag_len);
- break;
- }
- offset += 2;
- size = (tvb_get_guint8(tvb, offset) & 0x02) >> 1;
- proto_tree_add_item(tree, hf_ieee80211_tag_move, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_size, tvb, offset, 1, ENC_NA);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_tag_tbtt_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
- if(size == TRUE) { /* if size bit is 0, the field is reserved. */
- proto_tree_add_item(tree, hf_ieee80211_tag_bi_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- }
- offset += 2;
- break;
- }
- case TAG_DMG_CAPABILITIES:
- {
- if (tag_len != 17)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 17", tag_len);
- break;
- }
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_dmg_capa_sta_addr, tvb, offset, 6, ENC_NA);
- offset += 6;
- proto_tree_add_item(tree, hf_ieee80211_tag_dmg_capa_aid, tvb, offset, 1, ENC_NA);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_tag_reverse_direction, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_hlts, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_tpc, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_spsh, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_rx_antenna, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_fast_link, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_num_sectors, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_rxss_length, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_reciprocity, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_max_ampdu_exp, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- offset += 3;
- proto_tree_add_item(tree, hf_ieee80211_tag_min_mpdu_sapcing, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_ba_flow_control, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_max_sc_rx_mcs, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_max_ofdm_rx_mcs, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_max_sc_tx_mcs, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_max_ofdm_tx_mcs, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- offset += 3;
- proto_tree_add_item(tree, hf_ieee80211_tag_low_power_supported, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_code_rate, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_dtp, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_appdu_supp, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_heartbeat, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_other_aid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_pattern_recip, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_heartbeat_elapsed, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_grant_ack_supp, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_RXSSTxRate_supp, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_pcp_tddti, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_pcp_PSA, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_pcp_handover, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_pcp_max_assoc, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_pcp_power_src, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_pcp_decenter, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_pcp_forwarding, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_pcp_center, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- break;
- }
- case TAG_DMG_OPERATION:
- {
- if (tag_len != 10)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 10", tag_len);
- break;
- }
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_pcp_tddti, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_pcp_PSA, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_pcp_handover, tvb, offset, 1, ENC_NA);
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_PSRSI, tvb, offset, 1, ENC_NA);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_tag_min_BHI_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_brdct_sta_info_dur, tvb, offset, 1, ENC_NA);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_tag_assoc_resp_confirm_time, tvb, offset, 1, ENC_NA);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_tag_min_pp_duration, tvb, offset, 1, ENC_NA);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_tag_SP_idle_timeout, tvb, offset, 1, ENC_NA);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_tag_max_lost_beacons, tvb, offset, 1, ENC_NA);
- offset += 1;
- break;
- }
- case TAG_ANTENNA_SECTOR_ID:
- {
- if (tag_len != 4)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 4", tag_len);
- break;
- }
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_tap1, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_state1, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_tap2, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_state2, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
- break;
- }
- case TAG_EXTENDED_SCHEDULE:
- {
- guint32 i = 0;
- gboolean isGrant;
- proto_tree * alloc_tree;
- if ((tag_len%15) != 0)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be N*15 where 0<=N<=17", tag_len);
- break;
- }
- offset += 2;
- isGrant = ((ftype==CTRL_GRANT)||(ftype==CTRL_GRANT_ACK));
- for(i=0; i < tag_len; i+=15) {
- alloc_tree = proto_tree_add_subtree_format(tree, tvb, offset, 15, ett_allocation_tree, NULL, "Allocation %d", i/15);
- proto_tree_add_item(alloc_tree, hf_ieee80211_tag_allocation_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(alloc_tree, hf_ieee80211_tag_allocation_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(alloc_tree, hf_ieee80211_tag_pseudo_static, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(alloc_tree, hf_ieee80211_tag_truncatable, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(alloc_tree, hf_ieee80211_tag_extendable, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(alloc_tree, hf_ieee80211_tag_pcp_active, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(alloc_tree, hf_ieee80211_tag_lp_sc_used, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- offset += add_ff_beamforming_ctrl(alloc_tree, tvb, pinfo, offset, isGrant);
- proto_tree_add_item(alloc_tree, hf_ieee80211_tag_src_aid, tvb, offset, 1, ENC_NA);
- offset += 1;
- proto_tree_add_item(alloc_tree, hf_ieee80211_tag_dest_aid, tvb, offset, 1, ENC_NA);
- offset += 1;
- proto_tree_add_item(alloc_tree, hf_ieee80211_tag_alloc_start, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
- proto_tree_add_item(alloc_tree, hf_ieee80211_tag_alloc_block_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- proto_tree_add_item(alloc_tree, hf_ieee80211_tag_num_blocks, tvb, offset, 1, ENC_NA);
- offset += 1;
- proto_tree_add_item(alloc_tree, hf_ieee80211_tag_alloc_block_period, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- }
- break;
- }
- case TAG_STA_AVAILABILITY:
- {
- guint32 i = 0;
- proto_tree * sta_info_tree;
- if ((tag_len%2) != 0)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be N*2 where N>=0", tag_len);
- break;
- }
- offset += 2;
- for(i=0; i < tag_len; i+=2) {
- sta_info_tree = proto_tree_add_subtree_format(tree, tvb, offset, 2, ett_sta_info, NULL, "STA Info %d", i/2);
- proto_tree_add_item(sta_info_tree, hf_ieee80211_tag_aid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(sta_info_tree, hf_ieee80211_tag_cbap, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(sta_info_tree, hf_ieee80211_tag_pp_avail, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- }
- break;
- }
- case TAG_NEXT_DMG_ATI:
- {
- if (tag_len != 6)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be = 6", tag_len);
- break;
- }
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_next_ati_start_time, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
- proto_tree_add_item(tree, hf_ieee80211_tag_next_ati_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- break;
- }
- case TAG_NEXTPCP_LIST:
- {
- guint32 i = 0;
- if (tag_len < 1)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be at least 1", tag_len);
- break;
- }
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_nextpcp_token, tvb, offset, 1, ENC_NA);
- offset += 1;
- for(i=0; i < tag_len-1; i+=1) {
- proto_tree_add_item(tree, hf_ieee80211_tag_nextpcp_list, tvb, offset, 1, ENC_NA);
- offset += 1;
- }
- break;
- }
- case TAG_PCP_HANDOVER:
- {
- if (tag_len != 13)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be 13", tag_len);
- break;
- }
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_old_bssid, tvb, offset, 6, ENC_NA);
- offset += 6;
- proto_tree_add_item(tree, hf_ieee80211_tag_new_pcp_addr, tvb, offset, 6, ENC_NA);
- offset += 6;
- proto_tree_add_item(tree, hf_ieee80211_tag_reamaining_BI, tvb, offset, 1, ENC_NA);
- offset += 1;
- break;
- }
- case TAG_BEAMLINK_MAINTENANCE:
- {
- if (tag_len != 1)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be 1", tag_len);
- break;
- }
- offset += 2;
- offset += add_ff_beamformed_link(tree, tvb, pinfo, offset);
- break;
- }
- case TAG_QUIET_PERIOD_RES:
- {
- if (tag_len != 10)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be 10", tag_len);
- break;
- }
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_request_token, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_bssid, tvb, offset, 6, ENC_NA);
- offset += 6;
- offset += add_ff_sta_address(tree, tvb, pinfo, offset);
- break;
- }
- case TAG_RELAY_TRANSFER_PARAM:
- {
- if (tag_len != 8)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be 8", tag_len);
- break;
- }
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_duplex_relay, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_cooperation_relay, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_tx_mode, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_link_change_interval, tvb, offset+1, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_data_sensing_time, tvb, offset+2, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_first_period, tvb, offset+3, 2, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_second_period, tvb, offset+5, 2, ENC_LITTLE_ENDIAN);
- offset += 8;
- break;
- }
- case TAG_DMG_BEAM_REFINEMENT:
- {
- if (tag_len != 5)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be 5", tag_len);
- break;
- }
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_initiator, tvb, offset, 5, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_tx_train_res, tvb, offset, 5, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_rx_train_res, tvb, offset, 5, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_tx_trn_ok, tvb, offset, 5, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_txss_fbck_req, tvb, offset, 5, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_bs_fbck, tvb, offset, 5, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_bs_fbck_antenna_id, tvb, offset, 5, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_snr_requested, tvb, offset, 5, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_channel_measurement_requested, tvb, offset, 5, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_number_of_taps_requested, tvb, offset, 5, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_sector_id_order_req, tvb, offset, 5, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_snr_present, tvb, offset, 5, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_channel_measurement_present, tvb, offset, 5, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_tap_delay_present, tvb, offset, 5, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_number_of_taps_present, tvb, offset, 5, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_number_of_measurement, tvb, offset, 5, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_sector_id_order_present, tvb, offset, 5, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_number_of_beams, tvb, offset, 5, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_mid_extension, tvb, offset, 5, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_capability_request, tvb, offset, 5, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_beam_refine_reserved, tvb, offset, 5, ENC_LITTLE_ENDIAN);
- offset += 5;
- break;
- }
- case TAG_WAKEUP_SCHEDULE_AD:
- {
- if (tag_len != 8)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be 8", tag_len);
- break;
- }
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_bi_start_time, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
- proto_tree_add_item(tree, hf_ieee80211_tag_sleep_cycle, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_num_awake_bis, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- break;
- }
- case TAG_DMG_TSPEC:
- {
- gboolean isGrant;
- int num_constraints;
- if (tag_len < 14)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be at least 14", tag_len);
- break;
- }
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_tspec_allocation_id, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_tspec_allocation_type, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_tspec_allocation_format, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_tspec_pseudo_static, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_tspec_truncatable, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_tspec_extendable, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_tspec_lp_sc_used, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_tspec_up, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(tree, hf_ieee80211_tag_tspec_dest_aid, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- offset += 3;
- isGrant = ((ftype==CTRL_GRANT)||(ftype==CTRL_GRANT_ACK));
- offset += add_ff_beamforming_ctrl(tree, tvb, pinfo, 2, isGrant);
- proto_tree_add_item(tree, hf_ieee80211_tag_tspec_allocation_period, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_tspec_min_allocation, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_tspec_max_allocation, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_tspec_min_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- num_constraints = tvb_get_guint8(tvb, offset);
- proto_tree_add_item(tree, hf_ieee80211_tag_tspec_num_of_constraints, tvb, offset, 1, ENC_NA);
- offset += 1;
- while(num_constraints > 0) {
- proto_tree_add_item(tree, hf_ieee80211_tag_tspec_tsconst_start_time, tvb, offset, 4, ENC_LITTLE_ENDIAN);
- offset += 4;
- proto_tree_add_item(tree, hf_ieee80211_tag_tspec_tsconst_duration, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_tspec_tsconst_period, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_tspec_tsconst_interferer_mac, tvb, offset, 2, ENC_NA);
- offset += 6;
- num_constraints--;
- }
- break;
- }
- case TAG_CHANNEL_MEASURMENT_FB:
- {
- int num_measurement;
- if (tag_len%5 != 0)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be multiple of 5", tag_len);
- break;
- }
- num_measurement = tvb_get_guint8(tvb, offset+1);
- offset += 2;
- while(num_measurement > 0) {
- proto_tree_add_item(tree, hf_ieee80211_ff_snr, tvb, offset, 1, ENC_NA);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_tag_channel_measurement_feedback_realtive_I, tvb, offset, 1, ENC_NA);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_tag_channel_measurement_feedback_realtive_Q, tvb, offset, 1, ENC_NA);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_tag_channel_measurement_feedback_tap_delay, tvb, offset, 1, ENC_NA);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_tag_channel_measurement_feedback_sector_id, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_channel_measurement_feedback_antenna_id, tvb, offset, 1, ENC_NA);
- offset += 1;
- num_measurement--;
- }
- break;
- }
- case TAG_AWAKE_WINDOW:
- {
- if (tag_len != 2)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be 2", tag_len);
- break;
- }
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_awake_window, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- offset += 2;
- break;
- }
- case TAG_ADDBA_EXT:
- {
- if (tag_len != 1)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be 1", tag_len);
- break;
- }
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_addba_ext_no_frag, tvb, offset, 1, ENC_NA);
- offset += 1;
- break;
- }
- case TAG_MULTI_BAND:
- {
- gboolean chiper_present, addr_present;
- if (tag_len < 22)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be at least 22", tag_len);
- break;
- }
- offset += 2;
- chiper_present = (tvb_get_letohs(tvb, offset) & 0x08) >> 3;
- addr_present = (tvb_get_letohs(tvb, offset) & 0x10) >> 4;
- proto_tree_add_item(tree, hf_ieee80211_tag_multi_band_ctrl_sta_role, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_multi_band_ctrl_addr_present, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_multi_band_ctrl_cipher_present, tvb, offset, 1, ENC_NA);
- offset += 1;
- offset += add_ff_band_id(tree, tvb, pinfo, 1);
- proto_tree_add_item(tree, hf_ieee80211_tag_multi_band_oper_class, tvb, offset, 1, ENC_NA);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_tag_multi_band_channel_number, tvb, offset, 1, ENC_NA);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_tag_bssid, tvb, offset, 6, ENC_NA);
- offset += 6;
- offset += add_ff_beacon_interval(tree, tvb, pinfo, 2);
- proto_tree_add_item(tree, hf_ieee80211_tag_multi_band_tsf_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
- offset += 8;
- proto_tree_add_item(tree, hf_ieee80211_tag_multi_band_conn_ap, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_multi_band_conn_pcp, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_multi_band_conn_dls, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_multi_band_conn_tdls, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_multi_band_conn_ibss, tvb, offset, 1, ENC_NA);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_tag_multi_band_fst_timeout, tvb, offset, 1, ENC_NA);
- offset += 1;
- if(addr_present)
- {
- proto_tree_add_item(tree, hf_ieee80211_tag_multi_band_sta_mac, tvb, offset, 6, ENC_NA);
- offset += 6;
- }
- if(chiper_present)
- {
- proto_item *rsn_pcs_count, *rsn_pcs_item, *rsn_sub_pcs_item;
- proto_tree *rsn_pcs_tree, *rsn_sub_pcs_tree;
- gint ii;
- guint16 pcs_count;
- rsn_pcs_count = proto_tree_add_item(tree, hf_ieee80211_rsn_pcs_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- pcs_count = tvb_get_letohs(tvb, offset);
- offset += 2;
+static int
+ieee80211_tag_addba_ext(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
- if (offset + (pcs_count * 4) > tag_end)
- {
- expert_add_info_format(pinfo, rsn_pcs_count, &ei_ieee80211_rsn_pcs_count,
- "Pairwise Cipher Suite Count too large, 4*%u > %d", pcs_count, tag_end - offset);
- pcs_count = (tag_end - offset) / 4;
- }
+ if (tag_len != 1)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be 1", tag_len);
+ }
+ else
+ {
+ proto_tree_add_item(tree, hf_ieee80211_tag_addba_ext_no_frag, tvb, 0, 1, ENC_NA);
+ }
+ return tvb_captured_length(tvb);
+}
- rsn_pcs_item = proto_tree_add_item(tree, hf_ieee80211_rsn_pcs_list, tvb, offset, pcs_count * 4, ENC_NA);
- rsn_pcs_tree = proto_item_add_subtree(rsn_pcs_item, ett_rsn_pcs_tree);
- for (ii = 0; ii < pcs_count; ii++)
- {
- rsn_sub_pcs_item = proto_tree_add_item(rsn_pcs_tree, hf_ieee80211_rsn_pcs, tvb, offset, 4, ENC_BIG_ENDIAN);
- rsn_sub_pcs_tree = proto_item_add_subtree(rsn_sub_pcs_item, ett_rsn_sub_pcs_tree);
- proto_tree_add_item(rsn_sub_pcs_tree, hf_ieee80211_rsn_pcs_oui, tvb, offset, 3, ENC_BIG_ENDIAN);
+static int
+ieee80211_tag_multi_band(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+ gboolean chiper_present, addr_present;
- /* Check if OUI is 00:0F:AC (ieee80211) */
- if (tvb_get_ntoh24(tvb, offset) == OUI_RSN)
- {
- proto_tree_add_item(rsn_sub_pcs_tree, hf_ieee80211_rsn_pcs_80211_type, tvb, offset+3, 1, ENC_LITTLE_ENDIAN);
- proto_item_append_text(rsn_pcs_item, " %s", rsn_pcs_return(tvb_get_ntohl(tvb, offset)));
- } else {
- proto_tree_add_item(rsn_sub_pcs_tree, hf_ieee80211_rsn_pcs_type, tvb, offset+3, 1, ENC_LITTLE_ENDIAN);
- }
- offset += 4;
- }
- }
- break;
- }
- case TAG_DMG_LINK_MARGIN:
+ if (tag_len < 22)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be at least 22", tag_len);
+ return tvb_captured_length(tvb);
+ }
+ chiper_present = (tvb_get_letohs(tvb, offset) & 0x08) >> 3;
+ addr_present = (tvb_get_letohs(tvb, offset) & 0x10) >> 4;
+ proto_tree_add_item(tree, hf_ieee80211_tag_multi_band_ctrl_sta_role, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ieee80211_tag_multi_band_ctrl_addr_present, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ieee80211_tag_multi_band_ctrl_cipher_present, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ offset += add_ff_band_id(tree, tvb, pinfo, 1);
+ proto_tree_add_item(tree, hf_ieee80211_tag_multi_band_oper_class, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_multi_band_channel_number, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_bssid, tvb, offset, 6, ENC_NA);
+ offset += 6;
+ offset += add_ff_beacon_interval(tree, tvb, pinfo, 2);
+ proto_tree_add_item(tree, hf_ieee80211_tag_multi_band_tsf_offset, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ offset += 8;
+ proto_tree_add_item(tree, hf_ieee80211_tag_multi_band_conn_ap, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ieee80211_tag_multi_band_conn_pcp, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ieee80211_tag_multi_band_conn_dls, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ieee80211_tag_multi_band_conn_tdls, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ieee80211_tag_multi_band_conn_ibss, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_multi_band_fst_timeout, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ if(addr_present)
+ {
+ proto_tree_add_item(tree, hf_ieee80211_tag_multi_band_sta_mac, tvb, offset, 6, ENC_NA);
+ offset += 6;
+ }
+ if(chiper_present)
+ {
+ proto_item *rsn_pcs_count, *rsn_pcs_item, *rsn_sub_pcs_item;
+ proto_tree *rsn_pcs_tree, *rsn_sub_pcs_tree;
+ gint ii;
+ guint16 pcs_count;
+ int tag_end = tvb_reported_length(tvb);
+ rsn_pcs_count = proto_tree_add_item(tree, hf_ieee80211_rsn_pcs_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ pcs_count = tvb_get_letohs(tvb, offset);
+ offset += 2;
+
+ if (offset + (pcs_count * 4) > tag_end)
{
- if (tag_len != 8)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be 8", tag_len);
- break;
- }
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_activity, tvb, offset, 1, ENC_NA);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_tag_dmg_link_adapt_mcs, tvb, offset, 1, ENC_NA);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_tag_dmg_link_adapt_link_margin, tvb, offset, 1, ENC_NA);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_ff_snr, tvb, offset, 1, ENC_NA);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_tag_ref_timestamp, tvb, offset, 3, ENC_LITTLE_ENDIAN);
- offset += 4;
- break;
+ expert_add_info_format(pinfo, rsn_pcs_count, &ei_ieee80211_rsn_pcs_count,
+ "Pairwise Cipher Suite Count too large, 4*%u > %d", pcs_count, tag_end - offset);
+ pcs_count = (tag_end - offset) / 4;
}
- case TAG_DMG_LINK_ADAPTION_ACK:
+
+ rsn_pcs_item = proto_tree_add_item(tree, hf_ieee80211_rsn_pcs_list, tvb, offset, pcs_count * 4, ENC_NA);
+ rsn_pcs_tree = proto_item_add_subtree(rsn_pcs_item, ett_rsn_pcs_tree);
+ for (ii = 0; ii < pcs_count; ii++)
{
- if (tag_len != 5)
+ rsn_sub_pcs_item = proto_tree_add_item(rsn_pcs_tree, hf_ieee80211_rsn_pcs, tvb, offset, 4, ENC_BIG_ENDIAN);
+ rsn_sub_pcs_tree = proto_item_add_subtree(rsn_sub_pcs_item, ett_rsn_sub_pcs_tree);
+ proto_tree_add_item(rsn_sub_pcs_tree, hf_ieee80211_rsn_pcs_oui, tvb, offset, 3, ENC_BIG_ENDIAN);
+
+ /* Check if OUI is 00:0F:AC (ieee80211) */
+ if (tvb_get_ntoh24(tvb, offset) == OUI_RSN)
{
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be 5", tag_len);
- break;
+ proto_tree_add_item(rsn_sub_pcs_tree, hf_ieee80211_rsn_pcs_80211_type, tvb, offset+3, 1, ENC_LITTLE_ENDIAN);
+ proto_item_append_text(rsn_pcs_item, " %s", rsn_pcs_return(tvb_get_ntohl(tvb, offset)));
+ } else {
+ proto_tree_add_item(rsn_sub_pcs_tree, hf_ieee80211_rsn_pcs_type, tvb, offset+3, 1, ENC_LITTLE_ENDIAN);
}
- offset += 2;
- proto_tree_add_item(tree, hf_ieee80211_tag_activity, tvb, offset, 1, ENC_NA);
- offset += 1;
- proto_tree_add_item(tree, hf_ieee80211_tag_ref_timestamp, tvb, offset, 3, ENC_LITTLE_ENDIAN);
offset += 4;
- break;
}
- case TAG_SWITCHING_STREAM:
- {
- int param_num;
- if (tag_len < 4)
- {
- expert_add_info_format(pinfo, ti_len, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be at least 4", tag_len);
- break;
- }
- offset += 2;
- offset += add_ff_band_id(tree, tvb, pinfo, 1);
- offset += add_ff_band_id(tree, tvb, pinfo, 1);
- proto_tree_add_item(tree, hf_ieee80211_tag_switching_stream_non_qos, tvb, offset, 1, ENC_NA);
- offset += 1;
- param_num = tvb_get_letohs(tvb, offset);
- proto_tree_add_item(tree, hf_ieee80211_tag_switching_stream_param_num, tvb, offset, 1, ENC_NA);
- offset += 1;
- while(param_num > 0)
- {
- proto_tree_add_item(tree, hf_ieee80211_tag_switching_stream_old_tid, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_switching_stream_old_direction, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_switching_stream_new_tid, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_switching_stream_new_direction, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_switching_stream_new_valid_id, tvb, offset, 1, ENC_NA);
- proto_tree_add_item(tree, hf_ieee80211_tag_switching_stream_llt_type, tvb, offset, 1, ENC_NA);
- param_num--;
- offset += 2;
- }
- break;
- }
- default:
- proto_tree_add_item(tree, hf_ieee80211_tag_data, tvb, offset + 1 + 1, tag_len, ENC_NA);
- expert_add_info_format(pinfo, ti_tag, &ei_ieee80211_tag_data,
- "Dissector for 802.11 IE Tag"
- " (%s) code not implemented, Contact"
- " Wireshark developers if you want this supported", val_to_str_ext(tag_no,
- &tag_num_vals_ext, "(%d)"));
- proto_item_append_text(ti, ": Undecoded");
- break;
}
- if (offset < tag_end) {
- /* TODO: add Expert info to indicate there is unknown data ! but all tagged option don't yet return offset.
- For the moment, this code only remove Clang Warnings about not used offset... */
+
+ return tvb_captured_length(tvb);
+}
+
+static int
+ieee80211_tag_dmg_link_margin(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+
+ if (tag_len != 8)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be 8", tag_len);
+ return tvb_captured_length(tvb);
}
-end_of_tag:
- return tag_len + 1 + 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_activity, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_dmg_link_adapt_mcs, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_dmg_link_adapt_link_margin, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_ff_snr, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_ref_timestamp, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ return tvb_captured_length(tvb);
+}
+
+static int
+ieee80211_tag_dmg_link_adaption_ack(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+
+ if (tag_len != 5)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be 5", tag_len);
+ return tvb_captured_length(tvb);
+ }
+ proto_tree_add_item(tree, hf_ieee80211_tag_activity, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tree, hf_ieee80211_tag_ref_timestamp, tvb, offset, 3, ENC_LITTLE_ENDIAN);
+ return tvb_captured_length(tvb);
+}
+
+static int
+ieee80211_tag_switching_stream(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
+{
+ int tag_len = tvb_reported_length(tvb);
+ ieee80211_tagged_field_data_t* field_data = (ieee80211_tagged_field_data_t*)data;
+ int offset = 0;
+
+ int param_num;
+ if (tag_len < 4)
+ {
+ expert_add_info_format(pinfo, field_data->item_tag_length, &ei_ieee80211_tag_length, "Tag Length %u wrong, must be at least 4", tag_len);
+ return tvb_captured_length(tvb);
+ }
+ offset += add_ff_band_id(tree, tvb, pinfo, 1);
+ offset += add_ff_band_id(tree, tvb, pinfo, 1);
+ proto_tree_add_item(tree, hf_ieee80211_tag_switching_stream_non_qos, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ param_num = tvb_get_letohs(tvb, offset);
+ proto_tree_add_item(tree, hf_ieee80211_tag_switching_stream_param_num, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ while(param_num > 0)
+ {
+ proto_tree_add_item(tree, hf_ieee80211_tag_switching_stream_old_tid, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ieee80211_tag_switching_stream_old_direction, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ieee80211_tag_switching_stream_new_tid, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ieee80211_tag_switching_stream_new_direction, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ieee80211_tag_switching_stream_new_valid_id, tvb, offset, 1, ENC_NA);
+ proto_tree_add_item(tree, hf_ieee80211_tag_switching_stream_llt_type, tvb, offset, 1, ENC_NA);
+ param_num--;
+ offset += 2;
+ }
+ return tvb_captured_length(tvb);
}
static void
@@ -27581,6 +27612,8 @@ proto_register_ieee80211(void)
ether_len, ether_name_resolution_str, ether_name_resolution_len);
set_address(&bssid_broadcast, wlan_bssid_address_type, 6, bssid_broadcast_data);
+ tagged_field_table = register_dissector_table("wlan.tag.number", "IEEE 802.11 Fields", proto_wlan, FT_UINT8, BASE_DEC);
+
/* Register configuration options */
wlan_module = prefs_register_protocol(proto_wlan, init_wepkeys);
prefs_register_bool_preference(wlan_module, "defragment",
@@ -27838,6 +27871,128 @@ proto_reg_handoff_ieee80211(void)
dissector_add_uint("eapol.keydes.type", EAPOL_RSN_KEY, wlan_rsna_eapol_rsn_key_handle);
dissector_add_uint("sflow_245.header_protocol", SFLOW_5_HEADER_80211_MAC, wlan_withoutfcs_handle);
+
+ /* Tagged fields */
+ /* XXX - for now, do it without pinos so the protocol is -1 */
+ dissector_add_uint("wlan.tag.number", TAG_SSID, create_dissector_handle(ieee80211_tag_ssid, -1));
+ dissector_add_uint("wlan.tag.number", TAG_SUPP_RATES, create_dissector_handle(ieee80211_tag_supp_rates, -1));
+ dissector_add_uint("wlan.tag.number", TAG_FH_PARAMETER, create_dissector_handle(ieee80211_tag_fh_parameter, -1));
+ dissector_add_uint("wlan.tag.number", TAG_DS_PARAMETER, create_dissector_handle(ieee80211_tag_ds_parameter, -1));
+ dissector_add_uint("wlan.tag.number", TAG_CF_PARAMETER, create_dissector_handle(ieee80211_tag_cf_parameter, -1));
+ dissector_add_uint("wlan.tag.number", TAG_TIM, create_dissector_handle(ieee80211_tag_tim, -1));
+ dissector_add_uint("wlan.tag.number", TAG_IBSS_PARAMETER, create_dissector_handle(ieee80211_tag_ibss_parameter, -1));
+ dissector_add_uint("wlan.tag.number", TAG_COUNTRY_INFO, create_dissector_handle(ieee80211_tag_country_info, -1));
+ dissector_add_uint("wlan.tag.number", TAG_FH_HOPPING_PARAMETER, create_dissector_handle(ieee80211_tag_fh_hopping_parameter, -1));
+ dissector_add_uint("wlan.tag.number", TAG_FH_HOPPING_TABLE, create_dissector_handle(ieee80211_tag_fh_hopping_table, -1));
+ dissector_add_uint("wlan.tag.number", TAG_REQUEST, create_dissector_handle(ieee80211_tag_request, -1));
+ dissector_add_uint("wlan.tag.number", TAG_QBSS_LOAD, create_dissector_handle(ieee80211_tag_qbss_load, -1));
+#if 0
+ dissector_add_uint("wlan.tag.number", TAG_EDCA_PARAM_SET, create_dissector_handle(ieee80211_tag_edca_param_set, -1));
+#endif
+ dissector_add_uint("wlan.tag.number", TAG_TSPEC, create_dissector_handle(ieee80211_tag_tspec, -1));
+ dissector_add_uint("wlan.tag.number", TAG_TCLAS, create_dissector_handle(ieee80211_tag_tclas, -1));
+ dissector_add_uint("wlan.tag.number", TAG_SCHEDULE, create_dissector_handle(ieee80211_tag_schedule, -1));
+ dissector_add_uint("wlan.tag.number", TAG_CHALLENGE_TEXT, create_dissector_handle(ieee80211_tag_challenge_text, -1));
+ dissector_add_uint("wlan.tag.number", TAG_POWER_CONSTRAINT, create_dissector_handle(ieee80211_tag_power_constraint, -1));
+ dissector_add_uint("wlan.tag.number", TAG_POWER_CAPABILITY, create_dissector_handle(ieee80211_tag_power_capability, -1));
+ dissector_add_uint("wlan.tag.number", TAG_TPC_REQUEST, create_dissector_handle(ieee80211_tag_tpc_request, -1));
+ dissector_add_uint("wlan.tag.number", TAG_TPC_REPORT, create_dissector_handle(ieee80211_tag_tpc_report, -1));
+ dissector_add_uint("wlan.tag.number", TAG_SUPPORTED_CHANNELS, create_dissector_handle(ieee80211_tag_supported_channels, -1));
+ dissector_add_uint("wlan.tag.number", TAG_CHANNEL_SWITCH_ANN, create_dissector_handle(ieee80211_tag_switch_ann, -1));
+ dissector_add_uint("wlan.tag.number", TAG_MEASURE_REQ, create_dissector_handle(ieee80211_tag_measure_req, -1));
+ dissector_add_uint("wlan.tag.number", TAG_MEASURE_REP, create_dissector_handle(ieee80211_tag_measure_rep, -1));
+ dissector_add_uint("wlan.tag.number", TAG_QUIET, create_dissector_handle(ieee80211_tag_quiet, -1));
+ dissector_add_uint("wlan.tag.number", TAG_IBSS_DFS, create_dissector_handle(ieee80211_tag_ibss_dfs, -1));
+ dissector_add_uint("wlan.tag.number", TAG_ERP_INFO, create_dissector_handle(ieee80211_tag_erp_info, -1));
+ dissector_add_uint("wlan.tag.number", TAG_ERP_INFO_OLD, create_dissector_handle(ieee80211_tag_erp_info, -1));
+ dissector_add_uint("wlan.tag.number", TAG_TS_DELAY, create_dissector_handle(ieee80211_tag_ts_delay, -1));
+ dissector_add_uint("wlan.tag.number", TAG_TCLAS_PROCESS, create_dissector_handle(ieee80211_tag_tclas_process, -1));
+ dissector_add_uint("wlan.tag.number", TAG_QOS_CAPABILITY, create_dissector_handle(ieee80211_tag_qos_capability, -1));
+ dissector_add_uint("wlan.tag.number", TAG_RSN_IE, create_dissector_handle(ieee80211_tag_rsn_ie, -1));
+ dissector_add_uint("wlan.tag.number", TAG_EXT_SUPP_RATES, create_dissector_handle(ieee80211_tag_ext_supp_rates, -1));
+ dissector_add_uint("wlan.tag.number", TAG_EXTENDED_CAPABILITIES, create_dissector_handle(dissect_extended_capabilities_ie, -1));
+ dissector_add_uint("wlan.tag.number", TAG_CISCO_CCX1_CKIP, create_dissector_handle(ieee80211_tag_cisco_ccx1_ckip, -1));
+ dissector_add_uint("wlan.tag.number", TAG_VHT_CAPABILITY, create_dissector_handle(dissect_vht_capability_ie, -1));
+ dissector_add_uint("wlan.tag.number", TAG_VHT_OPERATION, create_dissector_handle(dissect_vht_operation_ie, -1));
+ dissector_add_uint("wlan.tag.number", TAG_EXT_BSS_LOAD, create_dissector_handle(dissect_ext_bss_load, -1));
+ dissector_add_uint("wlan.tag.number", TAG_WIDE_BW_CHANNEL_SWITCH, create_dissector_handle(dissect_wide_bw_channel_switch, -1));
+ dissector_add_uint("wlan.tag.number", TAG_VHT_TX_PWR_ENVELOPE, create_dissector_handle(dissect_vht_tx_pwr_envelope, -1));
+ dissector_add_uint("wlan.tag.number", TAG_CHANNEL_SWITCH_WRAPPER, create_dissector_handle(dissect_channel_switch_wrapper, -1));
+ dissector_add_uint("wlan.tag.number", TAG_OPERATING_MODE_NOTIFICATION, create_dissector_handle(dissect_operating_mode_notification, -1));
+ /* 7.3.2.26 Vendor Specific information element (221) */
+ dissector_add_uint("wlan.tag.number", TAG_VENDOR_SPECIFIC_IE, create_dissector_handle(ieee80211_tag_vendor_specific_ie, -1));
+ /* This Cisco proprietary IE seems to mimic 221 */
+ dissector_add_uint("wlan.tag.number", TAG_CISCO_VENDOR_SPECIFIC, create_dissector_handle(ieee80211_tag_vendor_specific_ie, -1));
+ /* This Symbol proprietary IE seems to mimic 221 */
+ dissector_add_uint("wlan.tag.number", TAG_SYMBOL_PROPRIETARY, create_dissector_handle(ieee80211_tag_vendor_specific_ie, -1));
+ dissector_add_uint("wlan.tag.number", TAG_MOBILITY_DOMAIN, create_dissector_handle(dissect_mobility_domain, -1));
+ dissector_add_uint("wlan.tag.number", TAG_FAST_BSS_TRANSITION, create_dissector_handle(dissect_fast_bss_transition, -1));
+ dissector_add_uint("wlan.tag.number", TAG_MMIE, create_dissector_handle(dissect_mmie, -1));
+ dissector_add_uint("wlan.tag.number", TAG_SSID_LIST, create_dissector_handle(dissect_ssid_list, -1));
+ dissector_add_uint("wlan.tag.number", TAG_TIME_ZONE, create_dissector_handle(dissect_time_zone, -1));
+ dissector_add_uint("wlan.tag.number", TAG_TIMEOUT_INTERVAL, create_dissector_handle(dissect_timeout_interval, -1));
+ dissector_add_uint("wlan.tag.number", TAG_RIC_DATA, create_dissector_handle(dissect_ric_data, -1));
+ dissector_add_uint("wlan.tag.number", TAG_LINK_IDENTIFIER, create_dissector_handle(dissect_link_identifier, -1));
+ dissector_add_uint("wlan.tag.number", TAG_WAKEUP_SCHEDULE, create_dissector_handle(dissect_wakeup_schedule, -1));
+ dissector_add_uint("wlan.tag.number", TAG_CHANNEL_SWITCH_TIMING, create_dissector_handle(dissect_channel_switch_timing, -1));
+ dissector_add_uint("wlan.tag.number", TAG_PTI_CONTROL, create_dissector_handle(dissect_pti_control, -1));
+ dissector_add_uint("wlan.tag.number", TAG_PU_BUFFER_STATUS, create_dissector_handle(dissect_pu_buffer_status, -1));
+ dissector_add_uint("wlan.tag.number", TAG_HT_CAPABILITY, create_dissector_handle(dissect_ht_capability_ie, -1));
+ dissector_add_uint("wlan.tag.number", TAG_HT_INFO, create_dissector_handle(dissect_ht_info_ie_1_1, -1));
+ dissector_add_uint("wlan.tag.number", TAG_SECONDARY_CHANNEL_OFFSET, create_dissector_handle(dissect_secondary_channel_offset_ie, -1));
+ dissector_add_uint("wlan.tag.number", TAG_BSS_AVG_ACCESS_DELAY, create_dissector_handle(dissect_bss_avg_access_delay_ie, -1));
+ dissector_add_uint("wlan.tag.number", TAG_ANTENNA, create_dissector_handle(dissect_antenna_ie, -1));
+ dissector_add_uint("wlan.tag.number", TAG_RSNI, create_dissector_handle(dissect_rsni_ie, -1));
+ dissector_add_uint("wlan.tag.number", TAG_BSS_AVB_ADM_CAPACITY, create_dissector_handle(dissect_bss_available_admission_capacity_ie, -1));
+ dissector_add_uint("wlan.tag.number", TAG_IE_68_CONFLICT, create_dissector_handle(ieee80211_tag_ie_68_conflict, -1));
+ dissector_add_uint("wlan.tag.number", TAG_BSS_MAX_IDLE_PERIOD, create_dissector_handle(dissect_bss_max_idle_period, -1));
+ dissector_add_uint("wlan.tag.number", TAG_TFS_REQUEST, create_dissector_handle(dissect_tfs_request, -1));
+ dissector_add_uint("wlan.tag.number", TAG_TFS_RESPONSE, create_dissector_handle(dissect_tfs_response, -1));
+ dissector_add_uint("wlan.tag.number", TAG_WNM_SLEEP_MODE, create_dissector_handle(dissect_wnm_sleep_mode, -1));
+ dissector_add_uint("wlan.tag.number", TAG_TIME_ADV, create_dissector_handle(dissect_time_adv, -1));
+ dissector_add_uint("wlan.tag.number", TAG_RM_ENABLED_CAPABILITY, create_dissector_handle(dissect_rm_enabled_capabilities_ie, -1));
+ dissector_add_uint("wlan.tag.number", TAG_20_40_BSS_CO_EX, create_dissector_handle(dissect_20_40_bss_coexistence, -1));
+ dissector_add_uint("wlan.tag.number", TAG_OVERLAP_BSS_SCAN_PAR, create_dissector_handle(dissect_overlap_bss_scan_par, -1));
+ dissector_add_uint("wlan.tag.number", TAG_RIC_DESCRIPTOR, create_dissector_handle(dissect_ric_descriptor, -1));
+ dissector_add_uint("wlan.tag.number", TAG_MESH_PEERING_MGMT, create_dissector_handle(ieee80211_tag_mesh_peering_mgmt, -1));
+ dissector_add_uint("wlan.tag.number", TAG_MESH_CONFIGURATION, create_dissector_handle(ieee80211_tag_mesh_configuration, -1));
+ dissector_add_uint("wlan.tag.number", TAG_MESH_ID, create_dissector_handle(ieee80211_tag_mesh_id, -1));
+ dissector_add_uint("wlan.tag.number", TAG_MESH_PREQ, create_dissector_handle(ieee80211_tag_mesh_preq, -1));
+ dissector_add_uint("wlan.tag.number", TAG_MESH_PREP, create_dissector_handle(ieee80211_tag_mesh_prep, -1));
+ dissector_add_uint("wlan.tag.number", TAG_MESH_PERR, create_dissector_handle(ieee80211_tag_mesh_perr, -1));
+ dissector_add_uint("wlan.tag.number", TAG_RANN, create_dissector_handle(ieee80211_tag_rann, -1));
+ dissector_add_uint("wlan.tag.number", TAG_MESH_CHANNEL_SWITCH, create_dissector_handle(ieee80211_tag_mesh_channel_switch, -1));
+ dissector_add_uint("wlan.tag.number", TAG_INTERWORKING, create_dissector_handle(dissect_interworking, -1));
+ dissector_add_uint("wlan.tag.number", TAG_ADVERTISEMENT_PROTOCOL, create_dissector_handle(dissect_advertisement_protocol, -1));
+ dissector_add_uint("wlan.tag.number", TAG_QOS_MAP_SET, create_dissector_handle(dissect_qos_map_set, -1));
+ dissector_add_uint("wlan.tag.number", TAG_ROAMING_CONSORTIUM, create_dissector_handle(dissect_roaming_consortium, -1));
+ dissector_add_uint("wlan.tag.number", TAG_AP_CHANNEL_REPORT, create_dissector_handle(dissect_ap_channel_report, -1));
+ dissector_add_uint("wlan.tag.number", TAG_NEIGHBOR_REPORT, create_dissector_handle(dissect_neighbor_report, -1));
+ dissector_add_uint("wlan.tag.number", TAG_EXTENDED_CHANNEL_SWITCH_ANNOUNCEMENT, create_dissector_handle(ieee80211_tag_channel_switch_announcement, -1));
+ dissector_add_uint("wlan.tag.number", TAG_SUPPORTED_OPERATING_CLASSES, create_dissector_handle(ieee80211_tag_supported_operating_classes, -1));
+ dissector_add_uint("wlan.tag.number", TAG_RELAY_CAPABILITIES, create_dissector_handle(add_tag_relay_capabilities, -1));
+ dissector_add_uint("wlan.tag.number", TAG_DMG_BSS_PARAMETER_CHANGE, create_dissector_handle(ieee80211_tag_bss_parameter_change, -1));
+ dissector_add_uint("wlan.tag.number", TAG_DMG_CAPABILITIES, create_dissector_handle(ieee80211_tag_dmg_capabilities, -1));
+ dissector_add_uint("wlan.tag.number", TAG_DMG_OPERATION, create_dissector_handle(ieee80211_tag_dmg_operation, -1));
+ dissector_add_uint("wlan.tag.number", TAG_ANTENNA_SECTOR_ID, create_dissector_handle(ieee80211_tag_antenna_section_id, -1));
+ dissector_add_uint("wlan.tag.number", TAG_EXTENDED_SCHEDULE, create_dissector_handle(ieee80211_tag_extended_schedule, -1));
+ dissector_add_uint("wlan.tag.number", TAG_STA_AVAILABILITY, create_dissector_handle(ieee80211_tag_sta_availability, -1));
+ dissector_add_uint("wlan.tag.number", TAG_NEXT_DMG_ATI, create_dissector_handle(ieee80211_tag_next_dmg_ati, -1));
+ dissector_add_uint("wlan.tag.number", TAG_NEXTPCP_LIST, create_dissector_handle(ieee80211_tag_nextpcp_list, -1));
+ dissector_add_uint("wlan.tag.number", TAG_PCP_HANDOVER, create_dissector_handle(ieee80211_tag_pcp_handover, -1));
+ dissector_add_uint("wlan.tag.number", TAG_BEAMLINK_MAINTENANCE, create_dissector_handle(ieee80211_tag_beamlink_maintenance, -1));
+ dissector_add_uint("wlan.tag.number", TAG_QUIET_PERIOD_RES, create_dissector_handle(ieee80211_tag_quiet_period_res, -1));
+ dissector_add_uint("wlan.tag.number", TAG_RELAY_TRANSFER_PARAM, create_dissector_handle(ieee80211_tag_relay_transfer_param, -1));
+ dissector_add_uint("wlan.tag.number", TAG_DMG_BEAM_REFINEMENT, create_dissector_handle(ieee80211_tag_dmg_beam_refinement, -1));
+ dissector_add_uint("wlan.tag.number", TAG_WAKEUP_SCHEDULE_AD, create_dissector_handle(ieee80211_tag_wakeup_schedule_ad, -1));
+ dissector_add_uint("wlan.tag.number", TAG_DMG_TSPEC, create_dissector_handle(ieee80211_tag_dmg_tspec, -1));
+ dissector_add_uint("wlan.tag.number", TAG_CHANNEL_MEASURMENT_FB, create_dissector_handle(ieee80211_tag_channel_measurement_fb, -1));
+ dissector_add_uint("wlan.tag.number", TAG_AWAKE_WINDOW, create_dissector_handle(ieee80211_tag_awake_window, -1));
+ dissector_add_uint("wlan.tag.number", TAG_ADDBA_EXT, create_dissector_handle(ieee80211_tag_addba_ext, -1));
+ dissector_add_uint("wlan.tag.number", TAG_MULTI_BAND, create_dissector_handle(ieee80211_tag_multi_band, -1));
+ dissector_add_uint("wlan.tag.number", TAG_DMG_LINK_MARGIN, create_dissector_handle(ieee80211_tag_dmg_link_margin, -1));
+ dissector_add_uint("wlan.tag.number", TAG_DMG_LINK_ADAPTION_ACK, create_dissector_handle(ieee80211_tag_dmg_link_adaption_ack, -1));
+ dissector_add_uint("wlan.tag.number", TAG_SWITCHING_STREAM, create_dissector_handle(ieee80211_tag_switching_stream, -1));
}
/*
diff --git a/epan/dissectors/packet-ieee80211.h b/epan/dissectors/packet-ieee80211.h
index 54eb5b4ff2..3ad2c7e19a 100644
--- a/epan/dissectors/packet-ieee80211.h
+++ b/epan/dissectors/packet-ieee80211.h
@@ -39,6 +39,15 @@ typedef struct {
proto_node *rsn_first_non_ft_akm_suite;
} association_sanity_check_t;
+typedef struct ieee80211_tagged_field_data
+{
+ int ftype;
+ association_sanity_check_t* sanity_check;
+ gboolean isDMG;
+ proto_item* item_tag;
+ proto_item* item_tag_length;
+} ieee80211_tagged_field_data_t;
+
void dissect_wifi_p2p_ie(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb,
int offset, gint size);
int dissect_wifi_p2p_public_action(packet_info *pinfo, proto_tree *tree,