radiotap.netbsd.org archive mirror
 help / color / mirror / Atom feed
* [RFA] namespaces and vendor extensions
@ 2009-11-26 17:55 Johannes Berg
       [not found] ` <1259258152.32372.90.camel-YfaajirXv2244ywRPIzf9A@public.gmane.org>
  0 siblings, 1 reply; 14+ messages in thread
From: Johannes Berg @ 2009-11-26 17:55 UTC (permalink / raw)
  To: Radiotap; +Cc: Gerald Combs


[-- Attachment #1.1: Type: text/plain, Size: 5826 bytes --]

[Gerald: I'm copying you directly because I have a question about this
patch, please see at the end of the email]

This is a request for adoption of the previously discussed namespace
proposal from David.

Namespaces in radiotap serve two different use cases:
 1) vendor extensions and
 2) multiple uses of a single radiotap field.

Vendor extensions allows data from any number of different vendors to be
present in a single radiotap header. Each vendor namespace contains
present bits just like regular radiotap, but these bits are under the
control of the vendor. To allow compliant parsers to read past vendor
extensions, they also contain the data length.

Resetting the radiotap namespace when extending the present bitmap
serves to allow a radiotap field be specified multiple times. An example
for that would be specifying multi-rate retries during injection or for
TX status.

In the current radiotap header, the IEEE80211_RADIOTAP_EXT bit (bit 31)
is reserved in any it_present bitmap and indicates that the bitmap
continues. This shall be true for bit 29 (reset radiotap namespace) and
bit 30 (vendor namespace) as well.

This proposal differs from David's original one by using different
alignment and size for the vendor data specification, I have opted to
use 16 bits for the vendor data length since some people want to put a
lot of data like raw TX/RX hardware descriptors into vendor fields. I
have also clarified the data length variable to specify the fact that
when switching away from a vendor namespace to another vendor namespace,
the vendor namespace data is not part of the vendor namespace data
length ("If a radiotap header changes from a vendor namespace to another
vendor namespace, the 6-byte data describing the new vendor namespace
shall not be accounted for in skip_length.") The text describing that
the two fields are mutually exclusive is also new.

Correct, existing radiotap implementations are compatible with this
proposal because they will stop parsing the radiotap header at bit 29/30
since even though they do not know that these bits are reserved in all
namespaces and it_present words they do know that they cannot understand
these bits, regardless of which it_present they encounter them in,
because they were not previously defined. [It seems to me that the
existing wireshark implementation is not correct -- it doesn't properly
skip over extended present bitmap words.]

Note that before this proposal the bits 63, 95, (31+n*32) were reserved
due to overlaying the extension bit, this proposal also reserves the
bits 29+n*32 and 30+n*32 in all namespaces due to overlapping with the
namespace changes bits.

The normative text of this proposal follows (minus formatting):

--- begin normative text ---
Vendor Namespace
Bit Number
        not applicable, bit 30 in every it_present word 
Structure
        u8 OUI[3], u8 sub_namespace, __le16 skip_length 
Required Alignment
        2 

This field is reserved in all namespaces and every it_present word, the
standard radiotap namespace as well as all vendor namespaces. It is
mutually exclusive with the "Reset to Radiotap Namespace" field, setting
both is undefined.

The Vendor Namespace Field contains three sub-fields. The first
sub-field is 3 bytes long. It contains the vendor's IEEE 802
Organizationally Unique Identifier (OUI). The fourth byte is a
vendor-specific "namespace selector." 

Before it resumes interpretation of presence bits in the following
32-bit presence words, if any, the interpreter shall reset its
presence-bitmap index to 0, and change to the vendor namespace specified
by the OUI and selector. 

The fifth and sixth bytes, skip_length, comprise a 16 bit little-endian
value that tells the interpreter how many bytes of data after the end of
the Vendor Namespace Field can only be interpreted according to the
vendor namespace. If a radiotap header changes to a namespace that the
interpreter does not understand, and back, the interpreter may resume
interpretation in the new namespace by skipping skip_length data bytes
after the end of the Vendor Namespace Field. If a radiotap header
changes from a vendor namespace to another vendor namespace, the 6-byte
data describing the new vendor namespace shall not be accounted for in
skip_length.

Reset to Radiotap Namespace
Bit Number
        not applicable, bit 29 in every it_present word 
Structure
        no contents 
Required Alignment
        N/A

This field is reserved in all namespaces and every it_present word, the
standard radiotap namespace as well as all vendor namespaces. It is
mutually exclusive with the "Vendor Namespace" field, setting both is
undefined.

Upon interpreting this field, the interpreter shall reset its
presence-bitmap index to 0 and its namespace to the default radiotap
namespace, and change to the default radiotap namespace, before it
interprets subsequent presence-bitmap words. 


--- end normative text ---

I have implemented this proposal in Andy Green's and my stand-alone
radiotap parser library available on
http://git.sipsolutions.net/radiotap.git/
(git clone http://git.sipsolutions.net/radiotap.git/ to get it, the web
interface can also generate tarballs).

I have additionally implemented this proposal in wireshark, without any
vendor extension parsing, by making wireshark use a copy of the above
library.

Gerald: Here's where I have a question -- is that acceptable to you? The
files are licensed properly, but it does require pulling the entire
radiotap header into memory with ep_tvb_memdup(). Are you ok with that?
Everything else would be rather complicated, requiring a complete
re-implementation of the parser which doesn't seem all that helpful.

johannes


[-- Attachment #1.2: radiotap-lib.patch --]
[-- Type: text/x-patch, Size: 82217 bytes --]

---
 epan/dissectors/Makefile.am                |    2 
 epan/dissectors/Makefile.common            |    3 
 epan/dissectors/Makefile.nmake             |    2 
 epan/dissectors/packet-radiotap-defs.h     |  245 ++++++
 epan/dissectors/packet-radiotap-iter.c     |  378 ++++++++++
 epan/dissectors/packet-radiotap-iter.h     |   96 ++
 epan/dissectors/packet-radiotap-platform.h |    9 
 epan/dissectors/packet-radiotap.c          | 1069 +++++++++++++----------------
 8 files changed, 1224 insertions(+), 580 deletions(-)

--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ trunk/epan/dissectors/packet-radiotap-defs.h	2009-11-26 18:53:53.000000000 +0100
@@ -0,0 +1,245 @@
+/*-
+ * Copyright (c) 2003, 2004 David Young.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of David Young may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DAVID
+ * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ */
+
+/*
+ * Modifications to fit into the linux IEEE 802.11 stack,
+ * Mike Kershaw (dragorn@kismetwireless.net)
+ */
+
+#ifndef IEEE80211RADIOTAP_H
+#define IEEE80211RADIOTAP_H
+
+#include <stdint.h>
+
+/* Base version of the radiotap packet header data */
+#define PKTHDR_RADIOTAP_VERSION		0
+
+/* A generic radio capture format is desirable. There is one for
+ * Linux, but it is neither rigidly defined (there were not even
+ * units given for some fields) nor easily extensible.
+ *
+ * I suggest the following extensible radio capture format. It is
+ * based on a bitmap indicating which fields are present.
+ *
+ * I am trying to describe precisely what the application programmer
+ * should expect in the following, and for that reason I tell the
+ * units and origin of each measurement (where it applies), or else I
+ * use sufficiently weaselly language ("is a monotonically nondecreasing
+ * function of...") that I cannot set false expectations for lawyerly
+ * readers.
+ */
+
+/* The radio capture header precedes the 802.11 header.
+ * All data in the header is little endian on all platforms.
+ */
+struct ieee80211_radiotap_header {
+	uint8_t it_version;	/* Version 0. Only increases
+				 * for drastic changes,
+				 * introduction of compatible
+				 * new fields does not count.
+				 */
+	uint8_t it_pad;
+	uint16_t it_len;	/* length of the whole
+				 * header in bytes, including
+				 * it_version, it_pad,
+				 * it_len, and data fields.
+				 */
+	uint32_t it_present;	/* A bitmap telling which
+				 * fields are present. Set bit 31
+				 * (0x80000000) to extend the
+				 * bitmap by another 32 bits.
+				 * Additional extensions are made
+				 * by setting bit 31.
+				 */
+};
+
+/* Name                                 Data type    Units
+ * ----                                 ---------    -----
+ *
+ * IEEE80211_RADIOTAP_TSFT              __le64       microseconds
+ *
+ *      Value in microseconds of the MAC's 64-bit 802.11 Time
+ *      Synchronization Function timer when the first bit of the
+ *      MPDU arrived at the MAC. For received frames, only.
+ *
+ * IEEE80211_RADIOTAP_CHANNEL           2 x uint16_t   MHz, bitmap
+ *
+ *      Tx/Rx frequency in MHz, followed by flags (see below).
+ *
+ * IEEE80211_RADIOTAP_FHSS              uint16_t       see below
+ *
+ *      For frequency-hopping radios, the hop set (first byte)
+ *      and pattern (second byte).
+ *
+ * IEEE80211_RADIOTAP_RATE              u8           500kb/s
+ *
+ *      Tx/Rx data rate
+ *
+ * IEEE80211_RADIOTAP_DBM_ANTSIGNAL     s8           decibels from
+ *                                                   one milliwatt (dBm)
+ *
+ *      RF signal power at the antenna, decibel difference from
+ *      one milliwatt.
+ *
+ * IEEE80211_RADIOTAP_DBM_ANTNOISE      s8           decibels from
+ *                                                   one milliwatt (dBm)
+ *
+ *      RF noise power at the antenna, decibel difference from one
+ *      milliwatt.
+ *
+ * IEEE80211_RADIOTAP_DB_ANTSIGNAL      u8           decibel (dB)
+ *
+ *      RF signal power at the antenna, decibel difference from an
+ *      arbitrary, fixed reference.
+ *
+ * IEEE80211_RADIOTAP_DB_ANTNOISE       u8           decibel (dB)
+ *
+ *      RF noise power at the antenna, decibel difference from an
+ *      arbitrary, fixed reference point.
+ *
+ * IEEE80211_RADIOTAP_LOCK_QUALITY      uint16_t       unitless
+ *
+ *      Quality of Barker code lock. Unitless. Monotonically
+ *      nondecreasing with "better" lock strength. Called "Signal
+ *      Quality" in datasheets.  (Is there a standard way to measure
+ *      this?)
+ *
+ * IEEE80211_RADIOTAP_TX_ATTENUATION    uint16_t       unitless
+ *
+ *      Transmit power expressed as unitless distance from max
+ *      power set at factory calibration.  0 is max power.
+ *      Monotonically nondecreasing with lower power levels.
+ *
+ * IEEE80211_RADIOTAP_DB_TX_ATTENUATION uint16_t       decibels (dB)
+ *
+ *      Transmit power expressed as decibel distance from max power
+ *      set at factory calibration.  0 is max power.  Monotonically
+ *      nondecreasing with lower power levels.
+ *
+ * IEEE80211_RADIOTAP_DBM_TX_POWER      s8           decibels from
+ *                                                   one milliwatt (dBm)
+ *
+ *      Transmit power expressed as dBm (decibels from a 1 milliwatt
+ *      reference). This is the absolute power level measured at
+ *      the antenna port.
+ *
+ * IEEE80211_RADIOTAP_FLAGS             u8           bitmap
+ *
+ *      Properties of transmitted and received frames. See flags
+ *      defined below.
+ *
+ * IEEE80211_RADIOTAP_ANTENNA           u8           antenna index
+ *
+ *      Unitless indication of the Rx/Tx antenna for this packet.
+ *      The first antenna is antenna 0.
+ *
+ * IEEE80211_RADIOTAP_RX_FLAGS          uint16_t       bitmap
+ *
+ *     Properties of received frames. See flags defined below.
+ *
+ * IEEE80211_RADIOTAP_TX_FLAGS          uint16_t       bitmap
+ *
+ *     Properties of transmitted frames. See flags defined below.
+ *
+ * IEEE80211_RADIOTAP_RTS_RETRIES       u8           data
+ *
+ *     Number of rts retries a transmitted frame used.
+ *
+ * IEEE80211_RADIOTAP_DATA_RETRIES      u8           data
+ *
+ *     Number of unicast retries a transmitted frame used.
+ *
+ */
+enum ieee80211_radiotap_type {
+	IEEE80211_RADIOTAP_TSFT = 0,
+	IEEE80211_RADIOTAP_FLAGS = 1,
+	IEEE80211_RADIOTAP_RATE = 2,
+	IEEE80211_RADIOTAP_CHANNEL = 3,
+	IEEE80211_RADIOTAP_FHSS = 4,
+	IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
+	IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
+	IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
+	IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
+	IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
+	IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
+	IEEE80211_RADIOTAP_ANTENNA = 11,
+	IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
+	IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
+	IEEE80211_RADIOTAP_RX_FLAGS = 14,
+	IEEE80211_RADIOTAP_TX_FLAGS = 15,
+	IEEE80211_RADIOTAP_RTS_RETRIES = 16,
+	IEEE80211_RADIOTAP_DATA_RETRIES = 17,
+
+	/* valid in every it_present bitmap, even vendor namespaces */
+	IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29,
+	IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30,
+	IEEE80211_RADIOTAP_EXT = 31
+};
+
+/* Channel flags. */
+#define	IEEE80211_CHAN_TURBO	0x0010	/* Turbo channel */
+#define	IEEE80211_CHAN_CCK	0x0020	/* CCK channel */
+#define	IEEE80211_CHAN_OFDM	0x0040	/* OFDM channel */
+#define	IEEE80211_CHAN_2GHZ	0x0080	/* 2 GHz spectrum channel. */
+#define	IEEE80211_CHAN_5GHZ	0x0100	/* 5 GHz spectrum channel */
+#define	IEEE80211_CHAN_PASSIVE	0x0200	/* Only passive scan allowed */
+#define	IEEE80211_CHAN_DYN	0x0400	/* Dynamic CCK-OFDM channel */
+#define	IEEE80211_CHAN_GFSK	0x0800	/* GFSK channel (FHSS PHY) */
+
+/* For IEEE80211_RADIOTAP_FLAGS */
+#define	IEEE80211_RADIOTAP_F_CFP	0x01	/* sent/received
+						 * during CFP
+						 */
+#define	IEEE80211_RADIOTAP_F_SHORTPRE	0x02	/* sent/received
+						 * with short
+						 * preamble
+						 */
+#define	IEEE80211_RADIOTAP_F_WEP	0x04	/* sent/received
+						 * with WEP encryption
+						 */
+#define	IEEE80211_RADIOTAP_F_FRAG	0x08	/* sent/received
+						 * with fragmentation
+						 */
+#define	IEEE80211_RADIOTAP_F_FCS	0x10	/* frame includes FCS */
+#define	IEEE80211_RADIOTAP_F_DATAPAD	0x20	/* frame has padding between
+						 * 802.11 header and payload
+						 * (to 32-bit boundary)
+						 */
+#define IEEE80211_RADIOTAP_F_BADFCS	0x40	/* frame failed FCS check */
+
+/* For IEEE80211_RADIOTAP_RX_FLAGS */
+#define IEEE80211_RADIOTAP_F_RX_BADPLCP	0x0002 /* bad PLCP */
+
+/* For IEEE80211_RADIOTAP_TX_FLAGS */
+#define IEEE80211_RADIOTAP_F_TX_FAIL	0x0001	/* failed due to excessive
+						 * retries */
+#define IEEE80211_RADIOTAP_F_TX_CTS	0x0002	/* used cts 'protection' */
+#define IEEE80211_RADIOTAP_F_TX_RTS	0x0004	/* used rts/cts handshake */
+
+#endif				/* IEEE80211_RADIOTAP_H */
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ trunk/epan/dissectors/packet-radiotap-iter.c	2009-11-26 18:53:53.000000000 +0100
@@ -0,0 +1,378 @@
+/*
+ * Radiotap parser
+ *
+ * Copyright 2007		Andy Green <andy@warmcat.com>
+ * Copyright 2009		Johannes Berg <johannes@sipsolutions.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See COPYING for more details.
+ */
+#include "packet-radiotap-iter.h"
+#include "packet-radiotap-platform.h"
+
+/* function prototypes and related defs are in radiotap_iter.h */
+
+static const struct radiotap_align_size rtap_namespace_sizes[] = {
+	[IEEE80211_RADIOTAP_TSFT] = { .align = 8, .size = 8, },
+	[IEEE80211_RADIOTAP_FLAGS] = { .align = 1, .size = 1, },
+	[IEEE80211_RADIOTAP_RATE] = { .align = 1, .size = 1, },
+	[IEEE80211_RADIOTAP_CHANNEL] = { .align = 2, .size = 4, },
+	[IEEE80211_RADIOTAP_FHSS] = { .align = 2, .size = 2, },
+	[IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = { .align = 1, .size = 1, },
+	[IEEE80211_RADIOTAP_DBM_ANTNOISE] = { .align = 1, .size = 1, },
+	[IEEE80211_RADIOTAP_LOCK_QUALITY] = { .align = 2, .size = 2, },
+	[IEEE80211_RADIOTAP_TX_ATTENUATION] = { .align = 2, .size = 2, },
+	[IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = { .align = 2, .size = 2, },
+	[IEEE80211_RADIOTAP_DBM_TX_POWER] = { .align = 1, .size = 1, },
+	[IEEE80211_RADIOTAP_ANTENNA] = { .align = 1, .size = 1, },
+	[IEEE80211_RADIOTAP_DB_ANTSIGNAL] = { .align = 1, .size = 1, },
+	[IEEE80211_RADIOTAP_DB_ANTNOISE] = { .align = 1, .size = 1, },
+	[IEEE80211_RADIOTAP_RX_FLAGS] = { .align = 2, .size = 2, },
+	[IEEE80211_RADIOTAP_TX_FLAGS] = { .align = 2, .size = 2, },
+	[IEEE80211_RADIOTAP_RTS_RETRIES] = { .align = 1, .size = 1, },
+	[IEEE80211_RADIOTAP_DATA_RETRIES] = { .align = 1, .size = 1, },
+	/*
+	 * add more here as they are defined in
+	 * include/net/ieee80211_radiotap.h
+	 */
+};
+
+static const struct ieee80211_radiotap_namespace radiotap_ns = {
+	.n_bits = sizeof(rtap_namespace_sizes) / sizeof(rtap_namespace_sizes[0]),
+	.align_size = rtap_namespace_sizes,
+};
+
+/**
+ * ieee80211_radiotap_iterator_init - radiotap parser iterator initialization
+ * @iterator: radiotap_iterator to initialize
+ * @radiotap_header: radiotap header to parse
+ * @max_length: total length we can parse into (eg, whole packet length)
+ *
+ * Returns: 0 or a negative error code if there is a problem.
+ *
+ * This function initializes an opaque iterator struct which can then
+ * be passed to ieee80211_radiotap_iterator_next() to visit every radiotap
+ * argument which is present in the header.  It knows about extended
+ * present headers and handles them.
+ *
+ * How to use:
+ * call __ieee80211_radiotap_iterator_init() to init a semi-opaque iterator
+ * struct ieee80211_radiotap_iterator (no need to init the struct beforehand)
+ * checking for a good 0 return code.  Then loop calling
+ * __ieee80211_radiotap_iterator_next()... it returns either 0,
+ * -ENOENT if there are no more args to parse, or -EINVAL if there is a problem.
+ * The iterator's @this_arg member points to the start of the argument
+ * associated with the current argument index that is present, which can be
+ * found in the iterator's @this_arg_index member.  This arg index corresponds
+ * to the IEEE80211_RADIOTAP_... defines.
+ *
+ * Radiotap header length:
+ * You can find the CPU-endian total radiotap header length in
+ * iterator->max_length after executing ieee80211_radiotap_iterator_init()
+ * successfully.
+ *
+ * Alignment Gotcha:
+ * You must take care when dereferencing iterator.this_arg
+ * for multibyte types... the pointer is not aligned.  Use
+ * get_unaligned((type *)iterator.this_arg) to dereference
+ * iterator.this_arg for type "type" safely on all arches.
+ *
+ * Example code:
+ * See Documentation/networking/radiotap-headers.txt
+ */
+
+int ieee80211_radiotap_iterator_init(
+	struct ieee80211_radiotap_iterator *iterator,
+	struct ieee80211_radiotap_header *radiotap_header,
+	int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns)
+{
+	/* Linux only supports version 0 radiotap format */
+	if (radiotap_header->it_version)
+		return -EINVAL;
+
+	/* sanity check for allowed length and radiotap length field */
+	if (max_length < get_unaligned_le16(&radiotap_header->it_len))
+		return -EINVAL;
+
+	iterator->_rtheader = radiotap_header;
+	iterator->_max_length = get_unaligned_le16(&radiotap_header->it_len);
+	iterator->_arg_index = 0;
+	iterator->_bitmap_shifter = get_unaligned_le32(&radiotap_header->it_present);
+	iterator->_arg = (uint8_t *)radiotap_header + sizeof(*radiotap_header);
+	iterator->_reset_on_ext = 0;
+	iterator->_next_bitmap = &radiotap_header->it_present;
+	iterator->_next_bitmap++;
+	iterator->_vns = vns;
+	iterator->current_namespace = &radiotap_ns;
+	iterator->is_radiotap_ns = 1;
+#ifdef RADIOTAP_SUPPORT_OVERRIDES
+	iterator->n_overrides = 0;
+	iterator->overrides = NULL;
+#endif
+
+	/* find payload start allowing for extended bitmap(s) */
+
+	if (iterator->_bitmap_shifter & (1<<IEEE80211_RADIOTAP_EXT)) {
+		while (get_unaligned_le32(iterator->_arg) &
+					(1 << IEEE80211_RADIOTAP_EXT)) {
+			iterator->_arg += sizeof(uint32_t);
+
+			/*
+			 * check for insanity where the present bitmaps
+			 * keep claiming to extend up to or even beyond the
+			 * stated radiotap header length
+			 */
+
+			if ((unsigned long)iterator->_arg -
+			    (unsigned long)iterator->_rtheader >
+			    (unsigned long)iterator->_max_length)
+				return -EINVAL;
+		}
+
+		iterator->_arg += sizeof(uint32_t);
+
+		/*
+		 * no need to check again for blowing past stated radiotap
+		 * header length, because ieee80211_radiotap_iterator_next
+		 * checks it before it is dereferenced
+		 */
+	}
+
+	iterator->this_arg = iterator->_arg;
+
+	/* we are all initialized happily */
+
+	return 0;
+}
+
+static void find_ns(struct ieee80211_radiotap_iterator *iterator,
+		    uint32_t oui, uint8_t subns)
+{
+	int i;
+
+	iterator->current_namespace = NULL;
+
+	if (!iterator->_vns)
+		return;
+
+	for (i = 0; i < iterator->_vns->n_ns; i++) {
+		if (iterator->_vns->ns[i].oui != oui)
+			continue;
+		if (iterator->_vns->ns[i].subns != subns)
+			continue;
+
+		iterator->current_namespace = &iterator->_vns->ns[i];
+		break;
+	}
+}
+
+#ifdef RADIOTAP_SUPPORT_OVERRIDES
+static int find_override(struct ieee80211_radiotap_iterator *iterator,
+			 int *align, int *size)
+{
+	int i;
+
+	if (!iterator->overrides)
+		return 0;
+
+	for (i = 0; i < iterator->n_overrides; i++) {
+		if (iterator->_arg_index == iterator->overrides[i].field) {
+			*align = iterator->overrides[i].align;
+			*size = iterator->overrides[i].size;
+			if (!*align) /* erroneous override */
+				return 0;
+			return 1;
+		}
+	}
+
+	return 0;
+}
+#endif
+
+
+/**
+ * ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg
+ * @iterator: radiotap_iterator to move to next arg (if any)
+ *
+ * Returns: 0 if there is an argument to handle,
+ * -ENOENT if there are no more args or -EINVAL
+ * if there is something else wrong.
+ *
+ * This function provides the next radiotap arg index (IEEE80211_RADIOTAP_*)
+ * in @this_arg_index and sets @this_arg to point to the
+ * payload for the field.  It takes care of alignment handling and extended
+ * present fields.  @this_arg can be changed by the caller (eg,
+ * incremented to move inside a compound argument like
+ * IEEE80211_RADIOTAP_CHANNEL).  The args pointed to are in
+ * little-endian format whatever the endianess of your CPU.
+ *
+ * Alignment Gotcha:
+ * You must take care when dereferencing iterator.this_arg
+ * for multibyte types... the pointer is not aligned.  Use
+ * get_unaligned((type *)iterator.this_arg) to dereference
+ * iterator.this_arg for type "type" safely on all arches.
+ */
+
+int ieee80211_radiotap_iterator_next(
+	struct ieee80211_radiotap_iterator *iterator)
+{
+	while (1) {
+		int hit = 0;
+		int pad, align, size, subns, vnslen;
+		uint32_t oui;
+
+		/* if no more EXT bits, that's it */
+		if ((iterator->_arg_index % 32) == IEEE80211_RADIOTAP_EXT &&
+		    !(iterator->_bitmap_shifter & 1))
+			return -ENOENT;
+
+		if (!(iterator->_bitmap_shifter & 1))
+			goto next_entry; /* arg not present */
+
+		/* get alignment/size of data */
+		switch (iterator->_arg_index % 32) {
+		case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE:
+		case IEEE80211_RADIOTAP_EXT:
+			align = 1;
+			size = 0;
+			break;
+		case IEEE80211_RADIOTAP_VENDOR_NAMESPACE:
+			align = 2;
+			size = 6;
+			break;
+		default:
+#ifdef RADIOTAP_SUPPORT_OVERRIDES
+			if (find_override(iterator, &align, &size)) {
+				/* all set */
+			} else
+#endif
+			if (!iterator->current_namespace ||
+			    iterator->_arg_index >= iterator->current_namespace->n_bits) {
+				if (iterator->current_namespace == &radiotap_ns)
+					return -ENOENT;
+				align = 0;
+			} else {
+				align = iterator->current_namespace->align_size[iterator->_arg_index].align;
+				size = iterator->current_namespace->align_size[iterator->_arg_index].size;
+			}
+			if (!align) {
+				/* skip all subsequent data */
+				iterator->_arg = iterator->_next_ns_data;
+				/* give up on this namespace */
+				iterator->current_namespace = NULL;
+				goto next_entry;
+			}
+			break;
+		}
+
+		/*
+		 * arg is present, account for alignment padding
+		 *
+		 * Note that these alignments are relative to the start
+		 * of the radiotap header.  There is no guarantee
+		 * that the radiotap header itself is aligned on any
+		 * kind of boundary.
+		 *
+		 * The above is why get_unaligned() is used to dereference
+		 * multibyte elements from the radiotap area.
+		 */
+
+		pad = ((unsigned long)iterator->_arg -
+		       (unsigned long)iterator->_rtheader) & (align - 1);
+
+		if (pad)
+			iterator->_arg += align - pad;
+
+		/*
+		 * this is what we will return to user, but we need to
+		 * move on first so next call has something fresh to test
+		 */
+		iterator->this_arg_index = iterator->_arg_index;
+		iterator->this_arg = iterator->_arg;
+		iterator->this_arg_size = size;
+
+		/* internally move on the size of this arg */
+		iterator->_arg += size;
+
+		/*
+		 * check for insanity where we are given a bitmap that
+		 * claims to have more arg content than the length of the
+		 * radiotap section.  We will normally end up equalling this
+		 * max_length on the last arg, never exceeding it.
+		 */
+
+		if ((unsigned long)iterator->_arg -
+		    (unsigned long)iterator->_rtheader >
+		    (unsigned long)iterator->_max_length)
+			return -EINVAL;
+
+		/* these special ones are valid in each bitmap word */
+		switch (iterator->_arg_index % 32) {
+		case IEEE80211_RADIOTAP_VENDOR_NAMESPACE:
+			iterator->_bitmap_shifter >>= 1;
+			iterator->_arg_index++;
+
+			iterator->_reset_on_ext = 1;
+
+			vnslen = get_unaligned_le16(iterator->this_arg + 4);
+			iterator->_next_ns_data = iterator->_arg + vnslen;
+			oui = (*iterator->this_arg << 16) |
+				(*(iterator->this_arg + 1) << 8) |
+				*(iterator->this_arg + 2);
+			subns = *(iterator->this_arg + 3);
+
+			find_ns(iterator, oui, subns);
+
+			iterator->is_radiotap_ns = 0;
+			/* allow parsers to show this information */
+			iterator->this_arg_index =
+				IEEE80211_RADIOTAP_VENDOR_NAMESPACE;
+			iterator->this_arg_size += vnslen;
+			if ((unsigned long)iterator->this_arg +
+			    iterator->this_arg_size -
+			    (unsigned long)iterator->_rtheader >
+			    (unsigned long)(unsigned long)iterator->_max_length)
+				return -EINVAL;
+			hit = 1;
+			break;
+		case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE:
+			iterator->_bitmap_shifter >>= 1;
+			iterator->_arg_index++;
+
+			iterator->_reset_on_ext = 1;
+			iterator->current_namespace = &radiotap_ns;
+			iterator->is_radiotap_ns = 1;
+			break;
+		case IEEE80211_RADIOTAP_EXT:
+			/*
+			 * bit 31 was set, there is more
+			 * -- move to next u32 bitmap
+			 */
+			iterator->_bitmap_shifter =
+				get_unaligned_le32(iterator->_next_bitmap);
+			iterator->_next_bitmap++;
+			if (iterator->_reset_on_ext)
+				iterator->_arg_index = 0;
+			else
+				iterator->_arg_index++;
+			iterator->_reset_on_ext = 0;
+			break;
+		default:
+			/* we've got a hit! */
+			hit = 1;
+ next_entry:
+			iterator->_bitmap_shifter >>= 1;
+			iterator->_arg_index++;
+		}
+
+		/* if we found a valid arg earlier, return it now */
+		if (hit)
+			return 0;
+	}
+}
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ trunk/epan/dissectors/packet-radiotap-iter.h	2009-11-26 18:53:53.000000000 +0100
@@ -0,0 +1,96 @@
+#ifndef __RADIOTAP_ITER_H
+#define __RADIOTAP_ITER_H
+
+#include <stdint.h>
+#include "packet-radiotap-defs.h"
+
+/* Radiotap header iteration
+ *   implemented in radiotap.c
+ */
+
+struct radiotap_override {
+	uint8_t field;
+	uint8_t align:4, size:4;
+};
+
+struct radiotap_align_size {
+	uint8_t align:4, size:4;
+};
+
+struct ieee80211_radiotap_namespace {
+	const struct radiotap_align_size *align_size;
+	int n_bits;
+	uint32_t oui;
+	uint8_t subns;
+};
+
+struct ieee80211_radiotap_vendor_namespaces {
+	const struct ieee80211_radiotap_namespace *ns;
+	int n_ns;
+};
+
+/**
+ * struct ieee80211_radiotap_iterator - tracks walk thru present radiotap args
+ * @this_arg_index: index of current arg, valid after each successful call
+ *	to ieee80211_radiotap_iterator_next()
+ * @this_arg: pointer to current radiotap arg; it is valid after each
+ *	call to ieee80211_radiotap_iterator_next() but also after
+ *	ieee80211_radiotap_iterator_init() where it will point to
+ *	the beginning of the actual data portion
+ * @this_arg_size: length of the current arg, for convenience
+ * @current_namespace: pointer to the current namespace definition
+ *	(or internally %NULL if the current namespace is unknown)
+ * @is_radiotap_ns: indicates whether the current namespace is the default
+ *	radiotap namespace or not
+ *
+ * @overrides: override standard radiotap fields
+ * @n_overrides: number of overrides
+ *
+ * @_rtheader: pointer to the radiotap header we are walking through
+ * @_max_length: length of radiotap header in cpu byte ordering
+ * @_arg_index: next argument index
+ * @_arg: next argument pointer
+ * @_next_bitmap: internal pointer to next present u32
+ * @_bitmap_shifter: internal shifter for curr u32 bitmap, b0 set == arg present
+ * @_vns: vendor namespace definitions
+ * @_next_ns_data: beginning of the next namespace's data
+ * @_reset_on_ext: internal; reset the arg index to 0 when going to the
+ *	next bitmap word
+ *
+ * Describes the radiotap parser state. Fields prefixed with an underscore
+ * must not be used by users of the parser, only by the parser internally.
+ */
+
+struct ieee80211_radiotap_iterator {
+	struct ieee80211_radiotap_header *_rtheader;
+	const struct ieee80211_radiotap_vendor_namespaces *_vns;
+	const struct ieee80211_radiotap_namespace *current_namespace;
+
+	unsigned char *_arg, *_next_ns_data;
+	uint32_t *_next_bitmap;
+
+	unsigned char *this_arg;
+#ifdef RADIOTAP_SUPPORT_OVERRIDES
+	const struct radiotap_override *overrides;
+	int n_overrides;
+#endif
+	int this_arg_index;
+	int this_arg_size;
+
+	int is_radiotap_ns;
+
+	int _max_length;
+	int _arg_index;
+	uint32_t _bitmap_shifter;
+	int _reset_on_ext;
+};
+
+extern int ieee80211_radiotap_iterator_init(
+	struct ieee80211_radiotap_iterator *iterator,
+	struct ieee80211_radiotap_header *radiotap_header,
+	int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns);
+
+extern int ieee80211_radiotap_iterator_next(
+	struct ieee80211_radiotap_iterator *iterator);
+
+#endif /* __RADIOTAP_ITER_H */
--- trunk.orig/epan/dissectors/Makefile.am	2009-11-26 18:50:51.000000000 +0100
+++ trunk/epan/dissectors/Makefile.am	2009-11-26 18:53:53.000000000 +0100
@@ -40,7 +40,7 @@ libdissectors_la_SOURCES = \
 	$(ASN1_DISSECTOR_SRC) \
 	$(PIDL_DISSECTOR_SRC) \
 	$(DISSECTOR_SUPPORT_SRC)
-libdissectors_la_CFLAGS = $(AM_CLEAN_CFLAGS)
+libdissectors_la_CFLAGS = $(AM_CLEAN_CFLAGS) -DRADIOTAP_SUPPORT_OVERRIDES
 
 
 EXTRA_DIST = \
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ trunk/epan/dissectors/packet-radiotap-platform.h	2009-11-26 18:53:53.000000000 +0100
@@ -0,0 +1,9 @@
+#include <stddef.h>
+#include <errno.h>
+#include <glib.h>
+#include "pint.h"
+
+#define le16_to_cpu		GINT16_FROM_LE
+#define le32_to_cpu		GINT32_FROM_LE
+#define get_unaligned_le16	pletohs
+#define get_unaligned_le32	pletohl
--- trunk.orig/epan/dissectors/packet-radiotap.c	2009-11-26 18:50:51.000000000 +0100
+++ trunk/epan/dissectors/packet-radiotap.c	2009-11-26 18:53:53.000000000 +0100
@@ -29,8 +29,11 @@
 # include "config.h"
 #endif
 
+#include <stdio.h>
+
 #include <glib.h>
 #include <string.h>
+#include <errno.h>
 
 #include <epan/packet.h>
 #include <epan/crc32.h>
@@ -39,6 +42,15 @@
 #include <epan/prefs.h>
 #include "packet-ieee80211.h"
 #include "packet-radiotap.h"
+#include "packet-radiotap-iter.h"
+#include "packet-radiotap-defs.h"
+
+/* not officially defined (yet) */
+#define IEEE80211_RADIOTAP_F_SHORTGI	0x80
+#define IEEE80211_RADIOTAP_XCHANNEL	18
+#define IEEE80211_CHAN_HT20		0x10000	/* HT 20 channel */
+#define IEEE80211_CHAN_HT40U		0x20000	/* HT 40 channel w/ ext above */
+#define IEEE80211_CHAN_HT40D		0x40000	/* HT 40 channel w/ ext below */
 
 /* Official specifcation:
  *
@@ -49,70 +61,6 @@
  * NetBSD's ieee80211_radiotap.h file
  */
 
-struct ieee80211_radiotap_header {
-    guint8	it_version;	/* Version 0. Only increases
-				 * for drastic changes,
-				 * introduction of compatible
-				 * new fields does not count.
-				 */
-    guint8	it_pad;
-    guint16     it_len;         /* length of the whole
-				 * header in bytes, including
-				 * it_version, it_pad,
-				 * it_len, and data fields.
-				 */
-#define MAX_PRESENT 1
-    guint32   it_present[MAX_PRESENT];	/* A bitmap telling which
-					 * fields are present. Set bit 31
-					 * (0x80000000) to extend the
-					 * bitmap by another 32 bits.
-					 * Additional extensions are made
-					 * by setting bit 31.
-					 */
-};
-
-#define RADIOTAP_MIN_HEADER_LEN	8	/* minimum header length */
-#define RADIOTAP_VERSION_OFFSET	0	/* offset of version field */
-#define RADIOTAP_LENGTH_OFFSET	2	/* offset of length field */
-#define RADIOTAP_PRESENT_OFFSET	4	/* offset of "present" field */
-
-enum ieee80211_radiotap_type {
-    IEEE80211_RADIOTAP_TSFT = 0,
-    IEEE80211_RADIOTAP_FLAGS = 1,
-    IEEE80211_RADIOTAP_RATE = 2,
-    IEEE80211_RADIOTAP_CHANNEL = 3,
-    IEEE80211_RADIOTAP_FHSS = 4,
-    IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
-    IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
-    IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
-    IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
-    IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
-    IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
-    IEEE80211_RADIOTAP_ANTENNA = 11,
-    IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
-    IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
-    IEEE80211_RADIOTAP_RX_FLAGS = 14,
-    IEEE80211_RADIOTAP_XCHANNEL = 18,
-    IEEE80211_RADIOTAP_EXT = 31
-};
-
-/* Channel flags. */
-#define	IEEE80211_CHAN_TURBO	0x00010	/* Turbo channel */
-#define	IEEE80211_CHAN_CCK	0x00020	/* CCK channel */
-#define	IEEE80211_CHAN_OFDM	0x00040	/* OFDM channel */
-#define	IEEE80211_CHAN_2GHZ	0x00080	/* 2 GHz spectrum channel. */
-#define	IEEE80211_CHAN_5GHZ	0x00100	/* 5 GHz spectrum channel */
-#define	IEEE80211_CHAN_PASSIVE	0x00200	/* Only passive scan allowed */
-#define	IEEE80211_CHAN_DYN	0x00400	/* Dynamic CCK-OFDM channel */
-#define	IEEE80211_CHAN_GFSK	0x00800	/* GFSK channel (FHSS PHY) */
-#define	IEEE80211_CHAN_GSM	0x01000	/* 900 MHz spectrum channel */
-#define	IEEE80211_CHAN_STURBO	0x02000	/* 11a static turbo channel only */
-#define	IEEE80211_CHAN_HALF	0x04000	/* Half rate channel */
-#define	IEEE80211_CHAN_QUARTER	0x08000	/* Quarter rate channel */
-#define	IEEE80211_CHAN_HT20	0x10000	/* HT 20 channel */
-#define	IEEE80211_CHAN_HT40U	0x20000	/* HT 40 channel w/ ext above */
-#define	IEEE80211_CHAN_HT40D	0x40000	/* HT 40 channel w/ ext below */
-
 /*
  * Useful combinations of channel characteristics.
  */
@@ -133,31 +81,6 @@ enum ieee80211_radiotap_type {
 #define	IEEE80211_CHAN_108PUREG \
 	(IEEE80211_CHAN_PUREG | IEEE80211_CHAN_TURBO)
 
-/* For IEEE80211_RADIOTAP_FLAGS */
-#define	IEEE80211_RADIOTAP_F_CFP	0x01	/* sent/received
-						 * during CFP
-						 */
-#define	IEEE80211_RADIOTAP_F_SHORTPRE	0x02	/* sent/received
-						 * with short
-						 * preamble
-						 */
-#define	IEEE80211_RADIOTAP_F_WEP	0x04	/* sent/received
-						 * with WEP encryption
-						 */
-#define	IEEE80211_RADIOTAP_F_FRAG	0x08	/* sent/received
-						 * with fragmentation
-						 */
-#define	IEEE80211_RADIOTAP_F_FCS	0x10	/* frame includes FCS */
-#define	IEEE80211_RADIOTAP_F_DATAPAD	0x20	/* frame has padding between
-						 * 802.11 header and payload
-						 * (to 32-bit boundary)
-						 */
-#define	IEEE80211_RADIOTAP_F_BADFCS	0x40	/* does not pass FCS check */
-#define	IEEE80211_RADIOTAP_F_SHORTGI	0x80	/* HT short GI */
-
-/* For IEEE80211_RADIOTAP_RX_FLAGS */
-#define IEEE80211_RADIOTAP_F_RX_BADPLCP		0x0002 /* bad PLCP */
-
 /* XXX need max array size */
 static const int ieee80211_htrates[16] = {
 	13,		/* IFM_IEEE80211_MCS0 */
@@ -221,9 +144,6 @@ static int hf_radiotap_xchannel_flags_qu
 static int hf_radiotap_xchannel_flags_ht20 = -1;
 static int hf_radiotap_xchannel_flags_ht40u = -1;
 static int hf_radiotap_xchannel_flags_ht40d = -1;
-#if 0
-static int hf_radiotap_xchannel_maxpower = -1;
-#endif
 static int hf_radiotap_fhss_hopset = -1;
 static int hf_radiotap_fhss_pattern = -1;
 static int hf_radiotap_datarate = -1;
@@ -235,6 +155,11 @@ static int hf_radiotap_db_antnoise = -1;
 static int hf_radiotap_tx_attenuation = -1;
 static int hf_radiotap_db_tx_attenuation = -1;
 static int hf_radiotap_txpower = -1;
+static int hf_radiotap_vendor_ns = -1;
+static int hf_radiotap_ven_oui = -1;
+static int hf_radiotap_ven_subns = -1;
+static int hf_radiotap_ven_skip = -1;
+static int hf_radiotap_ven_data = -1;
 
 /* "Present" flags */
 static int hf_radiotap_present_tsft = -1;
@@ -254,6 +179,8 @@ static int hf_radiotap_present_db_antnoi
 static int hf_radiotap_present_hdrfcs = -1;
 static int hf_radiotap_present_rxflags = -1;
 static int hf_radiotap_present_xchannel = -1;
+static int hf_radiotap_present_rtap_ns = -1;
+static int hf_radiotap_present_vendor_ns = -1;
 static int hf_radiotap_present_ext = -1;
 
 /* "present.flags" flags */
@@ -277,6 +204,7 @@ static gint ett_radiotap_flags = -1;
 static gint ett_radiotap_rxflags = -1;
 static gint ett_radiotap_channel_flags = -1;
 static gint ett_radiotap_xchannel_flags = -1;
+static gint ett_radiotap_vendor = -1;
 
 static dissector_handle_t ieee80211_handle;
 static dissector_handle_t ieee80211_datapad_handle;
@@ -309,25 +237,21 @@ dissect_radiotap(tvbuff_t *tvb, packet_i
  *    dissectors, such as tcpdump(8), expect the padding.
  */
 
-/*
- * Returns the amount required to align "offset" with "width"
- */
-#define ALIGN_OFFSET(offset, width) \
-    ( (((offset) + ((width) - 1)) & (~((width) - 1))) - offset )
-
 
 void
 capture_radiotap(const guchar *pd, int offset, int len, packet_counts *ld)
 {
     guint16 it_len;
-    guint32 present;
+    guint32 present, xpresent;
     guint8 rflags;
+    struct ieee80211_radiotap_header *hdr;
 
-    if(!BYTES_ARE_IN_FRAME(offset, len, RADIOTAP_MIN_HEADER_LEN)) {
+    if(!BYTES_ARE_IN_FRAME(offset, len, sizeof(struct ieee80211_radiotap_header))) {
         ld->other ++;
         return;
     }
-    it_len = pletohs(&pd[RADIOTAP_LENGTH_OFFSET]);
+    hdr = (void *)pd;
+    it_len = pletohs(&hdr->it_len);
     if(!BYTES_ARE_IN_FRAME(offset, len, it_len)) {
         ld->other ++;
         return;
@@ -339,28 +263,48 @@ capture_radiotap(const guchar *pd, int o
         return;
     }
 
-    if(it_len < RADIOTAP_MIN_HEADER_LEN) {
+    if(it_len < sizeof(struct ieee80211_radiotap_header)) {
         /* Header length is shorter than fixed-length portion of header */
         ld->other ++;
         return;
     }
 
-    present = pletohl(&pd[RADIOTAP_PRESENT_OFFSET]);
-    offset += RADIOTAP_MIN_HEADER_LEN;
-    it_len -= RADIOTAP_MIN_HEADER_LEN;
+    present = pletohl(&hdr->it_present);
+    offset += sizeof(struct ieee80211_radiotap_header);
+    it_len -= sizeof(struct ieee80211_radiotap_header);
+
+    /* skip over other present bitmaps */
+    xpresent = present;
+    while (xpresent & BIT(IEEE80211_RADIOTAP_EXT)) {
+        if (!BYTES_ARE_IN_FRAME(offset, 4, it_len)) {
+            ld->other ++;
+            return;
+        }
+        xpresent = pletohl(pd + offset);
+        offset += 4;
+        it_len -= 4;
+    }
 
     rflags = 0;
 
     /*
-     * IEEE80211_RADIOTAP_TSFT is the lowest-order bit.
+     * IEEE80211_RADIOTAP_TSFT is the lowest-order bit,
+     * just skip over it.
      */
     if (present & BIT(IEEE80211_RADIOTAP_TSFT)) {
+        /* align it properly */
+        if (offset & 7) {
+            int pad = 8 - (offset & 7);
+            offset += pad;
+            it_len -= pad;
+        }
+
     	if (it_len < 8) {
 	    /* No room in header for this field. */
 	    ld->other ++;
 	    return;
 	}
-	/* That field is present, and it's 8 bits long. */
+	/* That field is present, and it's 8 bytes long. */
 	offset += 8;
 	it_len -= 8;
     }
@@ -431,115 +375,109 @@ proto_register_radiotap(void)
 	 "Length of header including version, pad, length and data fields", HFILL } },
     { &hf_radiotap_present,
        { "Present flags", "radiotap.present",
-	 FT_UINT32, BASE_HEX, NULL, 0x0, "Bitmask indicating which fields are present", HFILL } },
+	 FT_NONE, BASE_NONE, NULL, 0x0, "Bitmask indicating which fields are present", HFILL } },
 
-#define RADIOTAP_MASK_TSFT                  0x00000001
-#define RADIOTAP_MASK_FLAGS                 0x00000002
-#define RADIOTAP_MASK_RATE                  0x00000004
-#define RADIOTAP_MASK_CHANNEL               0x00000008
-#define RADIOTAP_MASK_FHSS                  0x00000010
-#define RADIOTAP_MASK_DBM_ANTSIGNAL         0x00000020
-#define RADIOTAP_MASK_DBM_ANTNOISE          0x00000040
-#define RADIOTAP_MASK_LOCK_QUALITY          0x00000080
-#define RADIOTAP_MASK_TX_ATTENUATION        0x00000100
-#define RADIOTAP_MASK_DB_TX_ATTENUATION     0x00000200
-#define RADIOTAP_MASK_DBM_TX_ATTENUATION    0x00000400
-#define RADIOTAP_MASK_ANTENNA               0x00000800
-#define RADIOTAP_MASK_DB_ANTSIGNAL          0x00001000
-#define RADIOTAP_MASK_DB_ANTNOISE           0x00002000
-#define RADIOTAP_MASK_RX_FLAGS              0x00004000
-#define RADIOTAP_MASK_XCHANNEL              0x00040000
-#define RADIOTAP_MASK_EXT                   0x80000000
+#define RADIOTAP_MASK(name)	BIT(IEEE80211_RADIOTAP_ ##name)
 
     /* Boolean 'present' flags */
     { &hf_radiotap_present_tsft,
       { "TSFT", "radiotap.present.tsft",
-	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_TSFT,
+	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(TSFT),
 	"Specifies if the Time Synchronization Function Timer field is present", HFILL } },
 
     { &hf_radiotap_present_flags,
       { "Flags", "radiotap.present.flags",
-	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_FLAGS,
+	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(FLAGS),
 	"Specifies if the channel flags field is present", HFILL } },
 
     { &hf_radiotap_present_rate,
       { "Rate", "radiotap.present.rate",
-	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_RATE,
+	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(RATE),
 	"Specifies if the transmit/receive rate field is present", HFILL } },
 
     { &hf_radiotap_present_channel,
       { "Channel", "radiotap.present.channel",
-	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_CHANNEL,
+	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(CHANNEL),
 	"Specifies if the transmit/receive frequency field is present", HFILL } },
 
     { &hf_radiotap_present_fhss,
       { "FHSS", "radiotap.present.fhss",
-	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_FHSS,
+	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(FHSS),
 	"Specifies if the hop set and pattern is present for frequency hopping radios", HFILL } },
 
     { &hf_radiotap_present_dbm_antsignal,
       { "DBM Antenna Signal", "radiotap.present.dbm_antsignal",
-	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_DBM_ANTSIGNAL,
+	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(DBM_ANTSIGNAL),
 	"Specifies if the antenna signal strength in dBm is present", HFILL } },
 
     { &hf_radiotap_present_dbm_antnoise,
       { "DBM Antenna Noise", "radiotap.present.dbm_antnoise",
-	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_DBM_ANTNOISE,
+	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(DBM_ANTNOISE),
 	"Specifies if the RF noise power at antenna field is present", HFILL } },
 
     { &hf_radiotap_present_lock_quality,
       { "Lock Quality", "radiotap.present.lock_quality",
-	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_LOCK_QUALITY,
+	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(LOCK_QUALITY),
 	"Specifies if the signal quality field is present", HFILL } },
 
     { &hf_radiotap_present_tx_attenuation,
       { "TX Attenuation", "radiotap.present.tx_attenuation",
-	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_TX_ATTENUATION,
+	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(TX_ATTENUATION),
 	"Specifies if the transmit power from max power field is present", HFILL } },
 
     { &hf_radiotap_present_db_tx_attenuation,
       { "DB TX Attenuation", "radiotap.present.db_tx_attenuation",
-	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_DB_TX_ATTENUATION,
+	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(DB_TX_ATTENUATION),
 	"Specifies if the transmit power from max power (in dB) field is present", HFILL } },
 
     { &hf_radiotap_present_dbm_tx_attenuation,
       { "DBM TX Attenuation", "radiotap.present.dbm_tx_attenuation",
-	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_DBM_TX_ATTENUATION,
+	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(DB_TX_ATTENUATION),
 	"Specifies if the transmit power from max power (in dBm) field is present", HFILL } },
 
     { &hf_radiotap_present_antenna,
       { "Antenna", "radiotap.present.antenna",
-	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_ANTENNA,
+	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(ANTENNA),
 	"Specifies if the antenna number field is present", HFILL } },
 
     { &hf_radiotap_present_db_antsignal,
       { "DB Antenna Signal", "radiotap.present.db_antsignal",
-	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_DB_ANTSIGNAL,
+	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(DB_ANTSIGNAL),
 	"Specifies if the RF signal power at antenna in dB field is present", HFILL } },
 
     { &hf_radiotap_present_db_antnoise,
       { "DB Antenna Noise", "radiotap.present.db_antnoise",
-	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_DB_ANTNOISE,
+	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(DB_ANTNOISE),
 	"Specifies if the RF signal power at antenna in dBm field is present", HFILL } },
 
     { &hf_radiotap_present_rxflags,
       { "RX flags", "radiotap.present.rxflags",
-	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_RX_FLAGS,
+	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(RX_FLAGS),
 	"Specifies if the RX flags field is present", HFILL } },
 
     { &hf_radiotap_present_hdrfcs,
       { "FCS in header", "radiotap.present.fcs",
-	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_RX_FLAGS,
+	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(RX_FLAGS),
 	"Specifies if the FCS field is present", HFILL } },
 
     { &hf_radiotap_present_xchannel,
       { "Channel+", "radiotap.present.xchannel",
-	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_XCHANNEL,
+	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(XCHANNEL),
 	"Specifies if the extended channel info field is present", HFILL } },
 
+    { &hf_radiotap_present_rtap_ns,
+      { "Radiotap NS next", "radiotap.present.rtap_ns",
+	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(RADIOTAP_NAMESPACE),
+	"Specifies a reset to the radiotap namespace", HFILL } },
+
+    { &hf_radiotap_present_vendor_ns,
+      { "Vendor NS next", "radiotap.present.vendor_ns",
+	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(VENDOR_NAMESPACE),
+	"Specifies that the next bitmap is in a vendor namespace", HFILL } },
+
     { &hf_radiotap_present_ext,
       { "Ext", "radiotap.present.ext",
-	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_EXT,
+	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK(EXT),
 	"Specifies if there are any extensions to the header present", HFILL } },
 
     /* Boolean 'present.flags' flags */
@@ -719,11 +657,6 @@ proto_register_radiotap(void)
     { &hf_radiotap_xchannel_flags_ht40d,
        { "HT Channel (40MHz Channel Width with Extension channel below)", "radiotap.xchannel.type.ht40d",
 	 FT_BOOLEAN, 24, NULL, 0x40000, "Channel Type HT/40-", HFILL } },
-#if 0
-    { &hf_radiotap_xchannel_maxpower,
-      { "Max transmit power", "radiotap.xchannel.maxpower",
-	FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } },
-#endif
     { &hf_radiotap_fhss_hopset,
       { "FHSS Hop Set", "radiotap.fhss.hopset",
 	FT_UINT8, BASE_DEC, NULL,  0x0,
@@ -779,6 +712,31 @@ proto_register_radiotap(void)
 	FT_INT32, BASE_DEC, NULL, 0x0,
 	"Transmit power in decibels per one milliwatt (dBm)", HFILL } },
 
+    { &hf_radiotap_vendor_ns,
+      { "Vendor namespace", "radiotap.vendor_ns",
+	FT_NONE, BASE_NONE, NULL, 0x0,
+	"Vendor namespace", HFILL } },
+
+    { &hf_radiotap_ven_oui,
+      { "Vendor OUI", "radiotap.vendor_oui",
+	FT_BYTES, BASE_NONE, NULL, 0x0,
+	"Vendor OUI", HFILL } },
+
+    { &hf_radiotap_ven_subns,
+      { "Vendor sub namespace", "radiotap.vendor_subns",
+	FT_UINT8, BASE_DEC, NULL, 0x0,
+	"Vendor-specified sub namespace", HFILL } },
+
+    { &hf_radiotap_ven_skip,
+      { "Vendor data length", "radiotap.vendor_data_len",
+	FT_UINT16, BASE_DEC, NULL, 0x0,
+	"Length of vendor-specified data", HFILL } },
+
+    { &hf_radiotap_ven_data,
+      { "Vendor data", "radiotap.vendor_data",
+	FT_NONE, BASE_NONE, NULL, 0x0,
+	"Vendor-specified data", HFILL } },
+
     /* Special variables */
     { &hf_radiotap_fcs_bad,
       { "Bad FCS", "radiotap.fcs_bad",
@@ -792,7 +750,8 @@ proto_register_radiotap(void)
     &ett_radiotap_flags,
     &ett_radiotap_rxflags,
     &ett_radiotap_channel_flags,
-    &ett_radiotap_xchannel_flags
+    &ett_radiotap_xchannel_flags,
+    &ett_radiotap_vendor,
   };
   module_t *radiotap_module;
 
@@ -818,34 +777,45 @@ dissect_radiotap(tvbuff_t *tvb, packet_i
     proto_tree *radiotap_tree = NULL;
     proto_tree *pt, *present_tree = NULL;
     proto_tree *ft, *flags_tree = NULL;
-    proto_item *ti = NULL, *hidden_item;
-    int align_offset, offset;
+    proto_item *ti = NULL;
+    proto_item *hidden_item;
+    int offset;
     tvbuff_t *next_tvb;
-    guint32 version;
-    guint length, length_remaining;
+    guint8 version;
+    guint length;
     guint32 rate, freq, flags;
-    gint8 dbm;
-    guint8 db, rflags;
-    guint32 present, next_present;
-    int bit;
+    gint8 dbm, db;
+    guint8 rflags = 0;
     /* backward compat with bit 14 == fcs in header */
     proto_item *hdr_fcs_ti = NULL;
     int hdr_fcs_offset = 0;
     guint32 sent_fcs = 0;
     guint32 calc_fcs;
-
+    gint err;
+    struct ieee80211_radiotap_iterator iter;
+    void *data;
     struct _radiotap_info *radiotap_info;
-    static struct _radiotap_info rtp_info_arr[1];
-    
-    radiotap_info = &rtp_info_arr[0];
+    static struct _radiotap_info rtp_info_arr;
+
+    /* our non-standard overrides */
+    static struct radiotap_override overrides[] = {
+    	{ IEEE80211_RADIOTAP_XCHANNEL, 4, 8 }, /* xchannel */
+
+        /* keep last */
+    	{ 14, 4, 4 }, /* FCS in header */
+    };
+    guint n_overrides = array_length(overrides);
+
+    if (!radiotap_bit14_fcs)
+        n_overrides--;
+
+    radiotap_info = &rtp_info_arr;
 
     col_set_str(pinfo->cinfo, COL_PROTOCOL, "WLAN");
     col_clear(pinfo->cinfo, COL_INFO);
-    offset = 0;
 
-    version = tvb_get_guint8(tvb, offset);
-    length = tvb_get_letohs(tvb, offset+2);
-    present = tvb_get_letohl(tvb, offset+4);
+    version = tvb_get_guint8(tvb, 0);
+    length = tvb_get_letohs(tvb, 2);
     
     radiotap_info->radiotap_length = length;
 
@@ -858,441 +828,384 @@ dissect_radiotap(tvbuff_t *tvb, packet_i
 		tvb, 0, length, "Radiotap Header v%u, Length %u", version, length);
 	radiotap_tree = proto_item_add_subtree(ti, ett_radiotap);
 	proto_tree_add_uint(radiotap_tree, hf_radiotap_version,
-		tvb, offset, 1, version);
+		tvb, 0, 1, version);
 	proto_tree_add_item(radiotap_tree, hf_radiotap_pad,
-		tvb, offset + 1, 1, FALSE);
-	ti = proto_tree_add_uint(radiotap_tree, hf_radiotap_length,
-		tvb, offset + 2, 2, length);
+		tvb, 1, 1, FALSE);
+	proto_tree_add_uint(radiotap_tree, hf_radiotap_length,
+		tvb, 2, 2, length);
     }
-    length_remaining = length;
 
-    /*
-     * FIXME: This only works if there is exactly 1 it_present
-     *        field in the header
-     */
-    if (length_remaining < RADIOTAP_MIN_HEADER_LEN) {
-	/*
-	 * Radiotap header is shorter than the fixed-length portion
-	 * plus one "present" bitset.
-	 */
-	if (tree)
-	    proto_item_append_text(ti, " (bogus - minimum length is 8)");
-	return;
+    data = ep_tvb_memdup(tvb, 0, length);
+    if (!data)
+        return;
+
+    if (ieee80211_radiotap_iterator_init(&iter, data, length, NULL)) {
+        if (tree)
+            proto_item_append_text(ti, " (invalid)");
+        /* maybe the length was correct anyway ... */
+        goto hand_off_to_80211;
     }
-    /* Subtree for the "present flags" bitfield. */
+
+    iter.overrides = overrides;
+    iter.n_overrides = n_overrides;
+
+    /* Add the "present flags" bitmaps. */
     if (tree) {
-	pt = proto_tree_add_uint(radiotap_tree, hf_radiotap_present,
-	    tvb, offset + 4, 4, present);
-	present_tree = proto_item_add_subtree(pt, ett_radiotap_present);
-
-	proto_tree_add_item(present_tree, hf_radiotap_present_tsft,
-	    tvb, 4, 4, TRUE);
-	proto_tree_add_item(present_tree, hf_radiotap_present_flags,
-	    tvb, 4, 4, TRUE);
-	proto_tree_add_item(present_tree, hf_radiotap_present_rate,
-	    tvb, 4, 4, TRUE);
-	proto_tree_add_item(present_tree, hf_radiotap_present_channel,
-	    tvb, 4, 4, TRUE);
-	proto_tree_add_item(present_tree, hf_radiotap_present_fhss,
-	    tvb, 4, 4, TRUE);
-	proto_tree_add_item(present_tree, hf_radiotap_present_dbm_antsignal,
-	    tvb, 4, 4, TRUE);
-	proto_tree_add_item(present_tree, hf_radiotap_present_dbm_antnoise,
-	    tvb, 4, 4, TRUE);
-	proto_tree_add_item(present_tree, hf_radiotap_present_lock_quality,
-	    tvb, 4, 4, TRUE);
-	proto_tree_add_item(present_tree, hf_radiotap_present_tx_attenuation,
-	    tvb, 4, 4, TRUE);
-	proto_tree_add_item(present_tree, hf_radiotap_present_db_tx_attenuation,
-	    tvb, 4, 4, TRUE);
-	proto_tree_add_item(present_tree, hf_radiotap_present_dbm_tx_attenuation,
-	    tvb, 4, 4, TRUE);
-	proto_tree_add_item(present_tree, hf_radiotap_present_antenna,
-	    tvb, 4, 4, TRUE);
-	proto_tree_add_item(present_tree, hf_radiotap_present_db_antsignal,
-	    tvb, 4, 4, TRUE);
-	proto_tree_add_item(present_tree, hf_radiotap_present_db_antnoise,
-	    tvb, 4, 4, TRUE);
-	if (radiotap_bit14_fcs) {
-		proto_tree_add_item(present_tree, hf_radiotap_present_hdrfcs,
-			tvb, 4, 4, TRUE);
-	} else {
-		proto_tree_add_item(present_tree, hf_radiotap_present_rxflags,
-			tvb, 4, 4, TRUE);
-	}
-	proto_tree_add_item(present_tree, hf_radiotap_present_xchannel,
-	    tvb, 4, 4, TRUE);
-	proto_tree_add_item(present_tree, hf_radiotap_present_ext,
-	    tvb, 4, 4, TRUE);
+        guchar *bmap_start = (guchar *)data + 4;
+        guint n_bitmaps = (iter.this_arg - bmap_start) / 4;
+        guint i;
+        gboolean rtap_ns = TRUE;
+        guint rtap_ns_offset, rtap_ns_offset_next = 0;
+
+        pt = proto_tree_add_item(radiotap_tree, hf_radiotap_present,
+            tvb, 4, n_bitmaps * 4, FALSE /* ?? */);
+
+        for (i = 0; i < n_bitmaps; i++) {
+            guint32 bmap = pletohl(bmap_start + 4 * i);
+
+            rtap_ns_offset = rtap_ns_offset_next;
+            rtap_ns_offset_next += 4;
+
+            if (bmap & BIT(IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE)) {
+                rtap_ns = TRUE;
+                rtap_ns_offset_next = 0;
+            }
+            if (bmap & BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE))
+                rtap_ns = FALSE;
+
+            present_tree = proto_item_add_subtree(pt, ett_radiotap_present);
+
+            offset = 4 * i;
+
+            if (!rtap_ns)
+                goto always_bits;
+
+            if (rtap_ns_offset)
+                goto always_bits;
+
+            proto_tree_add_item(present_tree, hf_radiotap_present_tsft,
+                tvb, offset + 4, 4, TRUE);
+            proto_tree_add_item(present_tree, hf_radiotap_present_flags,
+                tvb, offset + 4, 4, TRUE);
+            proto_tree_add_item(present_tree, hf_radiotap_present_rate,
+                tvb, offset + 4, 4, TRUE);
+            proto_tree_add_item(present_tree, hf_radiotap_present_channel,
+                tvb, offset + 4, 4, TRUE);
+            proto_tree_add_item(present_tree, hf_radiotap_present_fhss,
+                tvb, offset + 4, 4, TRUE);
+            proto_tree_add_item(present_tree, hf_radiotap_present_dbm_antsignal,
+                tvb, offset + 4, 4, TRUE);
+            proto_tree_add_item(present_tree, hf_radiotap_present_dbm_antnoise,
+                tvb, offset + 4, 4, TRUE);
+            proto_tree_add_item(present_tree, hf_radiotap_present_lock_quality,
+                tvb, offset + 4, 4, TRUE);
+            proto_tree_add_item(present_tree, hf_radiotap_present_tx_attenuation,
+                tvb, offset + 4, 4, TRUE);
+            proto_tree_add_item(present_tree, hf_radiotap_present_db_tx_attenuation,
+                tvb, offset + 4, 4, TRUE);
+            proto_tree_add_item(present_tree, hf_radiotap_present_dbm_tx_attenuation,
+                tvb, offset + 4, 4, TRUE);
+            proto_tree_add_item(present_tree, hf_radiotap_present_antenna,
+                tvb, offset + 4, 4, TRUE);
+            proto_tree_add_item(present_tree, hf_radiotap_present_db_antsignal,
+                tvb, offset + 4, 4, TRUE);
+            proto_tree_add_item(present_tree, hf_radiotap_present_db_antnoise,
+                tvb, offset + 4, 4, TRUE);
+            if (radiotap_bit14_fcs) {
+                    proto_tree_add_item(present_tree, hf_radiotap_present_hdrfcs,
+                            tvb, offset + 4, 4, TRUE);
+            } else {
+                    proto_tree_add_item(present_tree, hf_radiotap_present_rxflags,
+                            tvb, offset + 4, 4, TRUE);
+            }
+            proto_tree_add_item(present_tree, hf_radiotap_present_xchannel,
+                tvb, offset + 4, 4, TRUE);
+
+ always_bits:
+            proto_tree_add_item(present_tree, hf_radiotap_present_rtap_ns,
+                tvb, offset + 4, 4, TRUE);
+            proto_tree_add_item(present_tree, hf_radiotap_present_vendor_ns,
+                tvb, offset + 4, 4, TRUE);
+            proto_tree_add_item(present_tree, hf_radiotap_present_ext,
+                tvb, offset + 4, 4, TRUE);
+        }
     }
-    offset += RADIOTAP_MIN_HEADER_LEN;
-    length_remaining -= RADIOTAP_MIN_HEADER_LEN;
 
-    rflags = 0;
-    for (; present; present = next_present) {
-	/* clear the least significant bit that is set */
-	next_present = present & (present - 1);
-
-	/* extract the least significant bit that is set */
-	bit = BITNO_32(present ^ next_present);
-
-	switch (bit) {
-	case IEEE80211_RADIOTAP_FLAGS:
-	    if (length_remaining < 1)
-		break;
-	    rflags = tvb_get_guint8(tvb, offset);
-	    if (tree) {
-        ft = proto_tree_add_item(radiotap_tree, hf_radiotap_flags,
-            tvb, offset, 1, FALSE);
-        flags_tree = proto_item_add_subtree(ft, ett_radiotap_flags);
-
-		proto_tree_add_item(flags_tree, hf_radiotap_flags_cfp,
-			tvb, offset, 1, FALSE);
-		proto_tree_add_item(flags_tree, hf_radiotap_flags_preamble,
-			tvb, offset, 1, FALSE);
-		proto_tree_add_item(flags_tree, hf_radiotap_flags_wep,
-			tvb, offset, 1, FALSE);
-		proto_tree_add_item(flags_tree, hf_radiotap_flags_frag,
-			tvb, offset, 1, FALSE);
-		proto_tree_add_item(flags_tree, hf_radiotap_flags_fcs,
-			tvb, offset, 1, FALSE);
-		proto_tree_add_item(flags_tree, hf_radiotap_flags_datapad,
-			tvb, offset, 1, FALSE);
-		proto_tree_add_item(flags_tree, hf_radiotap_flags_badfcs,
-			tvb, offset, 1, FALSE);
-		proto_tree_add_item(flags_tree, hf_radiotap_flags_shortgi,
-			tvb, offset, 1, FALSE);
-	    }
-	    offset++;
-	    length_remaining--;
-	    break;
-
-	case IEEE80211_RADIOTAP_RATE:
-	    if (length_remaining < 1)
-		break;
-	    rate = tvb_get_guint8(tvb, offset);
-	    if (rate & 0x80) {
-		/* XXX adjust by CW and short GI like other sniffers? */
-		rate = ieee80211_htrates[rate & 0xf];
-	    }
-	    col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%d.%d",
-		rate / 2, rate & 1 ? 5 : 0);
-	    if (tree) {
-		proto_tree_add_uint_format(radiotap_tree, hf_radiotap_datarate,
-			tvb, offset, 1, rate,
-			"Data Rate: %d.%d Mb/s", rate / 2, rate & 1 ? 5 : 0);
-	    }
-	    offset++;
-	    length_remaining--;
+    while (!(err = ieee80211_radiotap_iterator_next(&iter))) {
+        offset = (guchar *)iter.this_arg - (guchar *)data;
+
+        if (iter.this_arg_index == IEEE80211_RADIOTAP_VENDOR_NAMESPACE && tree) {
+            proto_tree *vt, *ven_tree = NULL;
+            vt = proto_tree_add_item(radiotap_tree, hf_radiotap_vendor_ns,
+                                     tvb, offset, iter.this_arg_size, FALSE);
+            ven_tree = proto_item_add_subtree(vt, ett_radiotap_vendor);
+            proto_tree_add_item(ven_tree, hf_radiotap_ven_oui, tvb, offset,
+                                3, FALSE);
+            proto_tree_add_item(ven_tree, hf_radiotap_ven_subns, tvb, offset + 3,
+                                1, FALSE);
+            proto_tree_add_item(ven_tree, hf_radiotap_ven_skip, tvb, offset + 4,
+                                2, TRUE);
+            proto_tree_add_item(ven_tree, hf_radiotap_ven_data, tvb, offset + 6,
+                                iter.this_arg_size - 6, TRUE);
+        }
+
+        if (!iter.is_radiotap_ns)
+            continue;
+
+        switch (iter.this_arg_index) {
+        case IEEE80211_RADIOTAP_FLAGS:
+            rflags = tvb_get_guint8(tvb, offset);
+            if (tree) {
+                ft = proto_tree_add_item(radiotap_tree, hf_radiotap_flags,
+                    tvb, offset, 1, FALSE);
+                flags_tree = proto_item_add_subtree(ft, ett_radiotap_flags);
+
+                proto_tree_add_item(flags_tree, hf_radiotap_flags_cfp,
+                    tvb, offset, 1, FALSE);
+                proto_tree_add_item(flags_tree, hf_radiotap_flags_preamble,
+                    tvb, offset, 1, FALSE);
+                proto_tree_add_item(flags_tree, hf_radiotap_flags_wep,
+                    tvb, offset, 1, FALSE);
+                proto_tree_add_item(flags_tree, hf_radiotap_flags_frag,
+                    tvb, offset, 1, FALSE);
+                proto_tree_add_item(flags_tree, hf_radiotap_flags_fcs,
+                    tvb, offset, 1, FALSE);
+                proto_tree_add_item(flags_tree, hf_radiotap_flags_datapad,
+                    tvb, offset, 1, FALSE);
+                proto_tree_add_item(flags_tree, hf_radiotap_flags_badfcs,
+                    tvb, offset, 1, FALSE);
+                proto_tree_add_item(flags_tree, hf_radiotap_flags_shortgi,
+                    tvb, offset, 1, FALSE);
+            }
+            break;
+        case IEEE80211_RADIOTAP_RATE:
+            rate = tvb_get_guint8(tvb, offset);
+            if (rate & 0x80) {
+                /* XXX adjust by CW and short GI like other sniffers? */
+                rate = ieee80211_htrates[rate & 0xf];
+            }
+            col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%d.%d",
+            rate / 2, rate & 1 ? 5 : 0);
+            if (tree) {
+                proto_tree_add_uint_format(radiotap_tree, hf_radiotap_datarate,
+                    tvb, offset, 1, rate,
+                    "Data Rate: %d.%d Mb/s", rate / 2, rate & 1 ? 5 : 0);
+            }
             radiotap_info->rate = rate;
-	    break;
-	case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
-	    if (length_remaining < 1)
-		break;
-	    dbm = (gint8) tvb_get_guint8(tvb, offset);
-	    col_add_fstr(pinfo->cinfo, COL_RSSI, "%d dBm", dbm);
-	    if (tree) {
-		proto_tree_add_int_format(radiotap_tree,
-					  hf_radiotap_dbm_antsignal,
-					  tvb, offset, 1, dbm,
-					  "SSI Signal: %d dBm", dbm);
-	    }
-	    offset++;
-	    length_remaining--;
+            break;
+        case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
+            dbm = (gint8) tvb_get_guint8(tvb, offset);
+            col_add_fstr(pinfo->cinfo, COL_RSSI, "%d dBm", dbm);
+            if (tree) {
+                proto_tree_add_int_format(radiotap_tree,
+                              hf_radiotap_dbm_antsignal,
+                              tvb, offset, 1, dbm,
+                              "SSI Signal: %d dBm", dbm);
+            }
             radiotap_info->dbm_antsignal=dbm;
-	    break;
-	case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
-	    if (length_remaining < 1)
-		break;
-	    db = tvb_get_guint8(tvb, offset);
-	    col_add_fstr(pinfo->cinfo, COL_RSSI, "%u dB", db);
-	    if (tree) {
-		proto_tree_add_uint_format(radiotap_tree,
-					   hf_radiotap_db_antsignal,
-					   tvb, offset, 1, db,
-					   "SSI Signal: %u dB", db);
-	    }
-	    offset++;
-	    length_remaining--;
-	    break;
-	case IEEE80211_RADIOTAP_DBM_ANTNOISE:
-	    if (length_remaining < 1)
-		break;
-	    dbm = (gint8) tvb_get_guint8(tvb, offset);
-	    if (tree) {
-		proto_tree_add_int_format(radiotap_tree,
-					  hf_radiotap_dbm_antnoise,
-					  tvb, offset, 1, dbm,
-					  "SSI Noise: %d dBm", dbm);
-	    }
-	    offset++;
-	    length_remaining--;
+            break;
+        case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
+            db = tvb_get_guint8(tvb, offset);
+            col_add_fstr(pinfo->cinfo, COL_RSSI, "%u dB", db);
+            if (tree) {
+                proto_tree_add_uint_format(radiotap_tree,
+                               hf_radiotap_db_antsignal,
+                               tvb, offset, 1, db,
+                               "SSI Signal: %u dB", db);
+            }
+            break;
+        case IEEE80211_RADIOTAP_DBM_ANTNOISE:
+            dbm = (gint8) tvb_get_guint8(tvb, offset);
+            if (tree) {
+                proto_tree_add_int_format(radiotap_tree,
+                              hf_radiotap_dbm_antnoise,
+                              tvb, offset, 1, dbm,
+                              "SSI Noise: %d dBm", dbm);
+            }
             radiotap_info->dbm_antnoise=dbm;
-	    break;
-	case IEEE80211_RADIOTAP_DB_ANTNOISE:
-	    if (length_remaining < 1)
-		break;
-	    db = tvb_get_guint8(tvb, offset);
-	    if (tree) {
-		proto_tree_add_uint_format(radiotap_tree,
-					   hf_radiotap_db_antnoise,
-					   tvb, offset, 1, db,
-					   "SSI Noise: %u dB", db);
-	    }
-	    offset++;
-	    length_remaining--;
-	    break;
-	case IEEE80211_RADIOTAP_ANTENNA:
-	    if (length_remaining < 1)
-		break;
-	    if (tree) {
-		proto_tree_add_uint(radiotap_tree, hf_radiotap_antenna,
-				   tvb, offset, 1, tvb_get_guint8(tvb, offset));
-	    }
-	    offset++;
-	    length_remaining--;
-	    break;
-	case IEEE80211_RADIOTAP_DBM_TX_POWER:
-	    if (length_remaining < 1)
-		break;
-	    if (tree) {
-		proto_tree_add_int(radiotap_tree, hf_radiotap_txpower,
-				   tvb, offset, 1, tvb_get_guint8(tvb, offset));
-	    }
-	    offset++;
-	    length_remaining--;
-	    break;
-	case IEEE80211_RADIOTAP_CHANNEL:
-	{
-	    proto_item *it;
-	    proto_tree *flags_tree;
-	    gchar *chan_str;
-
-	    align_offset = ALIGN_OFFSET(offset, 2);
-	    offset += align_offset;
-	    length_remaining -= align_offset;
-	    if (length_remaining < 2)
-		break;
-	    if (tree) {
-		freq = tvb_get_letohs(tvb, offset);
-		flags = tvb_get_letohs(tvb, offset+2);
-		chan_str = ieee80211_mhz_to_str(freq);
-		col_add_fstr(pinfo->cinfo, COL_FREQ_CHAN, "%s", chan_str);
-		proto_tree_add_uint_format(radiotap_tree, hf_radiotap_channel_frequency,
-				tvb, offset, 2, freq,
-				"Channel frequency: %s", chan_str);
-		g_free(chan_str);
-		/* We're already 2-byte aligned. */
-		it = proto_tree_add_uint(radiotap_tree, hf_radiotap_channel_flags,
-			tvb, offset+2, 2, flags);
-		flags_tree = proto_item_add_subtree(it, ett_radiotap_channel_flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_turbo,
-			tvb, offset+2, 1, flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_cck,
-			tvb, offset+2, 1, flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_ofdm,
-			tvb, offset+2, 1, flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_2ghz,
-			tvb, offset+2, 1, flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_5ghz,
-			tvb, offset+3, 1, flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_passive,
-			tvb, offset+3, 1, flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_dynamic,
-			tvb, offset+3, 1, flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_gfsk,
-			tvb, offset+3, 1, flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_gsm,
-			tvb, offset+3, 1, flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_sturbo,
-			tvb, offset+3, 1, flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_half,
-			tvb, offset+3, 1, flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_quarter,
-			tvb, offset+3, 1, flags);
-		radiotap_info->freq=freq;
-		radiotap_info->flags=flags;
-	    }
-	    offset+=4 /* Channel + flags */;
-	    length_remaining-=4;
-	    break;
-	}
-	case IEEE80211_RADIOTAP_XCHANNEL: {
-	    proto_item *it;
-	    proto_tree *flags_tree;
-
-	    align_offset = ALIGN_OFFSET(offset, 4);
-	    offset += align_offset;
-	    length_remaining -= align_offset;
-	    if (length_remaining < 8)
-		break;
-	    if (tree) {
-	        int channel;
-	        guint8 maxpower;
-
-		flags = tvb_get_letohl(tvb, offset);
-		freq = tvb_get_letohs(tvb, offset+4);
-		channel = tvb_get_guint8(tvb, offset+6);
-		maxpower = tvb_get_guint8(tvb, offset+7);
-		proto_tree_add_uint(radiotap_tree, hf_radiotap_xchannel,
-			tvb, offset+6, 1, (guint32) channel);
-		proto_tree_add_uint(radiotap_tree, hf_radiotap_xchannel_frequency,
-			tvb, offset+4, 2, freq);
-		it = proto_tree_add_uint(radiotap_tree, hf_radiotap_xchannel_flags,
-			tvb, offset+0, 4, flags);
-		flags_tree = proto_item_add_subtree(it, ett_radiotap_xchannel_flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_turbo,
-			tvb, offset+0, 1, flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_cck,
-			tvb, offset+0, 1, flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_ofdm,
-			tvb, offset+0, 1, flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_2ghz,
-			tvb, offset+0, 1, flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_5ghz,
-			tvb, offset+1, 1, flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_passive,
-			tvb, offset+1, 1, flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_dynamic,
-			tvb, offset+1, 1, flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_gfsk,
-			tvb, offset+1, 1, flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_gsm,
-			tvb, offset+1, 1, flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_sturbo,
-			tvb, offset+1, 1, flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_half,
-			tvb, offset+1, 1, flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_quarter,
-			tvb, offset+1, 1, flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_ht20,
-			tvb, offset+2, 1, flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_ht40u,
-			tvb, offset+2, 1, flags);
-		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_ht40d,
-			tvb, offset+2, 1, flags);
-#if 0
-		proto_tree_add_uint(radiotap_tree, hf_radiotap_xchannel_maxpower,
-			tvb, offset+7, 1, maxpower);
-#endif
-	    }
-	    offset+=8 /* flags + freq + ieee + maxregpower */;
-	    length_remaining-=8;
-	    break;
-	}
-	case IEEE80211_RADIOTAP_FHSS:
-	    align_offset = ALIGN_OFFSET(offset, 2);
-	    offset += align_offset;
-	    length_remaining -= align_offset;
-	    if (length_remaining < 2)
-		break;
-	    proto_tree_add_item(radiotap_tree, hf_radiotap_fhss_hopset,
-		tvb, offset, 1, FALSE);
-	    proto_tree_add_item(radiotap_tree, hf_radiotap_fhss_pattern,
-		tvb, offset, 1, FALSE);
-	    offset+=2;
-	    length_remaining-=2;
-	    break;
-	case IEEE80211_RADIOTAP_TX_ATTENUATION:
-	    align_offset = ALIGN_OFFSET(offset, 2);
-	    offset += align_offset;
-	    length_remaining -= align_offset;
-	    if (length_remaining < 2)
-		break;
-	    proto_tree_add_item(radiotap_tree, hf_radiotap_tx_attenuation,
-		tvb, offset, 2, FALSE);
-	    offset+=2;
-	    length_remaining-=2;
-	    break;
-	case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
-	    align_offset = ALIGN_OFFSET(offset, 2);
-	    offset += align_offset;
-	    length_remaining -= align_offset;
-	    if (length_remaining < 2)
-		break;
-	    proto_tree_add_item(radiotap_tree, hf_radiotap_db_tx_attenuation,
-		tvb, offset, 2, FALSE);
-	    offset+=2;
-	    length_remaining-=2;
-	    break;
-	case IEEE80211_RADIOTAP_TSFT:
-	    align_offset = ALIGN_OFFSET(offset, 8);
-	    offset += align_offset;
-	    length_remaining -= align_offset;
-	    if (length_remaining < 8)
-		break;
+            break;
+        case IEEE80211_RADIOTAP_DB_ANTNOISE:
+            db = tvb_get_guint8(tvb, offset);
+            if (tree) {
+                proto_tree_add_uint_format(radiotap_tree,
+                               hf_radiotap_db_antnoise,
+                               tvb, offset, 1, db,
+                               "SSI Noise: %u dB", db);
+            }
+            break;
+        case IEEE80211_RADIOTAP_ANTENNA:
+            if (tree) {
+                proto_tree_add_uint(radiotap_tree, hf_radiotap_antenna,
+                           tvb, offset, 1, tvb_get_guint8(tvb, offset));
+            }
+            break;
+        case IEEE80211_RADIOTAP_DBM_TX_POWER:
+            if (tree) {
+                proto_tree_add_int(radiotap_tree, hf_radiotap_txpower,
+                           tvb, offset, 1, tvb_get_guint8(tvb, offset));
+            }
+            break;
+        case IEEE80211_RADIOTAP_CHANNEL:
+        {
+            proto_item *it;
+            proto_tree *flags_tree;
+            gchar *chan_str;
+
+            if (tree) {
+                freq = tvb_get_letohs(tvb, offset);
+                flags = tvb_get_letohs(tvb, offset+2);
+                chan_str = ieee80211_mhz_to_str(freq);
+                col_add_fstr(pinfo->cinfo, COL_FREQ_CHAN, "%s", chan_str);
+                proto_tree_add_uint_format(radiotap_tree, hf_radiotap_channel_frequency,
+                        tvb, offset, 2, freq,
+                        "Channel frequency: %s", chan_str);
+                g_free(chan_str);
+                /* We're already 2-byte aligned. */
+                it = proto_tree_add_uint(radiotap_tree, hf_radiotap_channel_flags,
+                    tvb, offset+2, 2, flags);
+                flags_tree = proto_item_add_subtree(it, ett_radiotap_channel_flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_turbo,
+                    tvb, offset+2, 1, flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_cck,
+                    tvb, offset+2, 1, flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_ofdm,
+                    tvb, offset+2, 1, flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_2ghz,
+                    tvb, offset+2, 1, flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_5ghz,
+                    tvb, offset+3, 1, flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_passive,
+                    tvb, offset+3, 1, flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_dynamic,
+                    tvb, offset+3, 1, flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_gfsk,
+                    tvb, offset+3, 1, flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_gsm,
+                    tvb, offset+3, 1, flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_sturbo,
+                    tvb, offset+3, 1, flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_half,
+                    tvb, offset+3, 1, flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_quarter,
+                    tvb, offset+3, 1, flags);
+                radiotap_info->freq=freq;
+                radiotap_info->flags=flags;
+            }
+            break;
+        }
+        case IEEE80211_RADIOTAP_XCHANNEL: {
+            proto_item *it;
+            proto_tree *flags_tree;
+
+            if (tree) {
+                int channel;
+                guint8 maxpower;
+
+                flags = tvb_get_letohl(tvb, offset);
+                freq = tvb_get_letohs(tvb, offset+4);
+                channel = tvb_get_guint8(tvb, offset+6);
+                maxpower = tvb_get_guint8(tvb, offset+7);
+                proto_tree_add_uint(radiotap_tree, hf_radiotap_xchannel,
+                    tvb, offset+6, 1, (guint32) channel);
+                proto_tree_add_uint(radiotap_tree, hf_radiotap_xchannel_frequency,
+                    tvb, offset+4, 2, freq);
+                it = proto_tree_add_uint(radiotap_tree, hf_radiotap_xchannel_flags,
+                    tvb, offset+0, 4, flags);
+                flags_tree = proto_item_add_subtree(it, ett_radiotap_xchannel_flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_turbo,
+                    tvb, offset+0, 1, flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_cck,
+                    tvb, offset+0, 1, flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_ofdm,
+                    tvb, offset+0, 1, flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_2ghz,
+                    tvb, offset+0, 1, flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_5ghz,
+                    tvb, offset+1, 1, flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_passive,
+                    tvb, offset+1, 1, flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_dynamic,
+                    tvb, offset+1, 1, flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_gfsk,
+                    tvb, offset+1, 1, flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_gsm,
+                    tvb, offset+1, 1, flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_sturbo,
+                    tvb, offset+1, 1, flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_half,
+                    tvb, offset+1, 1, flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_quarter,
+                    tvb, offset+1, 1, flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_ht20,
+                    tvb, offset+2, 1, flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_ht40u,
+                    tvb, offset+2, 1, flags);
+                proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_ht40d,
+                    tvb, offset+2, 1, flags);
+            }
+            break;
+        }
+        case IEEE80211_RADIOTAP_FHSS:
+            proto_tree_add_item(radiotap_tree, hf_radiotap_fhss_hopset,
+                                tvb, offset, 1, FALSE);
+            proto_tree_add_item(radiotap_tree, hf_radiotap_fhss_pattern,
+                                tvb, offset, 1, FALSE);
+            break;
+        case IEEE80211_RADIOTAP_TX_ATTENUATION:
+            proto_tree_add_item(radiotap_tree, hf_radiotap_tx_attenuation,
+                                tvb, offset, 2, FALSE);
+            break;
+        case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
+            proto_tree_add_item(radiotap_tree, hf_radiotap_db_tx_attenuation,
+                                tvb, offset, 2, FALSE);
+            break;
+        case IEEE80211_RADIOTAP_TSFT:
             radiotap_info->tsft=tvb_get_letoh64(tvb, offset);
-	    if (tree) {
-		proto_tree_add_uint64(radiotap_tree, hf_radiotap_mactime,
-				tvb, offset, 8,radiotap_info->tsft );
-	    }
-	    offset+=8;
-	    length_remaining-=8;
-	    break;
-	case IEEE80211_RADIOTAP_LOCK_QUALITY:
-	    align_offset = ALIGN_OFFSET(offset, 2);
-	    offset += align_offset;
-	    length_remaining -= align_offset;
-	    if (length_remaining < 2)
-		break;
-	    if (tree) {
-		proto_tree_add_uint(radiotap_tree, hf_radiotap_quality,
-				tvb, offset, 2, tvb_get_letohs(tvb, offset));
-	    }
-	    offset+=2;
-	    length_remaining-=2;
-	    break;
-	case IEEE80211_RADIOTAP_RX_FLAGS:
-	    if (radiotap_bit14_fcs) {
-	        align_offset = ALIGN_OFFSET(offset, 4);
-	        offset += align_offset;
-	        length_remaining -= align_offset;
-	        if (length_remaining < 4)
-	            break;
+            if (tree) {
+                proto_tree_add_uint64(radiotap_tree, hf_radiotap_mactime,
+                        tvb, offset, 8,radiotap_info->tsft );
+            }
+            break;
+        case IEEE80211_RADIOTAP_LOCK_QUALITY:
+            if (tree) {
+                proto_tree_add_uint(radiotap_tree, hf_radiotap_quality,
+                        tvb, offset, 2, tvb_get_letohs(tvb, offset));
+            }
+            break;
+        case IEEE80211_RADIOTAP_RX_FLAGS:
+            if (radiotap_bit14_fcs) {
                 if (tree) {
-                    sent_fcs = tvb_get_ntohl(tvb, offset);
-                    hdr_fcs_ti = proto_tree_add_uint(radiotap_tree, hf_radiotap_fcs,
-                                                     tvb, offset, 4, sent_fcs);
-                    hdr_fcs_offset = offset;
+                        sent_fcs = tvb_get_ntohl(tvb, offset);
+                        hdr_fcs_ti = proto_tree_add_uint(radiotap_tree, hf_radiotap_fcs,
+                                                         tvb, offset, 4, sent_fcs);
+                        hdr_fcs_offset = offset;
                 }
-                offset+=4;
-                length_remaining-=4;
-	    } else {
-	        proto_item *it;
-
-                align_offset = ALIGN_OFFSET(offset, 2);
-                offset += align_offset;
-                length_remaining -= align_offset;
-                if (length_remaining < 2)
-                    break;
+            } else {
+                proto_item *it;
+
                 if (tree) {
-                    flags = tvb_get_letohs(tvb, offset);
-                    it = proto_tree_add_uint(radiotap_tree, hf_radiotap_rxflags,
-                            tvb, offset, 2, flags);
-                    flags_tree = proto_item_add_subtree(it, ett_radiotap_rxflags);
-                    proto_tree_add_boolean(flags_tree, hf_radiotap_rxflags_badplcp,
-                            tvb, offset, 1, flags);
+                        flags = tvb_get_letohs(tvb, offset);
+                        it = proto_tree_add_uint(radiotap_tree, hf_radiotap_rxflags,
+                                tvb, offset, 2, flags);
+                        flags_tree = proto_item_add_subtree(it, ett_radiotap_rxflags);
+                        proto_tree_add_boolean(flags_tree, hf_radiotap_rxflags_badplcp,
+                                tvb, offset, 1, flags);
                 }
-                offset+=2;
-                length_remaining-=2;
             }
-	    break;
-	default:
-	    /*
-	     * This indicates a field whose size we do not
-	     * know, so we cannot proceed.
-	     */
-	    next_present = 0;
-	    continue;
-	}
+            break;
+        }
     }
 
+    if (err != -ENOENT && tree)
+        proto_item_append_text(ti, " (malformed)");
+
     /* This handles the case of an FCS exiting at the end of the frame. */
     if (rflags & IEEE80211_RADIOTAP_F_FCS)
-	pinfo->pseudo_header->ieee_802_11.fcs_len = 4;
+        pinfo->pseudo_header->ieee_802_11.fcs_len = 4;
     else
-	pinfo->pseudo_header->ieee_802_11.fcs_len = 0;
+        pinfo->pseudo_header->ieee_802_11.fcs_len = 0;
 
+hand_off_to_80211:
     /* Grab the rest of the frame. */
     next_tvb = tvb_new_subset_remaining(tvb, length);
 
--- trunk.orig/epan/dissectors/Makefile.common	2009-11-26 18:50:51.000000000 +0100
+++ trunk/epan/dissectors/Makefile.common	2009-11-26 18:53:53.000000000 +0100
@@ -740,6 +740,7 @@ DISSECTOR_SRC = \
 	packet-radius.c		\
 	packet-radius_packetcable.c	\
 	packet-radiotap.c	\
+	packet-radiotap-iter.c	\
 	packet-raw.c		\
 	packet-rdm.c		\
 	packet-rdt.c		\
@@ -1168,6 +1169,8 @@ DISSECTOR_INCLUDES =	\
 	packet-q932.h	\
 	packet-qsig.h	\
 	packet-radiotap.h	\
+	packet-radiotap-iter.h	\
+	packet-radiotap-defs.h	\
 	packet-radius.h	\
 	packet-ranap.h	\
 	packet-raw.h	\
--- trunk.orig/epan/dissectors/Makefile.nmake	2009-11-26 18:50:51.000000000 +0100
+++ trunk/epan/dissectors/Makefile.nmake	2009-11-26 18:53:53.000000000 +0100
@@ -12,7 +12,7 @@ include Custom.nmake
 include Makefile.common
 
 CFLAGS=-WX -DHAVE_CONFIG_H /I. /I.. /I../.. $(GLIB_CFLAGS) \
-	$(ZLIB_CFLAGS) \
+	$(ZLIB_CFLAGS) -DRADIOTAP_SUPPORT_OVERRIDES \
 	$(PCRE_CFLAGS) $(GNUTLS_CFLAGS) $(NETTLE_CFLAGS) \
 	$(KFW_CFLAGS) $(AIRPCAP_CFLAGS) $(GEOIP_CFLAGS) \
 	/I$(PCAP_DIR)\include -D_U_="" $(LOCAL_CFLAGS)

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFA] namespaces and vendor extensions
       [not found] ` <1259258152.32372.90.camel-YfaajirXv2244ywRPIzf9A@public.gmane.org>
