aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-ieee80211-radiotap-iter.c
diff options
context:
space:
mode:
authorRichard Sharpe <realrichardsharpe@gmail.com>2020-02-08 13:55:52 -0500
committerAlexis La Goutte <alexis.lagoutte@gmail.com>2020-02-08 19:41:47 +0000
commit38d54660f20d53985ac3e837ce6ed3fc35839ab4 (patch)
tree8710f70027d783b87225dfa990fc0c3687a6ff12 /epan/dissectors/packet-ieee80211-radiotap-iter.c
parent0d68a088fa9c75d62ff96286b7128d553a82f8a1 (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.c55
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;
}
/*