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(">");
}