@ 2009-11-30 22:41   ` Joshua (Shiwei) Zhao
       [not found]     ` <d521a2310911301441l3c5503b5hf43d31a47e83fe4b-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 14+ messages in thread
From: Joshua (Shiwei) Zhao @ 2009-11-30 22:41 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Radiotap, Gerald Combs

Johannes,

I support to extend the current radiotap field definitions especailly
for vendor extension part. I hope Wireshark can soon adopt the idea of
vendor extension. I have comments on a few details in your proposal.

For the structure of the vendor space, you extend 'skip_length' from 8
bits to 16 bits.
> Structure
>        u8 OUI[3], u8 sub_namespace, __le16 skip_length
I'm neutral on that. My question is why not extend 'sub_namespace' to
16 bits too? I hardly see that a vendor extension part can go over 255
bytes. But if that happens, it's quite likely that the extension may
contain more than 8 fields.

Personally I'm not in favor of the proposed bit 29 "reset namespace".
But I'm ok with it if everyone else adopts it.

Thanks,
Joshua


On Thu, Nov 26, 2009 at 9:55 AM, Johannes Berg
<johannes-cdvu00un1VgdHxzADdlk8Q@public.gmane.org> wrote:
> [Gerald: I'm copying you directly because I have a question about this
> patch, please see at the end of the email]
>
> This is a request for adoption of the previously discussed namespace
> proposal from David.
>
> Namespaces in radiotap serve two different use cases:
>  1) vendor extensions and
>  2) multiple uses of a single radiotap field.
>
> Vendor extensions allows data from any number of different vendors to be
> present in a single radiotap header. Each vendor namespace contains
> present bits just like regular radiotap, but these bits are under the
> control of the vendor. To allow compliant parsers to read past vendor
> extensions, they also contain the data length.
>
> Resetting the radiotap namespace when extending the present bitmap
> serves to allow a radiotap field be specified multiple times. An example
> for that would be specifying multi-rate retries during injection or for
> TX status.
>
> In the current radiotap header, the IEEE80211_RADIOTAP_EXT bit (bit 31)
> is reserved in any it_present bitmap and indicates that the bitmap
> continues. This shall be true for bit 29 (reset radiotap namespace) and
> bit 30 (vendor namespace) as well.
>
> This proposal differs from David's original one by using different
> alignment and size for the vendor data specification, I have opted to
> use 16 bits for the vendor data length since some people want to put a
> lot of data like raw TX/RX hardware descriptors into vendor fields. I
> have also clarified the data length variable to specify the fact that
> when switching away from a vendor namespace to another vendor namespace,
> the vendor namespace data is not part of the vendor namespace data
> length ("If a radiotap header changes from a vendor namespace to another
> vendor namespace, the 6-byte data describing the new vendor namespace
> shall not be accounted for in skip_length.") The text describing that
> the two fields are mutually exclusive is also new.
>
> Correct, existing radiotap implementations are compatible with this
> proposal because they will stop parsing the radiotap header at bit 29/30
> since even though they do not know that these bits are reserved in all
> namespaces and it_present words they do know that they cannot understand
> these bits, regardless of which it_present they encounter them in,
> because they were not previously defined. [It seems to me that the
> existing wireshark implementation is not correct -- it doesn't properly
> skip over extended present bitmap words.]
>
> Note that before this proposal the bits 63, 95, (31+n*32) were reserved
> due to overlaying the extension bit, this proposal also reserves the
> bits 29+n*32 and 30+n*32 in all namespaces due to overlapping with the
> namespace changes bits.
>
> The normative text of this proposal follows (minus formatting):
>
> --- begin normative text ---
> Vendor Namespace
> Bit Number
>        not applicable, bit 30 in every it_present word
> Structure
>        u8 OUI[3], u8 sub_namespace, __le16 skip_length
> Required Alignment
>        2
>
> This field is reserved in all namespaces and every it_present word, the
> standard radiotap namespace as well as all vendor namespaces. It is
> mutually exclusive with the "Reset to Radiotap Namespace" field, setting
> both is undefined.
>
> The Vendor Namespace Field contains three sub-fields. The first
> sub-field is 3 bytes long. It contains the vendor's IEEE 802
> Organizationally Unique Identifier (OUI). The fourth byte is a
> vendor-specific "namespace selector."
>
> Before it resumes interpretation of presence bits in the following
> 32-bit presence words, if any, the interpreter shall reset its
> presence-bitmap index to 0, and change to the vendor namespace specified
> by the OUI and selector.
>
> The fifth and sixth bytes, skip_length, comprise a 16 bit little-endian
> value that tells the interpreter how many bytes of data after the end of
> the Vendor Namespace Field can only be interpreted according to the
> vendor namespace. If a radiotap header changes to a namespace that the
> interpreter does not understand, and back, the interpreter may resume
> interpretation in the new namespace by skipping skip_length data bytes
> after the end of the Vendor Namespace Field. If a radiotap header
> changes from a vendor namespace to another vendor namespace, the 6-byte
> data describing the new vendor namespace shall not be accounted for in
> skip_length.
>
> Reset to Radiotap Namespace
> Bit Number
>        not applicable, bit 29 in every it_present word
> Structure
>        no contents
> Required Alignment
>        N/A
>
> This field is reserved in all namespaces and every it_present word, the
> standard radiotap namespace as well as all vendor namespaces. It is
> mutually exclusive with the "Vendor Namespace" field, setting both is
> undefined.
>
> Upon interpreting this field, the interpreter shall reset its
> presence-bitmap index to 0 and its namespace to the default radiotap
> namespace, and change to the default radiotap namespace, before it
> interprets subsequent presence-bitmap words.
>
>
> --- end normative text ---
>
> I have implemented this proposal in Andy Green's and my stand-alone
> radiotap parser library available on
> http://git.sipsolutions.net/radiotap.git/
> (git clone http://git.sipsolutions.net/radiotap.git/ to get it, the web
> interface can also generate tarballs).
>
> I have additionally implemented this proposal in wireshark, without any
> vendor extension parsing, by making wireshark use a copy of the above
> library.
>
> Gerald: Here's where I have a question -- is that acceptable to you? The
> files are licensed properly, but it does require pulling the entire
> radiotap header into memory with ep_tvb_memdup(). Are you ok with that?
> Everything else would be rather complicated, requiring a complete
> re-implementation of the parser which doesn't seem all that helpful.
>
> johannes
>
>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFA] namespaces and vendor extensions
       [not found]     ` <d521a2310911301441l3c5503b5hf43d31a47e83fe4b-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2009-12-01  9:16       ` Johannes Berg
       [not found]         ` <1259659011.32171.45.camel-YfaajirXv2244ywRPIzf9A@public.gmane.org>
  0 siblings, 1 reply; 14+ messages in thread
From: Johannes Berg @ 2009-12-01  9:16 UTC (permalink / raw)
  To: Joshua (Shiwei) Zhao; +Cc: Radiotap, Gerald Combs

[-- Attachment #1: Type: text/plain, Size: 835 bytes --]

Joshua,

> For the structure of the vendor space, you extend 'skip_length' from 8
> bits to 16 bits.
> > Structure
> >        u8 OUI[3], u8 sub_namespace, __le16 skip_length
> I'm neutral on that. My question is why not extend 'sub_namespace' to
> 16 bits too? 

I don't see much point in having more than 255 sub-namespaces per OUI,
do you?

> I hardly see that a vendor extension part can go over 255
> bytes. But if that happens, it's quite likely that the extension may
> contain more than 8 fields.

Where are you taking 8 fields from? After the vendor extensions bit, the
vendor extension puts vendor-defined presence bits into the it_present
bitmap. Therefore, you have an unlimited number of fields per vendor
sub-namespace, as such I see little reason to support more than 255
sub-namespaces.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFA] namespaces and vendor extensions
       [not found]         ` <1259659011.32171.45.camel-YfaajirXv2244ywRPIzf9A@public.gmane.org>
