1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-13 14:40:22 +00:00

Add support for the experimental radiotap capture format. With this

we no longer need the debugging code to dump packets.
This commit is contained in:
Sam Leffler 2003-09-05 22:22:49 +00:00
parent 95a22a9a71
commit 73454c7385
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=119783
3 changed files with 112 additions and 11 deletions

View File

@ -298,6 +298,21 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
/* complete initialization */
ieee80211_media_init(ifp, ath_media_change, ieee80211_media_status);
bpfattach2(ifp, DLT_IEEE802_11_RADIO,
sizeof(struct ieee80211_frame) + sizeof(sc->sc_tx_th),
&sc->sc_drvbpf);
/*
* Initialize constant fields.
*
* NB: the channel is setup each time we transition to the
* RUN state to avoid filling it in for each frame.
*/
sc->sc_tx_th.wt_ihdr.it_len = sizeof(sc->sc_tx_th);
sc->sc_tx_th.wt_ihdr.it_present = ATH_TX_RADIOTAP_PRESENT;
sc->sc_rx_th.wr_ihdr.it_len = sizeof(sc->sc_rx_th);
sc->sc_rx_th.wr_ihdr.it_present = ATH_RX_RADIOTAP_PRESENT;
if_printf(ifp, "802.11 address: %s\n", ether_sprintf(ic->ic_myaddr));
return 0;
@ -317,6 +332,7 @@ ath_detach(struct ath_softc *sc)
mtx_lock(&sc->sc_mtx);
ath_stop(ifp);
bpfdetach(ifp);
ath_desc_free(sc);
ath_hal_detach(sc->sc_ah);
ieee80211_ifdetach(ifp);
@ -732,6 +748,23 @@ ath_start(struct ifnet *ifp)
if (ic->ic_rawbpf)
bpf_mtap(ic->ic_rawbpf, m);
if (sc->sc_drvbpf) {
struct mbuf *mb;
MGETHDR(mb, M_DONTWAIT, m->m_type);
if (mb != NULL) {
sc->sc_tx_th.wt_rate =
ni->ni_rates.rs_rates[ni->ni_txrate];
mb->m_next = m;
mb->m_data = (caddr_t)&sc->sc_tx_th;
mb->m_len = sizeof(sc->sc_tx_th);
mb->m_pkthdr.len += mb->m_len;
bpf_mtap(sc->sc_drvbpf, mb);
m_free(mb);
}
}
/*
* TODO:
* The duration field of 802.11 header should be filled.
@ -739,12 +772,6 @@ ath_start(struct ifnet *ifp)
* doesn't know the detail of parameters such as IFS
* for now..
*/
if (IFF_DUMPPKTS(ifp))
ieee80211_dump_pkt(mtod(m, u_int8_t *), m->m_len,
ni->ni_rates.rs_rates[ni->ni_txrate] & IEEE80211_RATE_VAL,
-1);
if (ath_tx_start(sc, ni, bf, m)) {
bad:
mtx_lock(&sc->sc_txbuflock);
@ -1526,11 +1553,29 @@ ath_rx_proc(void *arg, int npending)
bf->bf_m = NULL;
m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = len;
if (IFF_DUMPPKTS(ifp)) {
ieee80211_dump_pkt(mtod(m, u_int8_t *), len,
sc->sc_hwmap[ds->ds_rxstat.rs_rate] &
IEEE80211_RATE_VAL,
ds->ds_rxstat.rs_rssi);
if (sc->sc_drvbpf) {
struct mbuf *mb;
/* XXX pre-allocate space when setting up recv's */
MGETHDR(mb, M_DONTWAIT, m->m_type);
if (mb != NULL) {
sc->sc_rx_th.wr_rate =
sc->sc_hwmap[ds->ds_rxstat.rs_rate];
sc->sc_rx_th.wr_antsignal =
ds->ds_rxstat.rs_rssi;
sc->sc_rx_th.wr_antenna =
ds->ds_rxstat.rs_antenna;
/* XXX TSF */
(void) m_dup_pkthdr(mb, m, M_DONTWAIT);
mb->m_next = m;
mb->m_data = (caddr_t)&sc->sc_rx_th;
mb->m_len = sizeof(sc->sc_rx_th);
mb->m_pkthdr.len += mb->m_len;
bpf_mtap(sc->sc_drvbpf, mb);
m_free(mb);
}
}
m_adj(m, -IEEE80211_CRC_LEN);
@ -2127,6 +2172,14 @@ ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan)
return EIO;
}
/*
* Update BPF state.
*/
sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
htole16(chan->ic_freq);
sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
htole16(chan->ic_flags);
/*
* Change channels and update the h/w rate map
* if we're switching; e.g. 11a to 11b/g.

View File

@ -91,4 +91,39 @@ struct ath_stats {
#define SIOCGATHSTATS _IOWR('i', 137, struct ifreq)
/*
* Radio capture format.
*/
#define ATH_RX_RADIOTAP_PRESENT ( \
(1 << IEEE80211_RADIOTAP_FLAGS) | \
(1 << IEEE80211_RADIOTAP_RATE) | \
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \
(1 << IEEE80211_RADIOTAP_ANTENNA) | \
0)
struct ath_rx_radiotap_header {
struct ieee80211_radiotap_header wr_ihdr;
u_int8_t wr_flags; /* XXX for padding */
u_int8_t wr_rate;
u_int16_t wr_chan_freq;
u_int16_t wr_chan_flags;
u_int8_t wr_antsignal;
u_int8_t wr_antenna;
};
#define ATH_TX_RADIOTAP_PRESENT ( \
(1 << IEEE80211_RADIOTAP_FLAGS) | \
(1 << IEEE80211_RADIOTAP_RATE) | \
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
0)
struct ath_tx_radiotap_header {
struct ieee80211_radiotap_header wt_ihdr;
u_int8_t wt_flags; /* XXX for padding */
u_int8_t wt_rate;
u_int16_t wt_chan_freq;
u_int16_t wt_chan_flags;
};
#endif /* _DEV_ATH_ATHIOCTL_H */

View File

@ -45,6 +45,7 @@
#include <sys/taskqueue.h>
#include <contrib/dev/ath/ah.h>
#include <net80211/ieee80211_radiotap.h>
#include <dev/ath/if_athioctl.h>
#define ATH_TIMEOUT 1000
@ -100,6 +101,16 @@ struct ath_softc {
u_int8_t sc_hwmap[32]; /* h/w rate ix to IEEE table */
HAL_INT sc_imask; /* interrupt mask copy */
struct bpf_if *sc_drvbpf;
union {
struct ath_tx_radiotap_header th;
u_int8_t pad[64];
} u_tx_rt;
union {
struct ath_rx_radiotap_header th;
u_int8_t pad[64];
} u_rx_rt;
struct ath_desc *sc_desc; /* TX/RX descriptors */
bus_dma_segment_t sc_dseg;
bus_dmamap_t sc_ddmamap; /* DMA map for descriptors */
@ -132,6 +143,8 @@ struct ath_softc {
struct callout sc_scan_ch; /* callout handle for scan */
struct ath_stats sc_stats; /* interface statistics */
};
#define sc_tx_th u_tx_rt.th
#define sc_rx_th u_rx_rt.th
int ath_attach(u_int16_t, struct ath_softc *);
int ath_detach(struct ath_softc *);