> Date: Fri, 7 Oct 2016 15:28:19 +0200
> From: Stefan Sperling <s...@stsp.name>
> 
> Currently tcpdump shows "0 Mbit/s" for any frame sent with 11n HT MCS.
> To make progress easier, I'd like to see which MCS are used on the air,
> by any device.
> 
> The change below matches what FreeBSD did to pass an MCS index via radiotap.
> This simply writes the MCS index into a previously unused range of rate 
> values.
> This format is already recognized by third party tools such as wireshark
> so let's just do it the same way.
> 
> The diff below updates the radiotap docs, makes iwn pass the MCS index,
> shows it in tcpdump. I can now see MCS with iwn in monitor mode.
> 
> ok?

ok kettenis@

> Index: sys/net80211/ieee80211_radiotap.h
> ===================================================================
> RCS file: /cvs/src/sys/net80211/ieee80211_radiotap.h,v
> retrieving revision 1.13
> diff -u -p -r1.13 ieee80211_radiotap.h
> --- sys/net80211/ieee80211_radiotap.h 12 Jan 2016 09:28:09 -0000      1.13
> +++ sys/net80211/ieee80211_radiotap.h 7 Oct 2016 13:15:59 -0000
> @@ -90,9 +90,10 @@ struct ieee80211_radiotap_header {
>   *      For frequency-hopping radios, the hop set (first byte)
>   *      and pattern (second byte).
>   *
> - * IEEE80211_RADIOTAP_RATE              u_int8_t        500kb/s
> + * IEEE80211_RADIOTAP_RATE              u_int8_t        500kb/s or MCS index
>   *
> - *      Tx/Rx data rate
> + *      Tx/Rx data rate in units of 500kb/s. If the high bit (0x80) is set
> + *      the remaining bits contain an MCS index instead of a date rate.
>   *
>   * IEEE80211_RADIOTAP_DBM_ANTSIGNAL     int8_t          decibels from
>   *                                                      one milliwatt (dBm)
> Index: sys/dev/pci/if_iwn.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/if_iwn.c,v
> retrieving revision 1.172
> diff -u -p -r1.172 if_iwn.c
> --- sys/dev/pci/if_iwn.c      5 Sep 2016 08:18:18 -0000       1.172
> +++ sys/dev/pci/if_iwn.c      7 Oct 2016 13:10:42 -0000
> @@ -2131,23 +2131,27 @@ iwn_rx_done(struct iwn_softc *sc, struct
>               tap->wr_dbm_antsignal = (int8_t)rssi;
>               tap->wr_dbm_antnoise = (int8_t)sc->noise;
>               tap->wr_tsft = stat->tstamp;
> -             switch (stat->rate) {
> -             /* CCK rates. */
> -             case  10: tap->wr_rate =   2; break;
> -             case  20: tap->wr_rate =   4; break;
> -             case  55: tap->wr_rate =  11; break;
> -             case 110: tap->wr_rate =  22; break;
> -             /* OFDM rates. */
> -             case 0xd: tap->wr_rate =  12; break;
> -             case 0xf: tap->wr_rate =  18; break;
> -             case 0x5: tap->wr_rate =  24; break;
> -             case 0x7: tap->wr_rate =  36; break;
> -             case 0x9: tap->wr_rate =  48; break;
> -             case 0xb: tap->wr_rate =  72; break;
> -             case 0x1: tap->wr_rate =  96; break;
> -             case 0x3: tap->wr_rate = 108; break;
> -             /* Unknown rate: should not happen. */
> -             default:  tap->wr_rate =   0;
> +             if (stat->rflags & IWN_RFLAG_MCS) {
> +                     tap->wr_rate = (0x80 | stat->rate); /* HT MCS index */
> +             } else {
> +                     switch (stat->rate) {
> +                     /* CCK rates. */
> +                     case  10: tap->wr_rate =   2; break;
> +                     case  20: tap->wr_rate =   4; break;
> +                     case  55: tap->wr_rate =  11; break;
> +                     case 110: tap->wr_rate =  22; break;
> +                     /* OFDM rates. */
> +                     case 0xd: tap->wr_rate =  12; break;
> +                     case 0xf: tap->wr_rate =  18; break;
> +                     case 0x5: tap->wr_rate =  24; break;
> +                     case 0x7: tap->wr_rate =  36; break;
> +                     case 0x9: tap->wr_rate =  48; break;
> +                     case 0xb: tap->wr_rate =  72; break;
> +                     case 0x1: tap->wr_rate =  96; break;
> +                     case 0x3: tap->wr_rate = 108; break;
> +                     /* Unknown rate: should not happen. */
> +                     default:  tap->wr_rate =  0;
> +                     }
>               }
>  
>               mb.m_data = (caddr_t)tap;
> @@ -2876,8 +2880,7 @@ iwn_tx(struct iwn_softc *sc, struct mbuf
>               if ((ni->ni_flags & IEEE80211_NODE_HT) &&
>                   !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
>                   type == IEEE80211_FC0_TYPE_DATA) {
> -                     /* XXX need a way to pass current MCS in 11n mode */
> -                     tap->wt_rate = 0;
> +                     tap->wt_rate = (0x80 | ni->ni_txmcs);
>               } else
>                       tap->wt_rate = rinfo->rate;
>               tap->wt_hwqueue = ac;
> Index: usr.sbin/tcpdump/print-802_11.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/tcpdump/print-802_11.c,v
> retrieving revision 1.33
> diff -u -p -r1.33 print-802_11.c
> --- usr.sbin/tcpdump/print-802_11.c   2 Sep 2016 17:11:46 -0000       1.33
> +++ usr.sbin/tcpdump/print-802_11.c   7 Oct 2016 12:44:25 -0000
> @@ -1075,8 +1075,13 @@ ieee802_11_radio_if_print(u_char *user, 
>  
>       if (RADIOTAP(RATE)) {
>               TCHECK2(*t, 1);
> -             if (vflag)
> -                     printf(", %uMbit/s", (*(u_int8_t*)t) / 2);
> +             if (vflag) {
> +                     uint8_t rate = *(u_int8_t*)t;
> +                     if (rate & 0x80)
> +                             printf(", MCS %u", rate & 0x7f);
> +                     else
> +                             printf(", %uMbit/s", rate / 2);
> +             }
>               t += 1;
>       }
>  
> 
> 

Reply via email to