@ 2009-12-01 16:32           ` Joshua (Shiwei) Zhao
  2009-12-01 16:43           ` Luis R. Rodriguez
  2009-12-01 17:05           ` Gerald Combs
  2 siblings, 0 replies; 14+ messages in thread
From: Joshua (Shiwei) Zhao @ 2009-12-01 16:32 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Radiotap, Gerald Combs

Sorry, Johannes, you're right. I was kinda lost :(

Joshua

On Tue, Dec 1, 2009 at 1:16 AM, Johannes Berg <johannes-cdvu00un1VgdHxzADdlk8Q@public.gmane.org> wrote:
> Joshua,
>
>> For the structure of the vendor space, you extend 'skip_length' from 8
>> bits to 16 bits.
>> > Structure
>> >        u8 OUI[3], u8 sub_namespace, __le16 skip_length
>> I'm neutral on that. My question is why not extend 'sub_namespace' to
>> 16 bits too?
>
> I don't see much point in having more than 255 sub-namespaces per OUI,
> do you?
>
>> I hardly see that a vendor extension part can go over 255
>> bytes. But if that happens, it's quite likely that the extension may
>> contain more than 8 fields.
>
> Where are you taking 8 fields from? After the vendor extensions bit, the
> vendor extension puts vendor-defined presence bits into the it_present
> bitmap. Therefore, you have an unlimited number of fields per vendor
> sub-namespace, as such I see little reason to support more than 255
> sub-namespaces.
>
> johannes
>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFA] namespaces and vendor extensions
       [not found]         ` <1259659011.32171.45.camel-YfaajirXv2244ywRPIzf9A@public.gmane.org>
  2009-12-01 16:32           ` Joshua (Shiwei) Zhao
@ 2009-12-01 16:43           ` Luis R. Rodriguez
       [not found]             ` <43e72e890912010843y208201aawb2ad95cbec98c814-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  2009-12-01 17:05           ` Gerald Combs
  2 siblings, 1 reply; 14+ messages in thread
