diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2006-01-30 11:41:01 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2006-01-30 11:41:01 +0000 |
commit | ba44403ff43dd599599373590bd054284fc5e216 (patch) | |
tree | a09c75dd84be2ee7d1813db9141cad6ddd7afb1e /sys/dev/ic | |
parent | e0f0bd7be5bb2f7473c5554b4013cb1d140e0d92 (diff) |
Add basic radiotap support. Modelled somewhat after
ral and NetBSD wi radiotap.
"looks ok" damien@
Diffstat (limited to 'sys/dev/ic')
-rw-r--r-- | sys/dev/ic/an.c | 57 | ||||
-rw-r--r-- | sys/dev/ic/anvar.h | 42 |
2 files changed, 97 insertions, 2 deletions
diff --git a/sys/dev/ic/an.c b/sys/dev/ic/an.c index 23d22df9bad..f2429b4c042 100644 --- a/sys/dev/ic/an.c +++ b/sys/dev/ic/an.c @@ -1,4 +1,4 @@ -/* $OpenBSD: an.c,v 1.45 2006/01/09 21:19:47 jsg Exp $ */ +/* $OpenBSD: an.c,v 1.46 2006/01/30 11:41:00 jsg Exp $ */ /* $NetBSD: an.c,v 1.34 2005/06/20 02:49:18 atatat Exp $ */ /* * Copyright (c) 1997, 1998, 1999 @@ -110,6 +110,7 @@ #include <netinet/if_ether.h> #endif +#include <net80211/ieee80211_radiotap.h> #include <net80211/ieee80211_var.h> #if NBPFILTER > 0 @@ -317,6 +318,19 @@ an_attach(struct an_softc *sc) ieee80211_media_init(ifp, an_media_change, an_media_status); +#if NBPFILTER > 0 + bzero(&sc->sc_rxtapu, sizeof(sc->sc_rxtapu)); + sc->sc_rxtap.ar_ihdr.it_len = sizeof(sc->sc_rxtapu); + sc->sc_rxtap.ar_ihdr.it_present = AN_RX_RADIOTAP_PRESENT; + + bzero(&sc->sc_txtapu, sizeof(sc->sc_txtapu)); + sc->sc_txtap.at_ihdr.it_len = sizeof(sc->sc_txtapu); + sc->sc_txtap.at_ihdr.it_present = AN_TX_RADIOTAP_PRESENT; + + bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO, + sizeof(struct ieee80211_frame) + 64); +#endif + shutdownhook_establish(an_shutdown, sc); sc->sc_attached = 1; @@ -422,6 +436,26 @@ an_rxeof(struct an_softc *sc) m->m_pkthdr.rcvif = ifp; CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_RX); +#if NBPFILTER > 0 + if (sc->sc_drvbpf) { + struct mbuf mb; + struct an_rx_radiotap_header *tap = &sc->sc_rxtap; + + tap->ar_rate = frmhdr.an_rx_rate; + tap->ar_antsignal = frmhdr.an_rx_signal_strength; + tap->ar_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq); + tap->ar_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags); + + + M_DUP_PKTHDR(&mb, m); + mb.m_data = (caddr_t)tap; + mb.m_len = sizeof(sc->sc_rxtapu); + mb.m_next = m; + mb.m_pkthdr.len += mb.m_len; + bpf_mtap(sc->sc_drvbpf, &mb); + } +#endif /* NPBFILTER > 0 */ + wh = mtod(m, struct ieee80211_frame *); if (wh->i_fc[1] & IEEE80211_FC1_WEP) { /* @@ -1154,6 +1188,27 @@ an_start(struct ifnet *ifp) continue; } +#if NBPFILTER > 0 + if (sc->sc_drvbpf) { + struct mbuf mb; + struct an_tx_radiotap_header *tap = &sc->sc_txtap; + + tap->at_rate = + ic->ic_bss->ni_rates.rs_rates[ic->ic_bss->ni_txrate]; + tap->at_chan_freq = + htole16(ic->ic_bss->ni_chan->ic_freq); + tap->at_chan_flags = + htole16(ic->ic_bss->ni_chan->ic_flags); + + M_DUP_PKTHDR(&mb, m); + mb.m_data = (caddr_t)tap; + mb.m_len = sizeof(sc->sc_txtapu); + mb.m_next = m; + mb.m_pkthdr.len += mb.m_len; + bpf_mtap(sc->sc_drvbpf, m); + } +#endif + fid = sc->sc_txd[cur].d_fid; if (an_write_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr)) != 0) { ifp->if_oerrors++; diff --git a/sys/dev/ic/anvar.h b/sys/dev/ic/anvar.h index 6617c9a88fa..464f7d4a46e 100644 --- a/sys/dev/ic/anvar.h +++ b/sys/dev/ic/anvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: anvar.h,v 1.19 2006/01/09 21:19:47 jsg Exp $ */ +/* $OpenBSD: anvar.h,v 1.20 2006/01/30 11:41:00 jsg Exp $ */ /* $NetBSD: anvar.h,v 1.10 2005/02/27 00:27:00 perry Exp $ */ /* * Copyright (c) 1997, 1998, 1999 @@ -74,6 +74,33 @@ struct an_wepkey { #define AN_GAPLEN_MAX 8 +#define AN_RX_RADIOTAP_PRESENT ((1 << IEEE80211_RADIOTAP_FLAGS) | \ + (1 << IEEE80211_RADIOTAP_RATE) | \ + (1 << IEEE80211_RADIOTAP_CHANNEL) | \ + (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL)) + +struct an_rx_radiotap_header { + struct ieee80211_radiotap_header ar_ihdr; + u_int8_t ar_flags; + u_int8_t ar_rate; + u_int16_t ar_chan_freq; + u_int16_t ar_chan_flags; + int8_t ar_antsignal; +} __packed; + +#define AN_TX_RADIOTAP_PRESENT ((1 << IEEE80211_RADIOTAP_FLAGS) | \ + (1 << IEEE80211_RADIOTAP_RATE) | \ + (1 << IEEE80211_RADIOTAP_CHANNEL)) + +struct an_tx_radiotap_header { + struct ieee80211_radiotap_header at_ihdr; + u_int8_t at_flags; + u_int8_t at_rate; + u_int16_t at_chan_freq; + u_int16_t at_chan_flags; +} __packed; + + struct an_softc { struct device sc_dev; struct ieee80211com sc_ic; @@ -117,8 +144,21 @@ struct an_softc { struct an_rid_leapkey sc_leapkey; struct an_rid_encap sc_encap; } sc_buf; + + caddr_t sc_drvbpf; + union { + struct an_rx_radiotap_header tap; + u_int8_t pad[64]; + } sc_rxtapu; + union { + struct an_tx_radiotap_header tap; + u_int8_t pad[64]; + } sc_txtapu; }; +#define sc_rxtap sc_rxtapu.tap +#define sc_txtap sc_txtapu.tap + int an_attach(struct an_softc *); int an_detach(struct an_softc *); int an_activate(struct device *, enum devact); |