summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstsp <stsp@openbsd.org>2016-02-03 16:08:09 +0000
committerstsp <stsp@openbsd.org>2016-02-03 16:08:09 +0000
commit8dd9ce3edc73e4965f55577cf4f6cddba9a58d77 (patch)
tree93dc868b0b728c16dd0ad7c16ad0a9c09d817807
parentRename a local var so that we can call the global message buffer msg. (diff)
downloadwireguard-openbsd-8dd9ce3edc73e4965f55577cf4f6cddba9a58d77.tar.xz
wireguard-openbsd-8dd9ce3edc73e4965f55577cf4f6cddba9a58d77.zip
Make tcpdump show 802.11 control frames.
ok kettenis@, and help from David Vasek (thanks!)
-rw-r--r--usr.sbin/tcpdump/print-802_11.c85
1 files changed, 84 insertions, 1 deletions
diff --git a/usr.sbin/tcpdump/print-802_11.c b/usr.sbin/tcpdump/print-802_11.c
index 0a2778b2a94..5a3a2068495 100644
--- a/usr.sbin/tcpdump/print-802_11.c
+++ b/usr.sbin/tcpdump/print-802_11.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: print-802_11.c,v 1.29 2016/02/01 10:09:44 stsp Exp $ */
+/* $OpenBSD: print-802_11.c,v 1.30 2016/02/03 16:08:09 stsp Exp $ */
/*
* Copyright (c) 2005 Reyk Floeter <reyk@openbsd.org>
@@ -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,70 @@ ieee80211_frame(struct ieee80211_frame *wh, u_int len)
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;
+
+ t += 6;
+ 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;