diff options
author | Richard Sharpe <realrichardsharpe@gmail.com> | 2020-02-08 13:55:52 -0500 |
---|---|---|
committer | Alexis La Goutte <alexis.lagoutte@gmail.com> | 2020-02-08 19:41:47 +0000 |
commit | 38d54660f20d53985ac3e837ce6ed3fc35839ab4 (patch) | |
tree | 8710f70027d783b87225dfa990fc0c3687a6ff12 /epan/dissectors/packet-ieee80211-radiotap-iter.c | |
parent | 0d68a088fa9c75d62ff96286b7128d553a82f8a1 (diff) |
ieee80211-radiotap: Add support for radiotap TLVs.
From Johannes Berg with changes by Richard Sharpe to make it easier for
people to add support for RADIOTAP Header TLVs in the future.
Change-Id: I66d69cbe16740abce1e75ca1e789a2034283306b
Reviewed-on: https://code.wireshark.org/review/36057
Reviewed-by: Richard Sharpe <realrichardsharpe@gmail.com>
Petri-Dish: Richard Sharpe <realrichardsharpe@gmail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-ieee80211-radiotap-iter.c')
-rw-r--r-- | epan/dissectors/packet-ieee80211-radiotap-iter.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/epan/dissectors/packet-ieee80211-radiotap-iter.c b/epan/dissectors/packet-ieee80211-radiotap-iter.c index 94900f4337..202577873d 100644 --- a/epan/dissectors/packet-ieee80211-radiotap-iter.c +++ b/epan/dissectors/packet-ieee80211-radiotap-iter.c @@ -142,6 +142,7 @@ int ieee80211_radiotap_iterator_init( iterator->_vns = vns; iterator->current_namespace = &radiotap_ns; iterator->is_radiotap_ns = 1; + iterator->tlv_mode = 0; #ifdef RADIOTAP_SUPPORT_OVERRIDES iterator->n_overrides = 0; iterator->overrides = NULL; @@ -164,6 +165,13 @@ int ieee80211_radiotap_iterator_init( /* XXX - we should report an expert info here */ if (!ITERATOR_VALID(iterator, sizeof(guint32))) return -EINVAL; + + /* XXX - we should report an expert info here */ + if ((get_unaligned_le32(iterator->_arg) & + (1U << IEEE80211_RADIOTAP_TLVS)) && + (get_unaligned_le32(iterator->_arg) & + (1U << IEEE80211_RADIOTAP_EXT))) + return -EINVAL; } iterator->_arg += sizeof(guint32); @@ -253,6 +261,46 @@ static int find_override(struct ieee80211_radiotap_iterator *iterator, int ieee80211_radiotap_iterator_next( struct ieee80211_radiotap_iterator *iterator) { + if (iterator->tlv_mode) { + struct ieee80211_radiotap_tlv *tlv; + guint32 size; + +#define TLV_LEN_ALIGN(x) ((x + 3) & ~3) + size = sizeof(*tlv) + TLV_LEN_ALIGN(iterator->this_arg_size); + + /* + * We know that without the alignment padding it was valid, so + * ignore arbitrary padding and return that we finished if no + * further TLV could fit. + */ + if (!ITERATOR_VALID(iterator, size)) + return -ENOENT; + + /* move to next entry */ + iterator->_arg += sizeof(*tlv) + TLV_LEN_ALIGN(iterator->this_arg_size); + +return_tlv: + /* and check again if we reached the end */ + if (!ITERATOR_VALID(iterator, 1)) + return -ENOENT; + + /* if it's not the end but a new TLV won't fit - error out */ + if (!ITERATOR_VALID(iterator, sizeof(*tlv))) + return -EINVAL; + + tlv = (struct ieee80211_radiotap_tlv *)iterator->_arg; + + iterator->this_arg_index = get_unaligned_le16(&tlv->type); + iterator->this_arg_size = get_unaligned_le16(&tlv->datalen); + iterator->this_arg = tlv->data; + iterator->is_radiotap_ns = + iterator->this_arg_index != IEEE80211_RADIOTAP_VENDOR_NAMESPACE; + + if (!ITERATOR_VALID(iterator, sizeof(*tlv) + iterator->this_arg_size)) + return -EINVAL; + return 0; + } + while (1) { int hit = 0; int pad, align, size, subns; @@ -268,6 +316,10 @@ int ieee80211_radiotap_iterator_next( /* get alignment/size of data */ switch (iterator->_arg_index % 32) { + case IEEE80211_RADIOTAP_TLVS: + align = 4; + size = 0; + break; case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE: case IEEE80211_RADIOTAP_EXT: align = 1; @@ -344,6 +396,9 @@ int ieee80211_radiotap_iterator_next( iterator->_next_ns_data = iterator->_arg + size + vnslen; if (!iterator->current_namespace) size += vnslen; + } else if (iterator->_arg_index % 32 == IEEE80211_RADIOTAP_TLVS) { + iterator->tlv_mode = 1; + goto return_tlv; } /* |