On Sun, Dec 18, 2016 at 08:57:23AM +0100, Stefan Sperling wrote:
> Anybody?
>
> Did I write too much of a wall of text to explain the diff?
> In that case, just read the diff. It should make sense.
>
> On Sun, Dec 11, 2016 at 04:38:44PM +0100, Stefan Sperling wrote:
> > This diff makes 'tcpdump -i iwn0 -y IEEE802_11_RADIO' show the
> > correct mode for a channel in 11n mode.
> > Before:
> > <radiotap v0, chan 36, 11a, sig -46dBm, noise -91dBm>
> > After:
> > <radiotap v0, chan 36, 11n, sig -46dBm, noise -91dBm>
> >
> > Unfortunately this requires a kernel tweak because the kernel must
> > be more careful about the channel flags it passes to userland.
> >
> > Channels exist in the 11b/g (2GHz) and 11a (5GHz) ranges.
> > So net80211 has a "mode" concept, where a given mode is available
> > if supported channels exist in a particular range. And there is the
> > default "auto" mode which picks one of the other available modes.
> > (This may not be the best design but it is how it was designed
> > historically. Changing this is not in my radar.)
> >
> > The HT-channel flag is set to indicate whether a channel may be used
> > in 11n mode. In practice this is just the superset of all channels
> > supported by the device. When 11n support was introduced it was easier to
> > fold the new 11n mode into the existing code with a flag like this, and
> > avoid letting 11n mode be a special case which works against this design.
> >
> > And this HT-channel flag is set regardless of whether we're currently in
> > 11n mode because we need this flag to enter 11n mode from another mode.
> > A mode which has no channels available to it is not available.
> > So the kernel needs this flag to be set on all channels at all times
> > if the driver supports 11n.
> >
> > Now, we copy this flag out to userspace even in non-11n modes.
> > If the kernel instead omits the HT-channel flag from the userspace copy if
> > the current mode is not 11n, then tcpdump can inspect this flag to detect
> > whether the channel is in fact an "11n" channel and print the mode
> > correctly.
> >
> > In the end, this is just a cosmetic fix. If this is too much code
> > churn and quirks for too little gain, I am happy to drop this diff.
> >
> > Index: sys/dev/pci/if_iwm.c
> > ===================================================================
> > RCS file: /cvs/src/sys/dev/pci/if_iwm.c,v
> > retrieving revision 1.154
> > diff -u -p -r1.154 if_iwm.c
> > --- sys/dev/pci/if_iwm.c 10 Dec 2016 19:03:53 -0000 1.154
> > +++ sys/dev/pci/if_iwm.c 11 Dec 2016 14:54:58 -0000
> > @@ -3339,14 +3339,17 @@ iwm_rx_rx_mpdu(struct iwm_softc *sc, str
> > if (sc->sc_drvbpf != NULL) {
> > struct mbuf mb;
> > struct iwm_rx_radiotap_header *tap = &sc->sc_rxtap;
> > + uint16_t chan_flags;
> >
> > tap->wr_flags = 0;
> > if (phy_info->phy_flags & htole16(IWM_PHY_INFO_FLAG_SHPREAMBLE))
> > tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
> > tap->wr_chan_freq =
> > htole16(ic->ic_channels[phy_info->channel].ic_freq);
> > - tap->wr_chan_flags =
> > - htole16(ic->ic_channels[phy_info->channel].ic_flags);
> > + chan_flags = ic->ic_channels[phy_info->channel].ic_flags;
> > + if (ic->ic_curmode != IEEE80211_MODE_11N)
> > + chan_flags &= ~IEEE80211_CHAN_HT;
> > + tap->wr_chan_flags = htole16(chan_flags);
> > tap->wr_dbm_antsignal = (int8_t)rssi;
> > tap->wr_dbm_antnoise = (int8_t)sc->sc_noise;
> > tap->wr_tsft = phy_info->system_timestamp;
> > @@ -3991,10 +3994,14 @@ iwm_tx(struct iwm_softc *sc, struct mbuf
> > if (sc->sc_drvbpf != NULL) {
> > struct mbuf mb;
> > struct iwm_tx_radiotap_header *tap = &sc->sc_txtap;
> > + uint16_t chan_flags;
> >
> > tap->wt_flags = 0;
> > tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq);
> > - tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags);
> > + chan_flags = ni->ni_chan->ic_flags;
> > + if (ic->ic_curmode != IEEE80211_MODE_11N)
> > + chan_flags &= ~IEEE80211_CHAN_HT;
> > + tap->wt_chan_flags = htole16(chan_flags);
> > if ((ni->ni_flags & IEEE80211_NODE_HT) &&
> > !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
> > type == IEEE80211_FC0_TYPE_DATA &&
> > Index: sys/dev/pci/if_iwn.c
> > ===================================================================
> > RCS file: /cvs/src/sys/dev/pci/if_iwn.c,v
> > retrieving revision 1.178
> > diff -u -p -r1.178 if_iwn.c
> > --- sys/dev/pci/if_iwn.c 10 Dec 2016 13:22:07 -0000 1.178
> > +++ sys/dev/pci/if_iwn.c 11 Dec 2016 14:54:25 -0000
> > @@ -2130,14 +2130,17 @@ iwn_rx_done(struct iwn_softc *sc, struct
> > if (sc->sc_drvbpf != NULL) {
> > struct mbuf mb;
> > struct iwn_rx_radiotap_header *tap = &sc->sc_rxtap;
> > + uint16_t chan_flags;
> >
> > tap->wr_flags = 0;
> > if (stat->flags & htole16(IWN_STAT_FLAG_SHPREAMBLE))
> > tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
> > tap->wr_chan_freq =
> > htole16(ic->ic_channels[stat->chan].ic_freq);
> > - tap->wr_chan_flags =
> > - htole16(ic->ic_channels[stat->chan].ic_flags);
> > + chan_flags = ic->ic_channels[stat->chan].ic_flags;
> > + if (ic->ic_curmode != IEEE80211_MODE_11N)
> > + chan_flags &= ~IEEE80211_CHAN_HT;
> > + tap->wr_chan_flags = htole16(chan_flags);
> > tap->wr_dbm_antsignal = (int8_t)rssi;
> > tap->wr_dbm_antnoise = (int8_t)sc->noise;
> > tap->wr_tsft = stat->tstamp;
> > @@ -2908,10 +2911,14 @@ iwn_tx(struct iwn_softc *sc, struct mbuf
> > if (sc->sc_drvbpf != NULL) {
> > struct mbuf mb;
> > struct iwn_tx_radiotap_header *tap = &sc->sc_txtap;
> > + uint16_t chan_flags;
> >
> > tap->wt_flags = 0;
> > tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq);
> > - tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags);
> > + chan_flags = ni->ni_chan->ic_flags;
> > + if (ic->ic_curmode != IEEE80211_MODE_11N)
> > + chan_flags &= ~IEEE80211_CHAN_HT;
> > + tap->wt_chan_flags = htole16(chan_flags);
> > if ((ni->ni_flags & IEEE80211_NODE_HT) &&
> > !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
> > type == IEEE80211_FC0_TYPE_DATA) {
> > Index: sys/net80211/ieee80211_ioctl.c
> > ===================================================================
> > RCS file: /cvs/src/sys/net80211/ieee80211_ioctl.c,v
> > retrieving revision 1.44
> > diff -u -p -r1.44 ieee80211_ioctl.c
> > --- sys/net80211/ieee80211_ioctl.c 15 Sep 2016 03:32:48 -0000 1.44
> > +++ sys/net80211/ieee80211_ioctl.c 11 Dec 2016 14:56:03 -0000
> > @@ -71,6 +71,8 @@ ieee80211_node2req(struct ieee80211com *
> > /* Channel and rates */
> > nr->nr_channel = ieee80211_chan2ieee(ic, ni->ni_chan);
> > nr->nr_chan_flags = ni->ni_chan->ic_flags;
> > + if (ic->ic_curmode != IEEE80211_MODE_11N)
> > + nr->nr_chan_flags &= ~IEEE80211_CHAN_HT;
> > nr->nr_nrates = ni->ni_rates.rs_nrates;
> > bcopy(ni->ni_rates.rs_rates, nr->nr_rates, IEEE80211_RATE_MAXSIZE);
> >
> > Index: usr.sbin/tcpdump/print-802_11.c
> > ===================================================================
> > RCS file: /cvs/src/usr.sbin/tcpdump/print-802_11.c,v
> > retrieving revision 1.35
> > diff -u -p -r1.35 print-802_11.c
> > --- usr.sbin/tcpdump/print-802_11.c 19 Nov 2016 19:35:46 -0000 1.35
> > +++ usr.sbin/tcpdump/print-802_11.c 11 Dec 2016 14:18:05 -0000
> > @@ -1101,7 +1101,12 @@ ieee802_11_radio_if_print(u_char *user,
> >
> > printf(", chan %u", ieee80211_any2ieee(freq, flags));
> >
> > - if (flags & IEEE80211_CHAN_DYN &&
> > + if (flags & IEEE80211_CHAN_HT)
> > + printf(", 11n");
> > + else if (flags & IEEE80211_CHAN_DYN &&
> > + flags & IEEE80211_CHAN_2GHZ)
> > + printf(", 11g");
> > + else if (flags & IEEE80211_CHAN_DYN &&
> > flags & IEEE80211_CHAN_2GHZ)
> > printf(", 11g");
> > else if (flags & IEEE80211_CHAN_CCK &&
>
It seems that the 11g case is doubled up here. Apart from that OK claudio@
--
:wq Claudio