From: Luis R. Rodriguez @ 2009-12-01 16:43 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Joshua (Shiwei) Zhao, Radiotap, Gerald Combs

On Tue, Dec 1, 2009 at 1:16 AM, Johannes Berg <johannes-cdvu00un1VgdHxzADdlk8Q@public.gmane.org> wrote:
> Joshua,
>
>> For the structure of the vendor space, you extend 'skip_length' from 8
>> bits to 16 bits.
>> > Structure
>> >        u8 OUI[3], u8 sub_namespace, __le16 skip_length
>> I'm neutral on that. My question is why not extend 'sub_namespace' to
>> 16 bits too?
>
> I don't see much point in having more than 255 sub-namespaces per OUI,
> do you?
>
>> I hardly see that a vendor extension part can go over 255
>> bytes. But if that happens, it's quite likely that the extension may
>> contain more than 8 fields.
>
> Where are you taking 8 fields from? After the vendor extensions bit, the
> vendor extension puts vendor-defined presence bits into the it_present
> bitmap. Therefore, you have an unlimited number of fields per vendor
> sub-namespace, as such I see little reason to support more than 255
> sub-namespaces.

Wanted to clarify, on the vendor it_present bitmap, does it always
have to also respect the bit for vendor extension bit 30? The current
proposal seems to have language which would indicates so:

