]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Shuffle some stuff around a bit.
authorGuy Harris <[email protected]>
Mon, 28 Sep 2015 23:01:16 +0000 (16:01 -0700)
committerGuy Harris <[email protected]>
Mon, 28 Sep 2015 23:01:16 +0000 (16:01 -0700)
There were two places with radiotap stuff; move them together.

print-802_11.c

index 2aa05526a8ac8286557f20185cd903dfbd51775a..4014746a88b6f8d9762857283826ed00dc8aac90 100644 (file)
@@ -397,310 +397,6 @@ struct meshcntl_t {
 #define        IV_PAD(iv)      (((iv) >> 24) & 0x3F)
 #define        IV_KEYID(iv)    (((iv) >> 30) & 0x03)
 
-/* $FreeBSD: src/sys/net80211/ieee80211_radiotap.h,v 1.5 2005/01/22 20:12:05 sam Exp $ */
-/* NetBSD: ieee802_11_radio.h,v 1.2 2006/02/26 03:04:03 dyoung Exp  */
-
-/*-
- * 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.
- */
-
-/* A generic radio capture format is desirable. It must be
- * rigidly defined (e.g., units for fields should be given),
- * and easily extensible.
- *
- * The following is an 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.
- *
- * Note well: all radiotap fields are little-endian.
- */
-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              uint64_t       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).
- *     Note that IEEE80211_RADIOTAP_XCHANNEL must be used to
- *     represent an HT channel as there is not enough room in
- *     the flags word.
- *
- * IEEE80211_RADIOTAP_FHSS              uint16_t       see below
- *
- *      For frequency-hopping radios, the hop set (first byte)
- *      and pattern (second byte).
- *
- * IEEE80211_RADIOTAP_RATE              uint8_t        500kb/s or index
- *
- *      Tx/Rx data rate.  If bit 0x80 is set then it represents an
- *     an MCS index and not an IEEE rate.
- *
- * IEEE80211_RADIOTAP_DBM_ANTSIGNAL     int8_t          decibels from
- *                                                      one milliwatt (dBm)
- *
- *      RF signal power at the antenna, decibel difference from
- *      one milliwatt.
- *
- * IEEE80211_RADIOTAP_DBM_ANTNOISE      int8_t          decibels from
- *                                                      one milliwatt (dBm)
- *
- *      RF noise power at the antenna, decibel difference from one
- *      milliwatt.
- *
- * IEEE80211_RADIOTAP_DB_ANTSIGNAL      uint8_t        decibel (dB)
- *
- *      RF signal power at the antenna, decibel difference from an
- *      arbitrary, fixed reference.
- *
- * IEEE80211_RADIOTAP_DB_ANTNOISE       uint8_t        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      int8_t          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             uint8_t        bitmap
- *
- *      Properties of transmitted and received frames. See flags
- *      defined below.
- *
- * IEEE80211_RADIOTAP_ANTENNA           uint8_t        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_XCHANNEL          uint32_t       bitmap
- *                                     uint16_t        MHz
- *                                     uint8_t         channel number
- *                                     uint8_t         .5 dBm
- *
- *     Extended channel specification: flags (see below) followed by
- *     frequency in MHz, the corresponding IEEE channel number, and
- *     finally the maximum regulatory transmit power cap in .5 dBm
- *     units.  This property supersedes IEEE80211_RADIOTAP_CHANNEL
- *     and only one of the two should be present.
- *
- * IEEE80211_RADIOTAP_MCS              uint8_t         known
- *                                     uint8_t         flags
- *                                     uint8_t         mcs
- *
- *     Bitset indicating which fields have known values, followed
- *     by bitset of flag values, followed by the MCS rate index as
- *     in IEEE 802.11n.
- *
- * IEEE80211_RADIOTAP_VENDOR_NAMESPACE
- *                                     uint8_t  OUI[3]
- *                                   uint8_t  subspace
- *                                   uint16_t length
- *
- *     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."
- *
- */
-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,
-       /* NB: gap for netbsd definitions */
-       IEEE80211_RADIOTAP_XCHANNEL = 18,
-       IEEE80211_RADIOTAP_MCS = 19,
-       IEEE80211_RADIOTAP_NAMESPACE = 29,
-       IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30,
-       IEEE80211_RADIOTAP_EXT = 31
-};
-
-/* channel attributes */
-#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, borrowed from Ethereal */
-#define IEEE80211_CHAN_A \
-        (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
-#define IEEE80211_CHAN_B \
-        (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
-#define IEEE80211_CHAN_G \
-        (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
-#define IEEE80211_CHAN_TA \
-        (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO)
-#define IEEE80211_CHAN_TG \
-        (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN  | 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 */
-
-/* For IEEE80211_RADIOTAP_RX_FLAGS */
-#define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001  /* frame failed crc check */
-#define IEEE80211_RADIOTAP_F_RX_PLCP_CRC       0x0002  /* frame failed PLCP CRC check */
-
-/* For IEEE80211_RADIOTAP_MCS known */
-#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN         0x01
-#define IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN         0x02    /* MCS index field */
-#define IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN    0x04
-#define IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN         0x08
-#define IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN          0x10
-#define IEEE80211_RADIOTAP_MCS_STBC_KNOWN              0x20
-
-/* For IEEE80211_RADIOTAP_MCS flags */
-#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK  0x03
-#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20    0
-#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_40    1
-#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20L   2
-#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20U   3
-#define IEEE80211_RADIOTAP_MCS_SHORT_GI                0x04 /* short guard interval */
-#define IEEE80211_RADIOTAP_MCS_HT_GREENFIELD   0x08
-#define IEEE80211_RADIOTAP_MCS_FEC_LDPC                0x10
-#define IEEE80211_RADIOTAP_MCS_STBC_MASK       0x60
-#define                IEEE80211_RADIOTAP_MCS_STBC_1   1
-#define                IEEE80211_RADIOTAP_MCS_STBC_2   2
-#define                IEEE80211_RADIOTAP_MCS_STBC_3   3
-#define IEEE80211_RADIOTAP_MCS_STBC_SHIFT      5
-
-static const char tstr[] = "[|802.11]";
-
-/* Radiotap state */
-/*  This is used to save state when parsing/processing parameters */
-struct radiotap_state
-{
-       uint32_t        present;
-
-       uint8_t         rate;
-};
-
 #define PRINT_SSID(p) \
        if (p.ssid_present) { \
                ND_PRINT((ndo, " (")); \
@@ -2332,6 +2028,8 @@ ieee_802_11_hdr_print(netdissect_options *ndo,
 #define        roundup2(x, y)  (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
 #endif
 
+static const char tstr[] = "[|802.11]";
+
 static u_int
 ieee802_11_print(netdissect_options *ndo,
                  const u_char *p, u_int length, u_int orig_caplen, int pad,
@@ -2356,100 +2054,403 @@ ieee802_11_print(netdissect_options *ndo,
                ndo->ndo_snapend -= fcslen;
        }
 
-       if (caplen < IEEE802_11_FC_LEN) {
-               ND_PRINT((ndo, "%s", tstr));
-               return orig_caplen;
-       }
+       if (caplen < IEEE802_11_FC_LEN) {
+               ND_PRINT((ndo, "%s", tstr));
+               return orig_caplen;
+       }
+
+       fc = EXTRACT_LE_16BITS(p);
+       hdrlen = extract_header_length(ndo, fc);
+       if (hdrlen == 0) {
+               /* Unknown frame type or control frame subtype; quit. */
+               return (0);
+       }
+       if (pad)
+               hdrlen = roundup2(hdrlen, 4);
+       if (ndo->ndo_Hflag && FC_TYPE(fc) == T_DATA &&
+           DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) {
+               meshdrlen = extract_mesh_header_length(p+hdrlen);
+               hdrlen += meshdrlen;
+       } else
+               meshdrlen = 0;
+
+       if (caplen < hdrlen) {
+               ND_PRINT((ndo, "%s", tstr));
+               return hdrlen;
+       }
+
+       if (ndo->ndo_eflag)
+               ieee_802_11_hdr_print(ndo, fc, p, hdrlen, meshdrlen);
+
+       /*
+        * Go past the 802.11 header.
+        */
+       length -= hdrlen;
+       caplen -= hdrlen;
+       p += hdrlen;
+
+       switch (FC_TYPE(fc)) {
+       case T_MGMT:
+               get_mgmt_src_dst_mac(p - hdrlen, &src, &dst);
+               if (!mgmt_body_print(ndo, fc, src, p, length)) {
+                       ND_PRINT((ndo, "%s", tstr));
+                       return hdrlen;
+               }
+               break;
+       case T_CTRL:
+               if (!ctrl_body_print(ndo, fc, p - hdrlen)) {
+                       ND_PRINT((ndo, "%s", tstr));
+                       return hdrlen;
+               }
+               break;
+       case T_DATA:
+               if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc)))
+                       return hdrlen;  /* no-data frame */
+               /* There may be a problem w/ AP not having this bit set */
+               if (FC_PROTECTED(fc)) {
+                       ND_PRINT((ndo, "Data"));
+                       if (!wep_print(ndo, p)) {
+                               ND_PRINT((ndo, "%s", tstr));
+                               return hdrlen;
+                       }
+               } else {
+                       get_data_src_dst_mac(fc, p - hdrlen, &src, &dst);
+                       llc_hdrlen = llc_print(ndo, p, length, caplen, src, dst);
+                       if (llc_hdrlen < 0) {
+                               /*
+                                * Some kinds of LLC packet we cannot
+                                * handle intelligently
+                                */
+                               if (!ndo->ndo_suppress_default_print)
+                                       ND_DEFAULTPRINT(p, caplen);
+                               llc_hdrlen = -llc_hdrlen;
+                       }
+                       hdrlen += llc_hdrlen;
+               }
+               break;
+       default:
+               /* We shouldn't get here - we should already have quit */
+               break;
+       }
+
+       return hdrlen;
+}
+
+/*
+ * This is the top level routine of the printer.  'p' points
+ * to the 802.11 header of the packet, 'h->ts' is the timestamp,
+ * 'h->len' is the length of the packet off the wire, and 'h->caplen'
+ * is the number of bytes actually captured.
+ */
+u_int
+ieee802_11_if_print(netdissect_options *ndo,
+                    const struct pcap_pkthdr *h, const u_char *p)
+{
+       return ieee802_11_print(ndo, p, h->len, h->caplen, 0, 0);
+}
+
+
+/* $FreeBSD: src/sys/net80211/ieee80211_radiotap.h,v 1.5 2005/01/22 20:12:05 sam Exp $ */
+/* NetBSD: ieee802_11_radio.h,v 1.2 2006/02/26 03:04:03 dyoung Exp  */
+
+/*-
+ * 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.
+ */
+
+/* A generic radio capture format is desirable. It must be
+ * rigidly defined (e.g., units for fields should be given),
+ * and easily extensible.
+ *
+ * The following is an 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.
+ *
+ * Note well: all radiotap fields are little-endian.
+ */
+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              uint64_t       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).
+ *     Note that IEEE80211_RADIOTAP_XCHANNEL must be used to
+ *     represent an HT channel as there is not enough room in
+ *     the flags word.
+ *
+ * IEEE80211_RADIOTAP_FHSS              uint16_t       see below
+ *
+ *      For frequency-hopping radios, the hop set (first byte)
+ *      and pattern (second byte).
+ *
+ * IEEE80211_RADIOTAP_RATE              uint8_t        500kb/s or index
+ *
+ *      Tx/Rx data rate.  If bit 0x80 is set then it represents an
+ *     an MCS index and not an IEEE rate.
+ *
+ * IEEE80211_RADIOTAP_DBM_ANTSIGNAL     int8_t          decibels from
+ *                                                      one milliwatt (dBm)
+ *
+ *      RF signal power at the antenna, decibel difference from
+ *      one milliwatt.
+ *
+ * IEEE80211_RADIOTAP_DBM_ANTNOISE      int8_t          decibels from
+ *                                                      one milliwatt (dBm)
+ *
+ *      RF noise power at the antenna, decibel difference from one
+ *      milliwatt.
+ *
+ * IEEE80211_RADIOTAP_DB_ANTSIGNAL      uint8_t        decibel (dB)
+ *
+ *      RF signal power at the antenna, decibel difference from an
+ *      arbitrary, fixed reference.
+ *
+ * IEEE80211_RADIOTAP_DB_ANTNOISE       uint8_t        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      int8_t          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             uint8_t        bitmap
+ *
+ *      Properties of transmitted and received frames. See flags
+ *      defined below.
+ *
+ * IEEE80211_RADIOTAP_ANTENNA           uint8_t        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_XCHANNEL          uint32_t       bitmap
+ *                                     uint16_t        MHz
+ *                                     uint8_t         channel number
+ *                                     uint8_t         .5 dBm
+ *
+ *     Extended channel specification: flags (see below) followed by
+ *     frequency in MHz, the corresponding IEEE channel number, and
+ *     finally the maximum regulatory transmit power cap in .5 dBm
+ *     units.  This property supersedes IEEE80211_RADIOTAP_CHANNEL
+ *     and only one of the two should be present.
+ *
+ * IEEE80211_RADIOTAP_MCS              uint8_t         known
+ *                                     uint8_t         flags
+ *                                     uint8_t         mcs
+ *
+ *     Bitset indicating which fields have known values, followed
+ *     by bitset of flag values, followed by the MCS rate index as
+ *     in IEEE 802.11n.
+ *
+ * IEEE80211_RADIOTAP_VENDOR_NAMESPACE
+ *                                     uint8_t  OUI[3]
+ *                                   uint8_t  subspace
+ *                                   uint16_t length
+ *
+ *     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."
+ *
+ */
+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,
+       /* NB: gap for netbsd definitions */
+       IEEE80211_RADIOTAP_XCHANNEL = 18,
+       IEEE80211_RADIOTAP_MCS = 19,
+       IEEE80211_RADIOTAP_NAMESPACE = 29,
+       IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30,
+       IEEE80211_RADIOTAP_EXT = 31
+};
+
+/* channel attributes */
+#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 */
 
-       fc = EXTRACT_LE_16BITS(p);
-       hdrlen = extract_header_length(ndo, fc);
-       if (hdrlen == 0) {
-               /* Unknown frame type or control frame subtype; quit. */
-               return (0);
-       }
-       if (pad)
-               hdrlen = roundup2(hdrlen, 4);
-       if (ndo->ndo_Hflag && FC_TYPE(fc) == T_DATA &&
-           DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) {
-               meshdrlen = extract_mesh_header_length(p+hdrlen);
-               hdrlen += meshdrlen;
-       } else
-               meshdrlen = 0;
+/* Useful combinations of channel characteristics, borrowed from Ethereal */
+#define IEEE80211_CHAN_A \
+        (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
+#define IEEE80211_CHAN_B \
+        (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
+#define IEEE80211_CHAN_G \
+        (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
+#define IEEE80211_CHAN_TA \
+        (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO)
+#define IEEE80211_CHAN_TG \
+        (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN  | IEEE80211_CHAN_TURBO)
 
-       if (caplen < hdrlen) {
-               ND_PRINT((ndo, "%s", tstr));
-               return hdrlen;
-       }
 
-       if (ndo->ndo_eflag)
-               ieee_802_11_hdr_print(ndo, fc, p, hdrlen, meshdrlen);
+/* 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 */
 
-       /*
-        * Go past the 802.11 header.
-        */
-       length -= hdrlen;
-       caplen -= hdrlen;
-       p += hdrlen;
+/* For IEEE80211_RADIOTAP_RX_FLAGS */
+#define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001  /* frame failed crc check */
+#define IEEE80211_RADIOTAP_F_RX_PLCP_CRC       0x0002  /* frame failed PLCP CRC check */
 
-       switch (FC_TYPE(fc)) {
-       case T_MGMT:
-               get_mgmt_src_dst_mac(p - hdrlen, &src, &dst);
-               if (!mgmt_body_print(ndo, fc, src, p, length)) {
-                       ND_PRINT((ndo, "%s", tstr));
-                       return hdrlen;
-               }
-               break;
-       case T_CTRL:
-               if (!ctrl_body_print(ndo, fc, p - hdrlen)) {
-                       ND_PRINT((ndo, "%s", tstr));
-                       return hdrlen;
-               }
-               break;
-       case T_DATA:
-               if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc)))
-                       return hdrlen;  /* no-data frame */
-               /* There may be a problem w/ AP not having this bit set */
-               if (FC_PROTECTED(fc)) {
-                       ND_PRINT((ndo, "Data"));
-                       if (!wep_print(ndo, p)) {
-                               ND_PRINT((ndo, "%s", tstr));
-                               return hdrlen;
-                       }
-               } else {
-                       get_data_src_dst_mac(fc, p - hdrlen, &src, &dst);
-                       llc_hdrlen = llc_print(ndo, p, length, caplen, src, dst);
-                       if (llc_hdrlen < 0) {
-                               /*
-                                * Some kinds of LLC packet we cannot
-                                * handle intelligently
-                                */
-                               if (!ndo->ndo_suppress_default_print)
-                                       ND_DEFAULTPRINT(p, caplen);
-                               llc_hdrlen = -llc_hdrlen;
-                       }
-                       hdrlen += llc_hdrlen;
-               }
-               break;
-       default:
-               /* We shouldn't get here - we should already have quit */
-               break;
-       }
+/* For IEEE80211_RADIOTAP_MCS known */
+#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN         0x01
+#define IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN         0x02    /* MCS index field */
+#define IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN    0x04
+#define IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN         0x08
+#define IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN          0x10
+#define IEEE80211_RADIOTAP_MCS_STBC_KNOWN              0x20
 
-       return hdrlen;
-}
+/* For IEEE80211_RADIOTAP_MCS flags */
+#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK  0x03
+#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20    0
+#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_40    1
+#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20L   2
+#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20U   3
+#define IEEE80211_RADIOTAP_MCS_SHORT_GI                0x04 /* short guard interval */
+#define IEEE80211_RADIOTAP_MCS_HT_GREENFIELD   0x08
+#define IEEE80211_RADIOTAP_MCS_FEC_LDPC                0x10
+#define IEEE80211_RADIOTAP_MCS_STBC_MASK       0x60
+#define                IEEE80211_RADIOTAP_MCS_STBC_1   1
+#define                IEEE80211_RADIOTAP_MCS_STBC_2   2
+#define                IEEE80211_RADIOTAP_MCS_STBC_3   3
+#define IEEE80211_RADIOTAP_MCS_STBC_SHIFT      5
 
-/*
- * This is the top level routine of the printer.  'p' points
- * to the 802.11 header of the packet, 'h->ts' is the timestamp,
- * 'h->len' is the length of the packet off the wire, and 'h->caplen'
- * is the number of bytes actually captured.
- */
-u_int
-ieee802_11_if_print(netdissect_options *ndo,
-                    const struct pcap_pkthdr *h, const u_char *p)
+/* Radiotap state */
+/*  This is used to save state when parsing/processing parameters */
+struct radiotap_state
 {
-       return ieee802_11_print(ndo, p, h->len, h->caplen, 0, 0);
-}
+       uint32_t        present;
+
+       uint8_t         rate;
+};
 
 #define        IEEE80211_CHAN_FHSS \
        (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)