I would like to see some more flags and subtypes in tcpdump.
So here is a diff that prints the FC flags (e.g. the PWR flag) and
also knows more about the various data subtypes.

OK?
-- 
:wq Claudio

Index: usr.sbin/tcpdump/print-802_11.c
===================================================================
RCS file: /cvs/src/usr.sbin/tcpdump/print-802_11.c,v
retrieving revision 1.12
diff -u -p -r1.12 print-802_11.c
--- usr.sbin/tcpdump/print-802_11.c     14 Aug 2007 19:10:45 -0000      1.12
+++ usr.sbin/tcpdump/print-802_11.c     17 Sep 2012 12:21:25 -0000
@@ -52,11 +52,30 @@ const char *ieee80211_mgt_subtype_name[]
        "disassociation",
        "authentication",
        "deauthentication",
-       "reserved#13",
-       "reserved#14",
+       "action",
+       "action noack",
        "reserved#15"
 };
 
+const char *ieee80211_data_subtype_name[] = {
+       "data",
+       "data cf ack",
+       "data cf poll",
+       "data cf poll ack",
+       "no-data",
+       "no-data cf poll",
+       "no-data cf ack",
+       "no-data cf poll ack",
+       "QoS data",
+       "QoS data cf ack",
+       "QoS data cf poll",
+       "QoS data cf poll ack",
+       "QoS no-data",
+       "QoS no-data cf poll",
+       "QoS no-data cf ack",
+       "QoS no-data cf poll ack"
+};
+
 int     ieee80211_hdr(struct ieee80211_frame *);
 int     ieee80211_data(struct ieee80211_frame *, u_int);
 void    ieee80211_print_element(u_int8_t *, u_int);
@@ -134,6 +153,8 @@ ieee80211_data(struct ieee80211_frame *w
        u_int8_t *t = (u_int8_t *)wh;
        struct ieee80211_frame_addr4 *w4;
        u_int datalen;
+       int data = !(wh->i_fc[1] & IEEE80211_FC0_SUBTYPE_NODATA);
+       u_char *esrc = NULL, *edst = NULL;
 
        TCHECK(*wh);
        t += sizeof(struct ieee80211_frame);
@@ -141,23 +162,33 @@ ieee80211_data(struct ieee80211_frame *w
 
        switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
        case IEEE80211_FC1_DIR_TODS:
-               llc_print(t, datalen, datalen, wh->i_addr2, wh->i_addr3);
+               esrc = wh->i_addr2;
+               edst = wh->i_addr3;
                break;
        case IEEE80211_FC1_DIR_FROMDS:
-               llc_print(t, datalen, datalen, wh->i_addr3, wh->i_addr1);
+               esrc = wh->i_addr3;
+               edst = wh->i_addr1;
                break;
        case IEEE80211_FC1_DIR_NODS:
-               llc_print(t, datalen, datalen, wh->i_addr2, wh->i_addr1);
+               esrc = wh->i_addr2;
+               edst = wh->i_addr1;
                break;
        case IEEE80211_FC1_DIR_DSTODS:
                w4 = (struct ieee80211_frame_addr4 *) wh;
                TCHECK(*w4);
                t = (u_int8_t *) (w4 + 1);
                datalen = len - sizeof(*w4);
-               llc_print(t, datalen, datalen, w4->i_addr4, w4->i_addr3);
+               esrc = w4->i_addr4;
+               edst = w4->i_addr3;
                break;
        }
 
+       if (data && esrc)
+               llc_print(t, datalen, datalen, esrc, edst);
+       else if (eflag && esrc)
+               printf("%s > %s",
+                   etheraddr_string(esrc), etheraddr_string(edst));
+
        return (0);
 
  trunc:
@@ -360,9 +391,13 @@ ieee80211_frame(struct ieee80211_frame *
 
        frm = (u_int8_t *)&wh[1];
 
+       if (vflag)
+               printb(" flags", wh->i_fc[1], IEEE80211_FC1_BITS);
+
        switch (type) {
        case IEEE80211_FC0_TYPE_DATA:
-               printf(": data: ");
+               printf(": %s: ", ieee80211_data_subtype_name[
+                   subtype >> IEEE80211_FC0_SUBTYPE_SHIFT]);
                ieee80211_data(wh, len);
                break;
        case IEEE80211_FC0_TYPE_MGT:
@@ -421,9 +456,6 @@ ieee80211_frame(struct ieee80211_frame *
                printf(": type#%d", type);
                break;
        }
-
-       if (wh->i_fc[1] & IEEE80211_FC1_WEP)
-               printf(", WEP");
 
        return (0);
 
Index: sys/net80211//ieee80211.h
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211.h,v
retrieving revision 1.49
diff -u -p -r1.49 ieee80211.h
--- sys/net80211//ieee80211.h   28 Jan 2009 18:55:18 -0000      1.49
+++ sys/net80211//ieee80211.h   17 Sep 2012 08:16:04 -0000
@@ -162,6 +162,9 @@ struct ieee80211_htframe_addr4 {    /* 11n 
 #define        IEEE80211_FC1_PROTECTED                 0x40
 #define        IEEE80211_FC1_WEP                       0x40    /* pre-RSNA 
compat */
 #define        IEEE80211_FC1_ORDER                     0x80
+#define IEEE80211_FC1_BITS                                     \
+       "\20\03MORE_FRAG\04RETRY\05PWR_MGT\06MORE_DATA"         \
+       "\07PROTECTED\08ORDER"
 
 /*
  * Sequence Control field (see 7.1.3.4).

Reply via email to