summaryrefslogtreecommitdiff
path: root/sys/dev/ic
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2006-01-30 11:41:01 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2006-01-30 11:41:01 +0000
commitba44403ff43dd599599373590bd054284fc5e216 (patch)
treea09c75dd84be2ee7d1813db9141cad6ddd7afb1e /sys/dev/ic
parente0f0bd7be5bb2f7473c5554b4013cb1d140e0d92 (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.c57
-rw-r--r--sys/dev/ic/anvar.h42
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);