]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Fix the radiotap printer to handle the special bits correctly.
authorGuy Harris <[email protected]>
Mon, 11 Jan 2016 23:47:31 +0000 (15:47 -0800)
committerGuy Harris <[email protected]>
Mon, 11 Jan 2016 23:47:31 +0000 (15:47 -0800)
Process bits 29, 30, and 31 in code that's independent of what namespace
we're in:

  If we're switching to the radiotap namespace, reset the bit numbers to
  start back at 0.

  If we're switching to a vendor namespace, get the vendor OUI and
  subspace, and the skip length.

  Keep trace of which namespace we're in.

  If we're *in* a vendor namespace, skip over the data specified by the
  skip length (and reset it, as we've processed all the vendor namespace
  data and, if there's a subsequent bitmap in the same namespace,
  there's nothing more to process.  Use cpack_align_and_reserve() to
  skip that, so we check that we don't go past the end of the packet
  data.

Fixes GitHub tcpdump issue #498.

This removes some bogus errors; update the test output to reflect that.

print-802_11.c
tests/ieee802.11_exthdr.out

index 02e8cb2efc21bde9507961d0a04462746d7c19d2..27f15f44ec75731be7846a3458d8acddf145df61 100644 (file)
@@ -2492,16 +2492,6 @@ enum ieee80211_radiotap_type {
 
 #define IEEE80211_RADIOTAP_CODING_LDPC_USERn                   0x01
 
-
-/* Radiotap state */
-/*  This is used to save state when parsing/processing parameters */
-struct radiotap_state
-{
-       uint32_t        present;
-
-       uint8_t         rate;
-};
-
 #define        IEEE80211_CHAN_FHSS \
        (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
 #define        IEEE80211_CHAN_A \
@@ -2575,7 +2565,7 @@ print_chaninfo(netdissect_options *ndo,
 static int
 print_radiotap_field(netdissect_options *ndo,
                      struct cpack_state *s, uint32_t bit, uint8_t *flags,
-                     struct radiotap_state *state, uint32_t presentflags)
+                     uint32_t presentflags)
 {
        union {
                int8_t          i8;
@@ -2598,11 +2588,6 @@ print_radiotap_field(netdissect_options *ndo,
                break;
        case IEEE80211_RADIOTAP_RATE:
                rc = cpack_uint8(s, &u.u8);
-               if (rc != 0)
-                       break;
-
-               /* Save state rate */
-               state->rate = u.u8;
                break;
        case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
        case IEEE80211_RADIOTAP_DB_ANTNOISE:
@@ -2691,36 +2676,6 @@ print_radiotap_field(netdissect_options *ndo,
                rc = cpack_uint16(s, &u6.u16);
        fail:
                break;
-       case IEEE80211_RADIOTAP_VENDOR_NAMESPACE: {
-               uint8_t vns[3];
-               uint16_t length;
-               uint8_t subspace;
-
-               if ((cpack_align_and_reserve(s, 2)) == NULL) {
-                       rc = -1;
-                       break;
-               }
-
-               rc = cpack_uint8(s, &vns[0]);
-               if (rc != 0)
-                       break;
-               rc = cpack_uint8(s, &vns[1]);
-               if (rc != 0)
-                       break;
-               rc = cpack_uint8(s, &vns[2]);
-               if (rc != 0)
-                       break;
-               rc = cpack_uint8(s, &subspace);
-               if (rc != 0)
-                       break;
-               rc = cpack_uint16(s, &length);
-               if (rc != 0)
-                       break;
-
-               /* Skip up to length */
-               s->c_next += length;
-               break;
-       }
        default:
                /* this bit indicates a field whose
                 * size we do not know, so we cannot
@@ -2735,9 +2690,6 @@ print_radiotap_field(netdissect_options *ndo,
                return rc;
        }
 
-       /* Preserve the state present flags */
-       state->present = presentflags;
-
        switch (bit) {
        case IEEE80211_RADIOTAP_CHANNEL:
                /*
@@ -2990,31 +2942,76 @@ print_radiotap_field(netdissect_options *ndo,
        return 0;
 }
 
-static u_int
-ieee802_11_radio_print(netdissect_options *ndo,
-                       const u_char *p, u_int length, u_int caplen)
+
+static int
+print_in_radiotap_namespace(netdissect_options *ndo,
+                            struct cpack_state *s, uint8_t *flags,
+                            uint32_t presentflags, int bit0)
 {
 #define        BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
 #define        BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
 #define        BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
 #define        BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
 #define        BITNO_2(x) (((x) & 2) ? 1 : 0)
+       uint32_t present, next_present;
+       int bitno;
+       enum ieee80211_radiotap_type bit;
+       int rc;
+
+       for (present = presentflags; present; present = next_present) {
+               /*
+                * Clear the least significant bit that is set.
+                */
+               next_present = present & (present - 1);
+
+               /*
+                * Get the bit number, within this presence word,
+                * of the remaining least significant bit that
+                * is set.
+                */
+               bitno = BITNO_32(present ^ next_present);
+
+               /*
+                * Stop if this is one of the "same meaning
+                * in all presence flags" bits.
+                */
+               if (bitno >= IEEE80211_RADIOTAP_NAMESPACE)
+                       break;
+
+               /*
+                * Get the radiotap bit number of that bit.
+                */
+               bit = (enum ieee80211_radiotap_type)(bit0 + bitno);
+
+               rc = print_radiotap_field(ndo, s, bit, flags, presentflags);
+               if (rc != 0)
+                       return rc;
+       }
+
+       return 0;
+}
+
+static u_int
+ieee802_11_radio_print(netdissect_options *ndo,
+                       const u_char *p, u_int length, u_int caplen)
+{
 #define        BIT(n)  (1U << n)
 #define        IS_EXTENDED(__p)        \
            (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
 
        struct cpack_state cpacker;
        const struct ieee80211_radiotap_header *hdr;
-       uint32_t present, next_present;
-       uint32_t presentflags = 0;
+       uint32_t presentflags;
        const uint32_t *presentp, *last_presentp;
-       enum ieee80211_radiotap_type bit;
+       int vendor_namespace;
+       uint8_t vendor_oui[3];
+       uint8_t vendor_subnamespace;
+       uint16_t skip_length;
        int bit0;
        u_int len;
        uint8_t flags;
        int pad;
        u_int fcslen;
-       struct radiotap_state state;
 
        if (caplen < sizeof(*hdr)) {
                ND_PRINT((ndo, "%s", tstr));
@@ -3043,34 +3040,133 @@ ieee802_11_radio_print(netdissect_options *ndo,
                return caplen;
        }
 
+       /*
+        * Start out at the beginning of the default radiotap namespace.
+        */
+       bit0 = 0;
+       vendor_namespace = 0;
+       memset(vendor_oui, 0, 3);
+       vendor_subnamespace = 0;
+       skip_length = 0;
        /* Assume no flags */
        flags = 0;
        /* Assume no Atheros padding between 802.11 header and body */
        pad = 0;
        /* Assume no FCS at end of frame */
        fcslen = 0;
-       for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp;
-            presentp++, bit0 += 32) {
+       for (presentp = &hdr->it_present; presentp <= last_presentp;
+           presentp++) {
                presentflags = EXTRACT_LE_32BITS(presentp);
 
-               /* Clear state. */
-               memset(&state, 0, sizeof(state));
+               /*
+                * If this is a vendor namespace, we don't handle it.
+                */
+               if (vendor_namespace) {
+                       /*
+                        * Skip past the stuff we don't understand.
+                        * If we add support for any vendor namespaces,
+                        * it'd be added here; use vendor_oui and
+                        * vendor_subnamespace to interpret the fields.
+                        */
+                       if (cpack_advance(&cpacker, skip_length) != 0) {
+                               /*
+                                * Ran out of space in the packet.
+                                */
+                               break;
+                       }
 
-               for (present = EXTRACT_LE_32BITS(presentp); present;
-                    present = next_present) {
-                       /* clear the least significant bit that is set */
-                       next_present = present & (present - 1);
+                       /*
+                        * We've skipped it all; nothing more to
+                        * skip.
+                        */
+                       skip_length = 0;
+               } else {
+                       if (print_in_radiotap_namespace(ndo, &cpacker,
+                           &flags, presentflags, bit0) != 0) {
+                               /*
+                                * Fatal error - can't process anything
+                                * more in the radiotap header.
+                                */
+                               break;
+                       }
+               }
+
+               /*
+                * Handle the namespace switch bits; we've already handled
+                * the extension bit in all but the last word above.
+                */
+               switch (presentflags &
+                   (BIT(IEEE80211_RADIOTAP_NAMESPACE)|BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE))) {
 
-                       /* extract the least significant bit that is set */
-                       bit = (enum ieee80211_radiotap_type)
-                           (bit0 + BITNO_32(present ^ next_present));
+               case 0:
+                       /*
+                        * We're not changing namespaces.
+                        * advance to the next 32 bits in the current
+                        * namespace.
+                        */
+                       bit0 += 32;
+                       break;
 
-                       if (print_radiotap_field(ndo, &cpacker, bit, &flags, &state, presentflags) != 0)
-                               goto out;
+               case BIT(IEEE80211_RADIOTAP_NAMESPACE):
+                       /*
+                        * We're switching to the radiotap namespace.
+                        * Reset the presence-bitmap index to 0, and
+                        * reset the namespace to the default radiotap
+                        * namespace.
+                        */
+                       bit0 = 0;
+                       vendor_namespace = 0;
+                       memset(vendor_oui, 0, 3);
+                       vendor_subnamespace = 0;
+                       skip_length = 0;
+                       break;
+
+               case BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE):
+                       /*
+                        * We're switching to a vendor namespace.
+                        * Reset the presence-bitmap index to 0,
+                        * note that we're in a vendor namespace,
+                        * and fetch the fields of the Vendor Namespace
+                        * item.
+                        */
+                       bit0 = 0;
+                       vendor_namespace = 1;
+                       if ((cpack_align_and_reserve(&cpacker, 2)) == NULL) {
+                               ND_PRINT((ndo, "%s", tstr));
+                               break;
+                       }
+                       if (cpack_uint8(&cpacker, &vendor_oui[0]) != 0) {
+                               ND_PRINT((ndo, "%s", tstr));
+                               break;
+                       }
+                       if (cpack_uint8(&cpacker, &vendor_oui[1]) != 0) {
+                               ND_PRINT((ndo, "%s", tstr));
+                               break;
+                       }
+                       if (cpack_uint8(&cpacker, &vendor_oui[2]) != 0) {
+                               ND_PRINT((ndo, "%s", tstr));
+                               break;
+                       }
+                       if (cpack_uint8(&cpacker, &vendor_subnamespace) != 0) {
+                               ND_PRINT((ndo, "%s", tstr));
+                               break;
+                       }
+                       if (cpack_uint16(&cpacker, &skip_length) != 0) {
+                               ND_PRINT((ndo, "%s", tstr));
+                               break;
+                       }
+                       break;
+
+               default:
+                       /*
+                        * Illegal combination.  The behavior in this
+                        * case is undefined by the radiotap spec; we
+                        * just ignore both bits.
+                        */
+                       break;
                }
        }
 
-out:
        if (flags & IEEE80211_RADIOTAP_F_DATAPAD)
                pad = 1;        /* Atheros padding */
        if (flags & IEEE80211_RADIOTAP_F_FCS)
index 26cf7d8e5267bb7fcfcae0fabe8c0a82ce10dde6..7b217e5e7aaef0131e33beccf55029738689449e 100644 (file)
@@ -1,26 +1,26 @@
-10016360us tsft 1.0 Mb/s 2412 MHz 11b -22dBm signal -86dBm noise antenna 1 [bit 31] Probe Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
-10018922us tsft 1.0 Mb/s 2412 MHz 11b -19dBm signal -86dBm noise antenna 0 [bit 31] Acknowledgment RA:90:a4:de:c0:46:0a 
+10016360us tsft 1.0 Mb/s 2412 MHz 11b -22dBm signal -86dBm noise antenna 1 [bit 32] Probe Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
+10018922us tsft 1.0 Mb/s 2412 MHz 11b -19dBm signal -86dBm noise antenna 0 [bit 32] Acknowledgment RA:90:a4:de:c0:46:0a 
 10017245us tsft 1.0 Mb/s -86dBm noise 27dBm tx power [bit 15] Probe Response (omus) [1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0 Mbit] CH: 1
-10085301us tsft 1.0 Mb/s 2412 MHz 11b -19dBm signal -86dBm noise antenna 1 [bit 31] Probe Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
-10087718us tsft 1.0 Mb/s 2412 MHz 11b -18dBm signal -86dBm noise antenna 0 [bit 31] Acknowledgment RA:90:a4:de:c0:46:0a 
+10085301us tsft 1.0 Mb/s 2412 MHz 11b -19dBm signal -86dBm noise antenna 1 [bit 32] Probe Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
+10087718us tsft 1.0 Mb/s 2412 MHz 11b -18dBm signal -86dBm noise antenna 0 [bit 32] Acknowledgment RA:90:a4:de:c0:46:0a 
 10086042us tsft 1.0 Mb/s -86dBm noise 27dBm tx power [bit 15] Probe Response (omus) [1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0 Mbit] CH: 1
-10284358us tsft 1.0 Mb/s 2412 MHz 11b -61dBm signal -86dBm noise antenna 1 [bit 31] Probe Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
-10288217us tsft 1.0 Mb/s 2412 MHz 11b -46dBm signal -86dBm noise antenna 0 [bit 31] Acknowledgment RA:90:a4:de:c0:46:0a 
+10284358us tsft 1.0 Mb/s 2412 MHz 11b -61dBm signal -86dBm noise antenna 1 [bit 32] Probe Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
+10288217us tsft 1.0 Mb/s 2412 MHz 11b -46dBm signal -86dBm noise antenna 0 [bit 32] Acknowledgment RA:90:a4:de:c0:46:0a 
 10286542us tsft 1.0 Mb/s -86dBm noise 27dBm tx power [bit 15] Probe Response (omus) [1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0 Mbit] CH: 1
-10351366us tsft 1.0 Mb/s 2412 MHz 11b -70dBm signal -86dBm noise antenna 1 [bit 31] Probe Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
-10353769us tsft 1.0 Mb/s 2412 MHz 11b -57dBm signal -86dBm noise antenna 0 [bit 31] Acknowledgment RA:90:a4:de:c0:46:0a 
+10351366us tsft 1.0 Mb/s 2412 MHz 11b -70dBm signal -86dBm noise antenna 1 [bit 32] Probe Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
+10353769us tsft 1.0 Mb/s 2412 MHz 11b -57dBm signal -86dBm noise antenna 0 [bit 32] Acknowledgment RA:90:a4:de:c0:46:0a 
 10352092us tsft 1.0 Mb/s -86dBm noise 27dBm tx power [bit 15] Probe Response (omus) [1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0 Mbit] CH: 1
-10418368us tsft 1.0 Mb/s 2412 MHz 11b -67dBm signal -86dBm noise antenna 1 [bit 31] Probe Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
-10420929us tsft 1.0 Mb/s 2412 MHz 11b -73dBm signal -86dBm noise antenna 0 [bit 31] Acknowledgment RA:90:a4:de:c0:46:0a 
+10418368us tsft 1.0 Mb/s 2412 MHz 11b -67dBm signal -86dBm noise antenna 1 [bit 32] Probe Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
+10420929us tsft 1.0 Mb/s 2412 MHz 11b -73dBm signal -86dBm noise antenna 0 [bit 32] Acknowledgment RA:90:a4:de:c0:46:0a 
 10419253us tsft 1.0 Mb/s -86dBm noise 27dBm tx power [bit 15] Probe Response (omus) [1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0 Mbit] CH: 1
-10485371us tsft 1.0 Mb/s 2412 MHz 11b -72dBm signal -86dBm noise antenna 1 [bit 31] Probe Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
-10489278us tsft 1.0 Mb/s 2412 MHz 11b -74dBm signal -86dBm noise antenna 0 [bit 31] Acknowledgment RA:90:a4:de:c0:46:0a 
+10485371us tsft 1.0 Mb/s 2412 MHz 11b -72dBm signal -86dBm noise antenna 1 [bit 32] Probe Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
+10489278us tsft 1.0 Mb/s 2412 MHz 11b -74dBm signal -86dBm noise antenna 0 [bit 32] Acknowledgment RA:90:a4:de:c0:46:0a 
 10487602us tsft 1.0 Mb/s -86dBm noise 27dBm tx power [bit 15] Probe Response (omus) [1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0 Mbit] CH: 1
-13338508us tsft 1.0 Mb/s 2412 MHz 11b -14dBm signal -86dBm noise antenna 1 [bit 31] Authentication (Open System)-1: Successful
-13340215us tsft 1.0 Mb/s 2412 MHz 11b -17dBm signal -86dBm noise antenna 0 [bit 31] Acknowledgment RA:90:a4:de:c0:46:0a 
+13338508us tsft 1.0 Mb/s 2412 MHz 11b -14dBm signal -86dBm noise antenna 1 [bit 32] Authentication (Open System)-1: Successful
+13340215us tsft 1.0 Mb/s 2412 MHz 11b -17dBm signal -86dBm noise antenna 0 [bit 32] Acknowledgment RA:90:a4:de:c0:46:0a 
 13339435us tsft 1.0 Mb/s -86dBm noise 27dBm tx power [bit 15] Authentication (Open System)-2: 
-13341999us tsft 1.0 Mb/s 2412 MHz 11b -18dBm signal -86dBm noise antenna 1 [bit 31] Assoc Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
-13346458us tsft 1.0 Mb/s 2412 MHz 11b -18dBm signal -86dBm noise antenna 0 [bit 31] Acknowledgment RA:90:a4:de:c0:46:0a 
+13341999us tsft 1.0 Mb/s 2412 MHz 11b -18dBm signal -86dBm noise antenna 1 [bit 32] Assoc Request (omus) [1.0 2.0 5.5 11.0 6.0 9.0 12.0 18.0 Mbit]
+13346458us tsft 1.0 Mb/s 2412 MHz 11b -18dBm signal -86dBm noise antenna 0 [bit 32] Acknowledgment RA:90:a4:de:c0:46:0a 
 13344925us tsft 1.0 Mb/s -86dBm noise 27dBm tx power [bit 15] Assoc Response AID(1) :: Successful
-13355433us tsft 2412 MHz 11n -22dBm signal -86dBm noise antenna 1 19.5 Mb/s MCS 2 20 MHz long GI [bit 31
-13454791us tsft 2412 MHz 11n -21dBm signal -86dBm noise antenna 1 52.0 Mb/s MCS 11 20 MHz long GI [bit 31
+13355433us tsft 2412 MHz 11n -22dBm signal -86dBm noise antenna 1 19.5 Mb/s MCS 2 20 MHz long GI [bit 32
+13454791us tsft 2412 MHz 11n -21dBm signal -86dBm noise antenna 1 52.0 Mb/s MCS 11 20 MHz long GI [bit 32