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

Reply via email to