Accommodate the variety of RF front-ends when radiotapping frames:
tap only RSSI when there is a Philips RF front-end. Tap both Barker lock quality and RSSI when there is any other RF front-end. Provide radiotap listeners a more complete picture of channel activity: in promiscuous mode, tap frames who do not pass the CRC32 check. Flag packets that were received with a short preamble. Ask the NIC to pass us 802.11 Control frames. Pass frames to radiotap listeners before stripping the FCS. Re-order operations in rtw_intr_rx() in order to accomplish all of this, taking care not to pass a broken packet to net80211! Do not provide a flags field when tapping xmitted frames. Assert sane Rx packet lengths. Really should check and drop instead of KASSERTing. I will revisit this, soon. Update copyright.
This commit is contained in:
parent
223dc4f56f
commit
5c5f8f488c
@ -1,6 +1,7 @@
|
||||
/* $NetBSD: rtw.c,v 1.92 2007/11/15 22:55:50 dyoung Exp $ */
|
||||
/* $NetBSD: rtw.c,v 1.93 2007/11/16 23:35:19 dyoung Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2004, 2005 David Young. All rights reserved.
|
||||
* Copyright (c) 2004, 2005, 2006, 2007 David Young. All rights
|
||||
* reserved.
|
||||
*
|
||||
* Programmed for NetBSD by David Young.
|
||||
*
|
||||
@ -34,7 +35,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: rtw.c,v 1.92 2007/11/15 22:55:50 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: rtw.c,v 1.93 2007/11/16 23:35:19 dyoung Exp $");
|
||||
|
||||
#include "bpfilter.h"
|
||||
|
||||
@ -1450,7 +1451,7 @@ rtw_intr_rx(struct rtw_softc *sc, uint16_t isr)
|
||||
|
||||
for (next = rdb->rdb_next; ; next = rdb->rdb_next) {
|
||||
KASSERT(next < rdb->rdb_ndesc);
|
||||
|
||||
|
||||
rtw_rxdescs_sync(rdb, next, 1,
|
||||
BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
|
||||
rd = &rdb->rdb_desc[next];
|
||||
@ -1517,9 +1518,8 @@ rtw_intr_rx(struct rtw_softc *sc, uint16_t isr)
|
||||
sc->sc_ic.ic_stats.is_rx_tooshort++;
|
||||
goto next;
|
||||
}
|
||||
|
||||
/* CRC is included with the packet; trim it off. */
|
||||
len -= IEEE80211_CRC_LEN;
|
||||
KASSERT(len <= m->m_pkthdr.len);
|
||||
KASSERT(len <= m->m_len);
|
||||
|
||||
hwrate = __SHIFTOUT(hstat, RTW_RXSTAT_RATE_MASK);
|
||||
if (hwrate >= __arraycount(ratetbl)) {
|
||||
@ -1537,10 +1537,6 @@ rtw_intr_rx(struct rtw_softc *sc, uint16_t isr)
|
||||
(rate * 5) % 10, htsfth, htsftl));
|
||||
#endif /* RTW_DEBUG */
|
||||
|
||||
if ((hstat & RTW_RXSTAT_RES) != 0 &&
|
||||
sc->sc_ic.ic_opmode != IEEE80211_M_MONITOR)
|
||||
goto next;
|
||||
|
||||
/* if bad flags, skip descriptor */
|
||||
if ((hstat & RTW_RXSTAT_ONESEG) != RTW_RXSTAT_ONESEG) {
|
||||
printf("%s: too many rx segments, "
|
||||
@ -1568,8 +1564,10 @@ rtw_intr_rx(struct rtw_softc *sc, uint16_t isr)
|
||||
sc->sc_dev.dv_xname);
|
||||
}
|
||||
|
||||
sq = __SHIFTOUT(hrssi, RTW_RXRSSI_SQ);
|
||||
|
||||
if (sc->sc_rfchipid == RTW_RFCHIPID_PHILIPS)
|
||||
rssi = __SHIFTOUT(hrssi, RTW_RXRSSI_RSSI);
|
||||
rssi = UINT8_MAX - sq;
|
||||
else {
|
||||
rssi = __SHIFTOUT(hrssi, RTW_RXRSSI_IMR_RSSI);
|
||||
/* TBD find out each front-end's LNA gain in the
|
||||
@ -1578,7 +1576,6 @@ rtw_intr_rx(struct rtw_softc *sc, uint16_t isr)
|
||||
if ((hrssi & RTW_RXRSSI_IMR_LNA) == 0)
|
||||
rssi |= 0x80;
|
||||
}
|
||||
sq = __SHIFTOUT(hrssi, RTW_RXRSSI_SQ);
|
||||
|
||||
/* Note well: now we cannot recycle the rs_mbuf unless
|
||||
* we restore its original length.
|
||||
@ -1590,8 +1587,6 @@ rtw_intr_rx(struct rtw_softc *sc, uint16_t isr)
|
||||
|
||||
if (!IS_BEACON(wh->i_fc[0]))
|
||||
sc->sc_led_state.ls_event |= RTW_LED_S_RX;
|
||||
/* TBD use _MAR, _BAR, _PAR flags as hints to _find_rxnode? */
|
||||
ni = ieee80211_find_rxnode(&sc->sc_ic, wh);
|
||||
|
||||
sc->sc_tsfth = htsfth;
|
||||
|
||||
@ -1610,19 +1605,38 @@ rtw_intr_rx(struct rtw_softc *sc, uint16_t isr)
|
||||
rr->rr_tsft =
|
||||
htole64(((uint64_t)htsfth << 32) | htsftl);
|
||||
|
||||
rr->rr_flags = IEEE80211_RADIOTAP_F_FCS;
|
||||
|
||||
if ((hstat & RTW_RXSTAT_SPLCP) != 0)
|
||||
rr->rr_flags = IEEE80211_RADIOTAP_F_SHORTPRE;
|
||||
rr->rr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
|
||||
if ((hstat & RTW_RXSTAT_CRC32) != 0)
|
||||
rr->rr_flags |= IEEE80211_RADIOTAP_F_BADFCS;
|
||||
|
||||
rr->rr_flags = 0;
|
||||
rr->rr_rate = rate;
|
||||
rr->rr_antsignal = rssi;
|
||||
rr->rr_barker_lock = htole16(sq);
|
||||
|
||||
bpf_mtap2(sc->sc_radiobpf, (void *)rr,
|
||||
if (sc->sc_rfchipid == RTW_RFCHIPID_PHILIPS)
|
||||
rr->rr_u.u_philips.p_antsignal = rssi;
|
||||
else {
|
||||
rr->rr_u.u_other.o_antsignal = rssi;
|
||||
rr->rr_u.u_other.o_barker_lock =
|
||||
htole16(UINT8_MAX - sq);
|
||||
}
|
||||
|
||||
bpf_mtap2(sc->sc_radiobpf, rr,
|
||||
sizeof(sc->sc_rxtapu), m);
|
||||
}
|
||||
#endif /* NBPFILTER > 0 */
|
||||
|
||||
if ((hstat & RTW_RXSTAT_RES) != 0) {
|
||||
m_freem(m);
|
||||
goto next;
|
||||
}
|
||||
|
||||
/* CRC is included with the packet; trim it off. */
|
||||
m_adj(m, -IEEE80211_CRC_LEN);
|
||||
|
||||
/* TBD use _MAR, _BAR, _PAR flags as hints to _find_rxnode? */
|
||||
ni = ieee80211_find_rxnode(&sc->sc_ic, wh);
|
||||
ieee80211_input(&sc->sc_ic, m, ni, rssi, htsftl);
|
||||
ieee80211_free_node(ni);
|
||||
next:
|
||||
@ -2626,6 +2640,8 @@ rtw_pktfilt_load(struct rtw_softc *sc)
|
||||
|
||||
if (ifp->if_flags & IFF_PROMISC) {
|
||||
sc->sc_rcr |= RTW_RCR_AB; /* accept all broadcast */
|
||||
sc->sc_rcr |= RTW_RCR_ACRC32; /* accept frames failing CRC */
|
||||
sc->sc_rcr |= RTW_RCR_AICV; /* accept frames failing ICV */
|
||||
ifp->if_flags |= IFF_ALLMULTI;
|
||||
}
|
||||
|
||||
@ -3332,7 +3348,6 @@ rtw_start(struct ifnet *ifp)
|
||||
if (sc->sc_radiobpf != NULL) {
|
||||
struct rtw_tx_radiotap_header *rt = &sc->sc_txtap;
|
||||
|
||||
rt->rt_flags = 0;
|
||||
rt->rt_rate = rate;
|
||||
|
||||
bpf_mtap2(sc->sc_radiobpf, (void *)rt,
|
||||
@ -3816,9 +3831,16 @@ rtw_disestablish_hooks(struct rtw_hooks *hooks, const char *dvname,
|
||||
static inline void
|
||||
rtw_init_radiotap(struct rtw_softc *sc)
|
||||
{
|
||||
uint32_t present;
|
||||
|
||||
memset(&sc->sc_rxtapu, 0, sizeof(sc->sc_rxtapu));
|
||||
sc->sc_rxtap.rr_ihdr.it_len = htole16(sizeof(sc->sc_rxtapu));
|
||||
sc->sc_rxtap.rr_ihdr.it_present = htole32(RTW_RX_RADIOTAP_PRESENT);
|
||||
|
||||
if (sc->sc_rfchipid == RTW_RFCHIPID_PHILIPS)
|
||||
present = htole32(RTW_PHILIPS_RX_RADIOTAP_PRESENT);
|
||||
else
|
||||
present = htole32(RTW_RX_RADIOTAP_PRESENT);
|
||||
sc->sc_rxtap.rr_ihdr.it_present = present;
|
||||
|
||||
memset(&sc->sc_txtapu, 0, sizeof(sc->sc_txtapu));
|
||||
sc->sc_txtap.rt_ihdr.it_len = htole16(sizeof(sc->sc_txtapu));
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rtwreg.h,v 1.23 2007/01/06 08:27:53 dyoung Exp $ */
|
||||
/* $NetBSD: rtwreg.h,v 1.24 2007/11/16 23:35:19 dyoung Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2004, 2005 David Young. All rights reserved.
|
||||
*
|
||||
@ -283,6 +283,7 @@
|
||||
|
||||
/* Receive power-management frames and mgmt/ctrl/data frames. */
|
||||
#define RTW_RCR_PKTFILTER_DEFAULT ( \
|
||||
RTW_RCR_ACF | \
|
||||
RTW_RCR_ADF | \
|
||||
RTW_RCR_AMF | \
|
||||
RTW_RCR_APM | \
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rtwvar.h,v 1.31 2007/03/04 06:02:01 christos Exp $ */
|
||||
/* $NetBSD: rtwvar.h,v 1.32 2007/11/16 23:35:19 dyoung Exp $ */
|
||||
/*-
|
||||
* Copyright (c) 2004, 2005 David Young. All rights reserved.
|
||||
*
|
||||
@ -236,27 +236,41 @@ struct rtw_descs {
|
||||
(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \
|
||||
0)
|
||||
|
||||
#define RTW_PHILIPS_RX_RADIOTAP_PRESENT \
|
||||
((1 << IEEE80211_RADIOTAP_TSFT) | \
|
||||
(1 << IEEE80211_RADIOTAP_FLAGS) | \
|
||||
(1 << IEEE80211_RADIOTAP_RATE) | \
|
||||
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
||||
(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \
|
||||
0)
|
||||
|
||||
struct rtw_rx_radiotap_header {
|
||||
struct ieee80211_radiotap_header rr_ihdr;
|
||||
uint64_t rr_tsft;
|
||||
uint8_t rr_flags;
|
||||
uint8_t rr_rate;
|
||||
uint8_t rr_flags;
|
||||
uint8_t rr_rate;
|
||||
uint16_t rr_chan_freq;
|
||||
uint16_t rr_chan_flags;
|
||||
uint16_t rr_barker_lock;
|
||||
uint8_t rr_antsignal;
|
||||
union {
|
||||
struct {
|
||||
uint16_t o_barker_lock;
|
||||
uint8_t o_antsignal;
|
||||
} u_other;
|
||||
struct {
|
||||
uint8_t p_antsignal;
|
||||
} u_philips;
|
||||
} rr_u;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#define RTW_TX_RADIOTAP_PRESENT \
|
||||
((1 << IEEE80211_RADIOTAP_FLAGS) | \
|
||||
(1 << IEEE80211_RADIOTAP_RATE) | \
|
||||
((1 << IEEE80211_RADIOTAP_RATE) | \
|
||||
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
||||
0)
|
||||
|
||||
struct rtw_tx_radiotap_header {
|
||||
struct ieee80211_radiotap_header rt_ihdr;
|
||||
uint8_t rt_flags;
|
||||
uint8_t rt_rate;
|
||||
uint8_t rt_rate;
|
||||
uint8_t rt_pad;
|
||||
uint16_t rt_chan_freq;
|
||||
uint16_t rt_chan_flags;
|
||||
} __attribute__((__packed__));
|
||||
|
Loading…
Reference in New Issue
Block a user