When I added support for the HT Capabilities element to tcpdump(1)
I left out a couple of fields we did not yet have #defines for.

Since these fields contain valuable information (such as the MCS rates
supported by an AP), let's print them, too.

ok?

Index: sys/net80211/ieee80211.h
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211.h,v
retrieving revision 1.52
diff -u -p -r1.52 ieee80211.h
--- sys/net80211/ieee80211.h    14 Jul 2015 21:13:12 -0000      1.52
+++ sys/net80211/ieee80211.h    9 Oct 2015 12:11:03 -0000
@@ -572,6 +572,29 @@ enum {
 #define IEEE80211_HTCAP_LSIGTXOPPROT   0x00008000
 
 /*
+ * HT A-MPDU parameters (see 802.11-2012 8.4.2.58.3).
+ */
+#define IEEE80211_AMPDU_PARAM_LE       0x03
+#define IEEE80211_AMPDU_PARAM_SS       0x1c
+
+/*
+ * HT Supported MCS Set (see 802.11-2012 8.4.2.58.4).
+ * This field is 16 bytes in size. Bitmasks given below
+ * operate on 8 or 16 bit integer subsets of this field.
+ */
+/* Bits 0-77: Supported Rx MCS bitmask */
+/* Bits 77-79: Reserved */
+/* Bits 80-89: Highest Rx rate in units of 1MB/s */
+#define IEEE80211_MCS_RX_RATE_HIGH     0x03ff
+/* Bits 90-95: Reserved */
+/* Bits 96-100: Tx MCS set */
+#define IEEE80211_TX_MCS_SET_DEFINED           0x01
+#define IEEE80211_TX_RX_MCS_NOT_EQUAL          0x02
+#define IEEE80211_TX_SPATIAL_STREAMS           0x18
+#define IEEE80211_TX_UNEQUAL_MODULATION                0x20
+/* Bits 101-127: Reserved */
+
+/*
  * HT Extended Capabilities (see 802.11-2012 8.4.2.58.5).
  */
 #define IEEE80211_HTXCAP_PCO           0x0001
Index: usr.sbin/tcpdump/Makefile
===================================================================
RCS file: /cvs/src/usr.sbin/tcpdump/Makefile,v
retrieving revision 1.56
diff -u -p -r1.56 Makefile
--- usr.sbin/tcpdump/Makefile   30 Jun 2014 04:25:11 -0000      1.56
+++ usr.sbin/tcpdump/Makefile   9 Oct 2015 11:01:27 -0000
@@ -30,7 +30,7 @@ CFLAGS+=-I${.CURDIR}/../../lib/libpcap
 
 CFLAGS+=-DCSLIP -DPPP -DHAVE_FDDI -DETHER_SERVICE -DRETSIGTYPE=void 
-DHAVE_NET_SLIP_H -DHAVE_ETHER_NTOHOST -DINET6
 
-LDADD+=        -lpcap -ll -lcrypto
+LDADD+=        -lpcap -ll -lcrypto -lm
 DPADD+=        ${LIBL} ${LIBPCAP} ${LIBCRYPTO}
 
 SRCS=  tcpdump.c addrtoname.c privsep.c privsep_fdpass.c privsep_pcap.c \
Index: usr.sbin/tcpdump/print-802_11.c
===================================================================
RCS file: /cvs/src/usr.sbin/tcpdump/print-802_11.c,v
retrieving revision 1.24
diff -u -p -r1.24 print-802_11.c
--- usr.sbin/tcpdump/print-802_11.c     19 Jul 2015 02:49:54 -0000      1.24
+++ usr.sbin/tcpdump/print-802_11.c     9 Oct 2015 12:16:33 -0000
@@ -33,6 +33,7 @@
 #include <pcap.h>
 #include <stdio.h>
 #include <string.h>
+#include <math.h>
 
 #include "addrtoname.h"
 #include "interface.h"
@@ -279,8 +280,11 @@ ieee80211_print_country(u_int8_t *data, 
 void
 ieee80211_print_htcaps(u_int8_t *data, u_int len)
 {
-       u_int16_t htcaps;
+       uint16_t htcaps, rxrate;
        int smps, rxstbc;
+       uint8_t ampdu, txmcs;
+       int i;
+       uint8_t *rxmcs;
 
        if (len < 2) {
                ieee80211_print_element(data, len);
@@ -347,6 +351,83 @@ ieee80211_print_htcaps(u_int8_t *data, u
        /* L-SIG TXOP protection */
        if (htcaps & IEEE80211_HTCAP_LSIGTXOPPROT)
                printf(",L-SIG TXOP prot");
+
+       if (len < 3) {
+               printf(">");
+               return;
+       }
+
+       /* A-MPDU parameters. */
+       ampdu = data[2];
+
+       /* A-MPDU length exponent */
+       if ((ampdu & IEEE80211_AMPDU_PARAM_LE) >= 0 &&
+           (ampdu & IEEE80211_AMPDU_PARAM_LE) <= 3)
+               printf(",A-MPDU max %d",
+                   (int)(exp2f(13 + (ampdu & IEEE80211_AMPDU_PARAM_LE)) - 1));
+
+       /* A-MPDU start spacing */
+       if (ampdu & IEEE80211_AMPDU_PARAM_SS) {
+               float ss;
+
+               switch ((ampdu & IEEE80211_AMPDU_PARAM_SS) >> 2) {
+               case 1:
+                       ss = 0.25;
+                       break;
+               case 2:
+                       ss = 0.5;
+                       break;
+               case 3:
+                       ss = 1;
+                       break;
+               case 4:
+                       ss = 2;
+                       break;
+               case 5:
+                       ss = 4;
+                       break;
+               case 6:
+                       ss = 8;
+                       break;
+               case 7:
+                       ss = 16;
+                       break;
+               default:
+                       ss = 0;
+                       break;
+               }
+               if (ss != 0)
+                       printf(",A-MPDU spacing %.2fus", ss);
+       }
+
+       if (len < 21) {
+               printf(">");
+               return;
+       }
+
+       /* Supported MCS set. */
+       printf(",RxMCS 0x");
+       rxmcs = &data[3];
+       for (i = 0; i < 10; i++)
+               printf("%x", rxmcs[i]);
+
+       /* Max MCS Rx rate (a value of 0 means "not specified"). */
+       rxrate = ((data[13] | (data[14]) << 8) & IEEE80211_MCS_RX_RATE_HIGH);
+       if (rxrate)
+               printf(",RxMaxrate %huMb/s", rxrate);
+
+       /* Tx MCS Set */
+       txmcs = data[15];
+       if (txmcs & IEEE80211_TX_MCS_SET_DEFINED) {
+               if (txmcs & IEEE80211_TX_RX_MCS_NOT_EQUAL) {
+                       /* Number of spatial Tx streams. */
+                       printf(",%d Tx streams",
+                            1 + ((txmcs & IEEE80211_TX_SPATIAL_STREAMS) >> 2));
+                       /* Transmit unequal modulation supported. */
+                       if (txmcs & IEEE80211_TX_UNEQUAL_MODULATION)
+                               printf(",UEQM");
+               }
+       }
 
        printf(">");
 }

Reply via email to