"This field is reserved in all namespaces and every it_present word,
the standard radiotap namespace as well as all vendor namespaces. "

If so what is the point of the reset bit? What I mean is that if we
give radiotap its own OUI technically we could just reset ourselves to
the radiotap namespace by specifying the radiotap OUI with what I'd
think would be optional radiotap subnamespace material (length could
be 0 I take it).

  Luis

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFA] namespaces and vendor extensions
       [not found]             ` <43e72e890912010843y208201aawb2ad95cbec98c814-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2009-12-01 17:03               ` Johannes Berg
       [not found]                 ` <1259687018.32171.96.camel-YfaajirXv2244ywRPIzf9A@public.gmane.org>
  0 siblings, 1 reply; 14+ messages in thread
From: Johannes Berg @ 2009-12-01 17:03 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: Joshua (Shiwei) Zhao, Radiotap, Gerald Combs

[-- Attachment #1: Type: text/plain, Size: 1146 bytes --]

On Tue, 2009-12-01 at 08:43 -0800, Luis R. Rodriguez wrote:

> Wanted to clarify, on the vendor it_present bitmap, does it always
> have to also respect the bit for vendor extension bit 30? The current
> proposal seems to have language which would indicates so:
> 
> "This field is reserved in all namespaces and every it_present word,
> the standard radiotap namespace as well as all vendor namespaces. "

Yes, we have already reserved bit 31 in all it_present words, and now we
also reserve bits 29 and 30, so that vendor extensions can only use
numbers 0-28, 32-60, 64-92, ...

> If so what is the point of the reset bit? What I mean is that if we
> give radiotap its own OUI technically we could just reset ourselves to
> the radiotap namespace by specifying the radiotap OUI with what I'd
> think would be optional radiotap subnamespace material (length could
> be 0 I take it).

Well I personally would rather reserve a bit than try to come up with a
radiotap OUI (how would it get that?) and then special-casing the length
field etc. That just means _more_ special cases in the parser, rather
than less.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFA] namespaces and vendor extensions
       [not found]         ` <1259659011.32171.45.camel-YfaajirXv2244ywRPIzf9A@public.gmane.org>
  2009-12-01 16:32           ` Joshua (Shiwei) Zhao
  2009-12-01 16:43           ` Luis R. Rodriguez
