This diff makes tcpdump display details of association requests.
These are interesting because clients announce HT capabilities there.
We can share some printing code with beacons.

Use with something like tcpdump -s 1500 -v -y IEEE802_11_RADIO -i iwn0

Index: print-802_11.c
===================================================================
RCS file: /cvs/src/usr.sbin/tcpdump/print-802_11.c,v
retrieving revision 1.32
diff -u -p -r1.32 print-802_11.c
--- print-802_11.c      21 Feb 2016 16:09:47 -0000      1.32
+++ print-802_11.c      1 Sep 2016 12:21:43 -0000
@@ -101,7 +101,9 @@ void         ieee80211_print_essid(u_int8_t *, 
 void    ieee80211_print_country(u_int8_t *, u_int);
 void    ieee80211_print_htcaps(u_int8_t *, u_int);
 void    ieee80211_print_htop(u_int8_t *, u_int);
-int     ieee80211_elements(struct ieee80211_frame *, u_int);
+int     ieee80211_print_beacon(struct ieee80211_frame *, u_int);
+int     ieee80211_print_assocreq(struct ieee80211_frame *, u_int);
+int     ieee80211_print_elements(uint8_t *);
 int     ieee80211_frame(struct ieee80211_frame *, u_int);
 int     ieee80211_print(struct ieee80211_frame *, u_int);
 u_int   ieee80211_any2ieee(u_int, u_int);
@@ -589,37 +591,74 @@ ieee80211_print_htop(u_int8_t *data, u_i
 }
 
 int
-ieee80211_elements(struct ieee80211_frame *wh, u_int flen)
+ieee80211_print_beacon(struct ieee80211_frame *wh, u_int len)
 {
-       u_int8_t *buf, *frm;
-       u_int64_t tstamp;
-       u_int16_t bintval, capinfo;
-       int i;
+       uint64_t tstamp;
+       uint16_t bintval, capinfo;
+       uint8_t *frm;
+
+       if (len < sizeof(tstamp) + sizeof(bintval) + sizeof(capinfo))
+               return 1; /* truncated */
 
-       buf = (u_int8_t *)wh;
        frm = (u_int8_t *)&wh[1];
 
-       TCHECK2(*frm, 8);
        bcopy(frm, &tstamp, sizeof(u_int64_t));
        frm += 8;
-
        if (vflag > 1)
                printf(", timestamp %llu", letoh64(tstamp));
 
-       TCHECK2(*frm, 2);
        bcopy(frm, &bintval, sizeof(u_int16_t));
        frm += 2;
-
        if (vflag > 1)
                printf(", interval %u", letoh16(bintval));
 
-       TCHECK2(*frm, 2);
        bcopy(frm, &capinfo, sizeof(u_int16_t));
        frm += 2;
+       if (vflag)
+               printb(", caps", letoh16(capinfo), IEEE80211_CAPINFO_BITS);
+
+       return ieee80211_print_elements(frm);
+}
+
+int
+ieee80211_print_assocreq(struct ieee80211_frame *wh, u_int len)
+{
+       uint8_t subtype;
+       uint16_t capinfo, lintval;
+       uint8_t *frm;
+
+       subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
+
+       if (len < sizeof(capinfo) + sizeof(lintval) +
+           (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ ?
+           IEEE80211_ADDR_LEN : 0))
+               return 1; /* truncated */
+
+       frm = (u_int8_t *)&wh[1];
 
+       bcopy(frm, &capinfo, sizeof(u_int16_t));
+       frm += 2;
        if (vflag)
-               printb(", caps", letoh16(capinfo),
-                   IEEE80211_CAPINFO_BITS);
+               printb(", caps", letoh16(capinfo), IEEE80211_CAPINFO_BITS);
+
+       bcopy(frm, &lintval, sizeof(u_int16_t));
+       frm += 2;
+       if (vflag > 1)
+               printf(", listen interval %u", letoh16(lintval));
+
+       if (subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) {
+               if (vflag)
+                       printf(", AP %s", etheraddr_string(frm));
+               frm += IEEE80211_ADDR_LEN;
+       }
+
+       return ieee80211_print_elements(frm);
+}
+
+int
+ieee80211_print_elements(uint8_t *frm)
+{
+       int i;
 
        while (TTEST2(*frm, 2)) {
                u_int len = frm[1];
@@ -628,7 +667,7 @@ ieee80211_elements(struct ieee80211_fram
                if (!TTEST2(*data, len))
                        break;
 
-#define ELEM_CHECK(l)  if (len != l) break
+#define ELEM_CHECK(l)  if (len != l) goto trunc
 
                switch (*frm) {
                case IEEE80211_ELEMID_SSID:
@@ -789,7 +828,12 @@ ieee80211_frame(struct ieee80211_frame *
                switch (subtype) {
                case IEEE80211_FC0_SUBTYPE_BEACON:
                case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
-                       if (ieee80211_elements(wh, len) != 0)
+                       if (ieee80211_print_beacon(wh, len) != 0)
+                               goto trunc;
+                       break;
+               case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
+               case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
+                       if (ieee80211_print_assocreq(wh, len) != 0)
                                goto trunc;
                        break;
                case IEEE80211_FC0_SUBTYPE_AUTH:

Reply via email to