> Date: Wed, 3 Feb 2016 13:27:50 +0100 > From: Stefan Sperling <s...@stsp.name> > > Currently, tcpdump displays 802.11 control frames as "type#4" and > doesn't give more information than that. > > This diff makes tcpdump show the subtype of such frames, and pretty-print > a few subtypes in verbose mode. There are more subtypes but these can > be pretty-printed later. > > This can be tested with: > > ifconfig iwn0 mediaopt monitor up > tcpdump -n -i iwn0 -y IEEE802_11_RADIO -v -s 1500 type ctl > > Whether such frames can be seen depends on the driver's RX filter > settings in monitor mode. Another driver I've tested with is zyd(4). > > ok?
ok kettenis@ > Index: print-802_11.c > =================================================================== > RCS file: /cvs/src/usr.sbin/tcpdump/print-802_11.c,v > retrieving revision 1.29 > diff -u -p -r1.29 print-802_11.c > --- print-802_11.c 1 Feb 2016 10:09:44 -0000 1.29 > +++ print-802_11.c 3 Feb 2016 12:21:20 -0000 > @@ -37,6 +37,25 @@ > #include "addrtoname.h" > #include "interface.h" > > +const char *ieee80211_ctl_subtype_name[] = { > + "reserved#0", > + "reserved#1", > + "reserved#2", > + "reserved#3", > + "reserved#4", > + "reserved#5", > + "reserved#6", > + "wrapper", > + "block ack request", > + "block ack", > + "ps poll", > + "rts", > + "cts", > + "ack", > + "cf-end", > + "cf-end-ack", > +}; > + > const char *ieee80211_mgt_subtype_name[] = { > "association request", > "association response", > @@ -813,6 +832,69 @@ ieee80211_frame(struct ieee80211_frame * > break; > } > break; > + case IEEE80211_FC0_TYPE_CTL: { > + u_int8_t *t = (u_int8_t *) wh; > + > + printf(": %s", ieee80211_ctl_subtype_name[ > + subtype >> IEEE80211_FC0_SUBTYPE_SHIFT]); > + if (!vflag) > + break; > + > + /* See 802.11 2012 "8.3.1 Control frames". */ > + t += 2; /* skip Frame Control */ > + switch (subtype) { > + case IEEE80211_FC0_SUBTYPE_RTS: > + case IEEE80211_FC0_SUBTYPE_BAR: > + case IEEE80211_FC0_SUBTYPE_BA: > + TCHECK2(*t, 2); /* Duration */ > + printf(", duration %dms", (t[0] || t[1] << 8)); > + t += 2; > + TCHECK2(*t, 6); /* RA */ > + printf(", ra %s", etheraddr_string(t)); > + t += 6; > + TCHECK2(*t, 6); /* TA */ > + printf(", ta %s", etheraddr_string(t)); > + if (subtype == IEEE80211_FC0_SUBTYPE_BAR || > + subtype == IEEE80211_FC0_SUBTYPE_BA) { > + u_int16_t ctrl; > + > + TCHECK2(*t, 2); /* BAR/BA control */ > + ctrl = t[0] | (t[1] << 8); > + if (ctrl & IEEE80211_BA_ACK_POLICY) > + printf(", no ack"); > + else > + printf(", normal ack"); > + if ((ctrl & IEEE80211_BA_MULTI_TID) == 0 && > + (ctrl & IEEE80211_BA_COMPRESSED) == 0) > + printf(", basic variant"); > + else if ((ctrl & IEEE80211_BA_MULTI_TID) && > + (ctrl & IEEE80211_BA_COMPRESSED)) > + printf(", multi-tid variant"); > + else if (ctrl & IEEE80211_BA_COMPRESSED) > + printf(", compressed variant"); > + } > + break; > + case IEEE80211_FC0_SUBTYPE_CTS: > + case IEEE80211_FC0_SUBTYPE_ACK: > + TCHECK2(*t, 2); /* Duration */ > + printf(", duration %dms", (t[0] || t[1] << 8)); > + t += 2; > + TCHECK2(*t, 6); /* RA */ > + printf(", ra %s", etheraddr_string(t)); > + break; > + case IEEE80211_FC0_SUBTYPE_PS_POLL: > + TCHECK2(*t, 2); /* AID */ > + printf(", aid 0x%x", (t[0] || t[1] << 8)); > + t += 2; > + TCHECK2(*t, 6); /* BSSID(RA) */ > + printf(", RA %s", etheraddr_string(t)); > + t += 6; > + TCHECK2(*t, 6); /* TA */ > + printf(", ta %s", etheraddr_string(t)); > + break; > + } > + break; > + } > default: > printf(": type#%d", type); > break; > >