@ 2009-12-01 17:05           ` Gerald Combs
       [not found]             ` <4B154CD4.8020700-IZ8446WsY0/dtAWm4Da02A@public.gmane.org>
  2 siblings, 1 reply; 14+ messages in thread
From: Gerald Combs @ 2009-12-01 17:05 UTC (permalink / raw)
  To: radiotap-sUITvd46vNxg9hUCZPvPmw

Johannes Berg wrote:
> Joshua,
> 
>> For the structure of the vendor space, you extend 'skip_length' from 8
>> bits to 16 bits.
>>> Structure
>>>        u8 OUI[3], u8 sub_namespace, __le16 skip_length

What happens if someone without an OUI wants to add a vendor extension?
Do they need to purchase an OUI or IAB from the IEEE?

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFA] namespaces and vendor extensions
       [not found]                 ` <1259687018.32171.96.camel-YfaajirXv2244ywRPIzf9A@public.gmane.org>
@ 2009-12-01 17:31                   ` David Young
  2009-12-01 17:46                   ` Luis R. Rodriguez
  1 sibling, 0 replies; 14+ messages in thread
From: David Young @ 2009-12-01 17:31 UTC (permalink / raw)
  To: Radiotap

On Tue, Dec 01, 2009 at 06:03:38PM +0100, Johannes Berg wrote:
> On Tue, 2009-12-01 at 08:43 -0800, Luis R. Rodriguez wrote:
> > If so what is the point of the reset bit? What I mean is that if we
> > give radiotap its own OUI technically we could just reset ourselves to
> > the radiotap namespace by specifying the radiotap OUI with what I'd
> > think would be optional radiotap subnamespace material (length could
> > be 0 I take it).
> 
> Well I personally would rather reserve a bit than try to come up with a
> radiotap OUI (how would it get that?) and then special-casing the length
> field etc. That just means _more_ special cases in the parser, rather
> than less.

I'm not keen on adding a special case to the length field, either.
Implementing the namespace-reset bit is simple.

I foresee using namespace reset a lot in the same header [1].  Using a
vendor extension field of 5-plus bytes each time, instead, will use a
lot of bytes fast!

I think that getting an OUI for Radiotap would be expensive.

Dave

[1] I'm thinking of using namespace-reset in re-transmission histories/strategies.

-- 
David Young             OJC Technologies
dyoung-eZodSLrBbDpBDgjK7y7TUQ@public.gmane.org      Urbana, IL * (217) 278-3933

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFA] namespaces and vendor extensions
       [not found]                 ` <1259687018.32171.96.camel-YfaajirXv2244ywRPIzf9A@public.gmane.org>
  2009-12-01 17:31                   ` David Young
@ 2009-12-01 17:46                   ` Luis R. Rodriguez
  1 sibling, 0 replies; 14+ messages in thread
