> 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;
> 
> 

Reply via email to