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).