From: Luis R. Rodriguez @ 2009-12-01 17:46 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Joshua (Shiwei) Zhao, Radiotap, Gerald Combs

On Tue, Dec 1, 2009 at 9:03 AM, Johannes Berg <johannes-cdvu00un1VgdHxzADdlk8Q@public.gmane.org> wrote:
> On Tue, 2009-12-01 at 08:43 -0800, Luis R. Rodriguez wrote:
>
>> Wanted to clarify, on the vendor it_present bitmap, does it always
>> have to also respect the bit for vendor extension bit 30? The current
>> proposal seems to have language which would indicates so:
>>
>> "This field is reserved in all namespaces and every it_present word,
>> the standard radiotap namespace as well as all vendor namespaces. "
>
> Yes, we have already reserved bit 31 in all it_present words, and now we
> also reserve bits 29 and 30, so that vendor extensions can only use
> numbers 0-28, 32-60, 64-92, ...

OK thanks.

>> If so what is the point of the reset bit? What I mean is that if we
>> give radiotap its own OUI technically we could just reset ourselves to
>> the radiotap namespace by specifying the radiotap OUI with what I'd
>> think would be optional radiotap subnamespace material (length could
>> be 0 I take it).
>
> Well I personally would rather reserve a bit than try to come up with a
> radiotap OUI (how would it get that?)

