diff options
author | etxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7> | 2011-09-15 06:53:42 +0000 |
---|---|---|
committer | etxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7> | 2011-09-15 06:53:42 +0000 |
commit | dad0fe61b78d49157774ed86af194e1d1e219b0c (patch) | |
tree | 7780a17c4ae76cfb50fb77d0e5fe448f9040c18f | |
parent | 011f37806ca34fc6586f25d4339a9ea8d84e8a25 (diff) |
From Jouni Malinen:
ieee80211: Support multiple ANQP info elements in response
ANQP Query Response may include multiple ANQP info elements. Parse each
one of these separately. In addition, clean up three ANQP subtrees to
avoid the unnecessary subtree at higher layer and instead, use a
separate subtree for each ANQP info elements.
https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=6339
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@39008 f5534014-38df-0310-8fa8-9805f1628bb7
-rw-r--r-- | epan/dissectors/packet-ieee80211.c | 89 |
1 files changed, 55 insertions, 34 deletions
diff --git a/epan/dissectors/packet-ieee80211.c b/epan/dissectors/packet-ieee80211.c index 479dd0b932..53b01b611f 100644 --- a/epan/dissectors/packet-ieee80211.c +++ b/epan/dissectors/packet-ieee80211.c @@ -3479,24 +3479,28 @@ dissect_advertisement_protocol(packet_info *pinfo, proto_tree *tree, return 2 + tag_len; } -static void -dissect_anqp(proto_tree *tree, tvbuff_t *tvb, int offset, gboolean request) +static int +dissect_anqp_info(proto_tree *tree, tvbuff_t *tvb, int offset, + gboolean request, int idx) { guint16 id, len; guint32 oui; guint8 subtype; + proto_item *item; - proto_tree_add_text(tree, tvb, offset, 4, - request ? "Access Network Query Protocol Request" : - "Access Network Query Protocol Response"); - if (tvb_reported_length_remaining(tvb, offset) < 4) { - expert_add_info_format(g_pinfo, tree, PI_MALFORMED, PI_ERROR, - "Not enough room for ANQP header"); - return; - } - proto_tree_add_item(tree, hf_ieee80211_ff_anqp_info_id, - tvb, offset, 2, TRUE); + item = proto_tree_add_item(tree, hf_ieee80211_ff_anqp_info_id, + tvb, offset, 2, TRUE); id = tvb_get_letohs(tvb, offset); + if (id != ANQP_INFO_ANQP_VENDOR_SPECIFIC_LIST) { + if (idx == 0) { + proto_item_append_text(tree, " - %s", + val_to_str(id, anqp_info_id_vals, + "Unknown (%u)")); + } else if (idx == 1) { + proto_item_append_text(tree, ", .."); + } + } + tree = proto_item_add_subtree(item, ett_gas_anqp); offset += 2; proto_tree_add_item(tree, hf_ieee80211_ff_anqp_info_length, tvb, offset, 2, TRUE); @@ -3505,7 +3509,7 @@ dissect_anqp(proto_tree *tree, tvbuff_t *tvb, int offset, gboolean request) if (tvb_reported_length_remaining(tvb, offset) < len) { expert_add_info_format(g_pinfo, tree, PI_MALFORMED, PI_ERROR, "Invalid ANQP Info length"); - return; + return 4 + len; } switch (id) { @@ -3536,6 +3540,26 @@ dissect_anqp(proto_tree *tree, tvbuff_t *tvb, int offset, gboolean request) tvb, offset, len, ENC_BIG_ENDIAN); break; } + + return 4 + len; +} + +static void +dissect_anqp(proto_tree *tree, tvbuff_t *tvb, int offset, gboolean request) +{ + int idx = 0; + + proto_item_append_text(tree, ": ANQP "); + proto_item_append_text(tree, request ? "Request" : "Response"); + if (tvb_reported_length_remaining(tvb, offset) < 4) { + expert_add_info_format(g_pinfo, tree, PI_MALFORMED, PI_ERROR, + "Not enough room for ANQP header"); + return; + } + while (tvb_reported_length_remaining(tvb, offset) > 0) { + offset += dissect_anqp_info(tree, tvb, offset, request, idx); + idx++; + } } static guint @@ -3545,7 +3569,7 @@ dissect_gas_initial_request(proto_tree *tree, tvbuff_t *tvb, int offset, guint16 req_len; int start = offset; proto_item *item; - proto_tree *query, *anqp_tree; + proto_tree *query; /* Query Request Length (2 octets) */ req_len = tvb_get_letohs(tvb, offset); @@ -3560,12 +3584,11 @@ dissect_gas_initial_request(proto_tree *tree, tvbuff_t *tvb, int offset, * Query Request (GAS query; formatted per protocol specified in the * Advertisement Protocol IE) */ - item = proto_tree_add_item(query, hf_ieee80211_ff_query_request, - tvb, offset, req_len, FALSE); - if (anqp) { - anqp_tree = proto_item_add_subtree(item, ett_gas_anqp); - dissect_anqp(anqp_tree, tvb, offset, TRUE); - } + if (anqp) + dissect_anqp(query, tvb, offset, TRUE); + else + proto_tree_add_item(query, hf_ieee80211_ff_query_request, + tvb, offset, req_len, FALSE); offset += req_len; return offset - start; @@ -3578,7 +3601,7 @@ dissect_gas_initial_response(proto_tree *tree, tvbuff_t *tvb, int offset, guint16 resp_len; int start = offset; proto_item *item; - proto_tree *query, *anqp_tree; + proto_tree *query; /* Query Response Length (2 octets) */ resp_len = tvb_get_letohs(tvb, offset); @@ -3592,12 +3615,11 @@ dissect_gas_initial_response(proto_tree *tree, tvbuff_t *tvb, int offset, offset += 2; /* Query Response (optional) */ if (resp_len) { - item = proto_tree_add_item(query, hf_ieee80211_ff_query_response, - tvb, offset, resp_len, FALSE); - if (anqp) { - anqp_tree = proto_item_add_subtree(item, ett_gas_anqp); - dissect_anqp(anqp_tree, tvb, offset, FALSE); - } + if (anqp) + dissect_anqp(query, tvb, offset, FALSE); + else + proto_tree_add_item(query, hf_ieee80211_ff_query_response, + tvb, offset, resp_len, FALSE); offset += resp_len; } @@ -3611,7 +3633,7 @@ dissect_gas_comeback_response(proto_tree *tree, tvbuff_t *tvb, int offset, guint16 resp_len; int start = offset; proto_item *item; - proto_tree *query, *anqp_tree; + proto_tree *query; /* Query Response Length (2 octets) */ resp_len = tvb_get_letohs(tvb, offset); @@ -3625,12 +3647,11 @@ dissect_gas_comeback_response(proto_tree *tree, tvbuff_t *tvb, int offset, offset += 2; /* Query Response (optional) */ if (resp_len) { - item = proto_tree_add_item(query, hf_ieee80211_ff_query_response, - tvb, offset, resp_len, FALSE); - if (anqp && frag == 0) { - anqp_tree = proto_item_add_subtree(item, ett_gas_anqp); - dissect_anqp(anqp_tree, tvb, offset, FALSE); - } + if (anqp && frag == 0) + dissect_anqp(query, tvb, offset, FALSE); + else + proto_tree_add_item(query, hf_ieee80211_ff_query_response, + tvb, offset, resp_len, FALSE); offset += resp_len; } |