We don't have to buy an OUI. We could use a locally administered OUI,
which you had pointed out a while back when were looking for a private
OUI for some other purpose, I forget what it was.

> and then special-casing the length field etc.

Well I'm not saying you would *have* to force the length of the
subnamespace stuff to be 0, you could technically still use it and
stuff new it_present stuff with additional subnamespace radiotap
stuff. With the current reset proposal if you wanted to switch from
one private namespace to another you'd use two words, one to indicate
the reset which will throw you back to the radiotap namespace and then
a vendor extension bit on the second word to indicate a vendor
extension on a new namespace.

I actually would not even bother using the it_present bitmap for my
own private namespace, instead I'd just use the whole subnamespace to
stuff whatever random crap I want. I also believe inserting plugins to
interpret private namespaces then becomes easier to add to the code.

>That just means _more_ special cases in the parser, rather
> than less.

I'm thinking of ways in which the radtiotap code which appends new
radiotap information can easily be added for vendor extensions, which
is what I really only care about right now. For Atheros vendor
namespace for example it would seem easier to just use the vendor
extension bit to indicate the atheros subnamespace will have content,
then just stuff all our data there. For mac80211 this would mean just
adding a possible driver->extend_radiotap() or something like this.
You could certainly pass along the it_present bitmap[s] for the vendor
too but it seems easier to me if that would not have to be passed at
all or kept record of.

  Luis

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFA] namespaces and vendor extensions
       [not found]             ` <4B154CD4.8020700-IZ8446WsY0/dtAWm4Da02A@public.gmane.org>
@ 2009-12-01 21:37               ` Luis R. Rodriguez
       [not found]                 ` <43e72e890912011337l704c68ebscea8fd23160f7a8b-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  2009-12-01 23:08               ` Johannes Berg
  1 sibling, 1 reply; 14+ messages in thread
From: Luis R. Rodriguez @ 2009-12-01 21:37 UTC (permalink / raw)
  To: Gerald Combs; +Cc: radiotap-sUITvd46vNxg9hUCZPvPmw

On Tue, Dec 1, 2009 at 9:05 AM, Gerald Combs <gerald-IZ8446WsY0/dtAWm4Da02A@public.gmane.org> wrote:
> Johannes Berg wrote:
>> Joshua,
>>
>>> For the structure of the vendor space, you extend 'skip_length' from 8
>>> bits to 16 bits.
>>>> Structure
>>>>        u8 OUI[3], u8 sub_namespace, __le16 skip_length
>
> What happens if someone without an OUI wants to add a vendor extension?
> Do they need to purchase an OUI or IAB from the IEEE?

No, you can use a locally administered OUI, there is a bit on the OUI
you can use to mark this.

  Luis

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFA] namespaces and vendor extensions
       [not found]             ` <4B154CD4.8020700-IZ8446WsY0/dtAWm4Da02A@public.gmane.org>
  2009-12-01 21:37               ` Luis R. Rodriguez
@ 2009-12-01 23:08               ` Johannes Berg
       [not found]                 ` <1259708896.32171.132.camel-YfaajirXv2244ywRPIzf9A@public.gmane.org>
  1 sibling, 1 reply; 14+ messages in thread
From: Johannes Berg @ 2009-12-01 23:08 UTC (permalink / raw)
  To: Gerald Combs; +Cc: radiotap-sUITvd46vNxg9hUCZPvPmw

[-- Attachment #1: Type: text/plain, Size: 1355 bytes --]

On Tue, 2009-12-01 at 09:05 -0800, Gerald Combs wrote:
> Johannes Berg wrote:
> > Joshua,
> > 
> >> For the structure of the vendor space, you extend 'skip_length' from 8
> >> bits to 16 bits.
> >>> Structure
> >>>        u8 OUI[3], u8 sub_namespace, __le16 skip_length
> 
> What happens if someone without an OUI wants to add a vendor extension?
> Do they need to purchase an OUI or IAB from the IEEE?

IABs won't work, because we only have 24 bits reserved in this proposal.

However, is there a good reason for anyone to be wanting this, apart
from hardware-specific (and thus probably being affiliated with a
vendor) information? Shouldn't almost everything else be standardised
within the regular radiotap namespace? We do have a use case on Linux,
but we also have vendor backing so we'll be using a sub-namespace for
that specific use case (and maintenance within that namespace is easy by
controlling what patches go into the source tree).

I have no interest in helping maintain a second namespace in addition to
the radiotap bit namespace, and since we do allow sub-typing, being able
to use a subtype of somebody's OUI should be possible for virtually
anyone. If somebody ends up being completely lost without one, there are
probably enough people on this list willing to assign a sub-namespace to
them.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFA] namespaces and vendor extensions
       [not found]                 ` <43e72e890912011337l704c68ebscea8fd23160f7a8b-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2009-12-01 23:11                   ` Johannes Berg
  0 siblings, 0 replies; 14+ messages in thread
From: Johannes Berg @ 2009-12-01 23:11 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: Gerald Combs, radiotap-sUITvd46vNxg9hUCZPvPmw

[-- Attachment #1: Type: text/plain, Size: 867 bytes --]

On Tue, 2009-12-01 at 13:37 -0800, Luis R. Rodriguez wrote:
> On Tue, Dec 1, 2009 at 9:05 AM, Gerald Combs <gerald-IZ8446WsY0/dtAWm4Da02A@public.gmane.org> wrote:
> > Johannes Berg wrote:
> >> Joshua,
> >>
> >>> For the structure of the vendor space, you extend 'skip_length' from 8
> >>> bits to 16 bits.
> >>>> Structure
> >>>>        u8 OUI[3], u8 sub_namespace, __le16 skip_length
> >
> > What happens if someone without an OUI wants to add a vendor extension?
> > Do they need to purchase an OUI or IAB from the IEEE?
> 
> No, you can use a locally administered OUI, there is a bit on the OUI
> you can use to mark this.

As we've discussed, I don't think this is true. The EUI-48 (or only MAC
address?) has such a bit along with the group bit, but it is not
inconceivable that OUIs could be assigned in that range for other uses.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFA] namespaces and vendor extensions
       [not found]                 ` <1259708896.32171.132.camel-YfaajirXv2244ywRPIzf9A@public.gmane.org>
@ 2010-01-06 17:22                   ` Johannes Berg
       [not found]                     ` <1262798525.30225.15.camel-YfaajirXv2244ywRPIzf9A@public.gmane.org>
  0 siblings, 1 reply; 14+ messages in thread
From: Johannes Berg @ 2010-01-06 17:22 UTC (permalink / raw)
  To: Johannes Berg; +Cc: Gerald Combs, radiotap-sUITvd46vNxg9hUCZPvPmw

[-- Attachment #1: Type: text/plain, Size: 165 bytes --]

Gerald,

Did this clear up the issue you raised? If so, I think we can go ahead
and adopt this proposal, or are there any other objections?

Thanks,
Johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFA] namespaces and vendor extensions
       [not found]                     ` <1262798525.30225.15.camel-YfaajirXv2244ywRPIzf9A@public.gmane.org>
@ 2010-01-09  0:18                       ` Gerald Combs
  0 siblings, 0 replies; 14+ messages in thread
From: Gerald Combs @ 2010-01-09  0:18 UTC (permalink / raw)
  To: Johannes Berg; +Cc: radiotap-sUITvd46vNxg9hUCZPvPmw

Johannes Berg wrote:
> Gerald,
> 
> Did this clear up the issue you raised? If so, I think we can go ahead
> and adopt this proposal, or are there any other objections?

No objections here.

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2010-01-09  0:18 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-11-26 17:55 [RFA] namespaces and vendor extensions Johannes Berg
     [not found] ` <1259258152.32372.90.camel-YfaajirXv2244ywRPIzf9A@public.gmane.org>
2009-11-30 22:41   ` Joshua (Shiwei) Zhao
     [not found]     ` <d521a2310911301441l3c5503b5hf43d31a47e83fe4b-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2009-12-01  9:16       ` Johannes Berg
     [not found]         ` <1259659011.32171.45.camel-YfaajirXv2244ywRPIzf9A@public.gmane.org>
2009-12-01 16:32           ` Joshua (Shiwei) Zhao
2009-12-01 16:43           ` Luis R. Rodriguez
     [not found]             ` <43e72e890912010843y208201aawb2ad95cbec98c814-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2009-12-01 17:03               ` Johannes Berg
     [not found]                 ` <1259687018.32171.96.camel-YfaajirXv2244ywRPIzf9A@public.gmane.org>
2009-12-01 17:31                   ` David Young
2009-12-01 17:46                   ` Luis R. Rodriguez
2009-12-01 17:05           ` Gerald Combs
     [not found]             ` <4B154CD4.8020700-IZ8446WsY0/dtAWm4Da02A@public.gmane.org>
2009-12-01 21:37               ` Luis R. Rodriguez
     [not found]                 ` <43e72e890912011337l704c68ebscea8fd23160f7a8b-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2009-12-01 23:11                   ` Johannes Berg
2009-12-01 23:08               ` Johannes Berg
     [not found]                 ` <1259708896.32171.132.camel-YfaajirXv2244ywRPIzf9A@public.gmane.org>
2010-01-06 17:22                   ` Johannes Berg
     [not found]                     ` <1262798525.30225.15.camel-YfaajirXv2244ywRPIzf9A@public.gmane.org>
2010-01-09  0:18                       ` Gerald Combs

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).