summaryrefslogtreecommitdiff
path: root/sys/dev/ic
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2006-10-01 22:03:26 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2006-10-01 22:03:26 +0000
commitb0001c059a4798c9f55e154b22ce74073e028512 (patch)
tree44ddbd8181d00952627e64c3ebba8217cd97b232 /sys/dev/ic
parentf8e9a4c928367cd52698663ca6f3ae739ef42378 (diff)
Make monitor mode work by prepending the right kind headers and fixing the
channel selection code. Joint work with mglocker@, OK mglocker@
Diffstat (limited to 'sys/dev/ic')
-rw-r--r--sys/dev/ic/pgt.c79
-rw-r--r--sys/dev/ic/pgtreg.h12
2 files changed, 61 insertions, 30 deletions
diff --git a/sys/dev/ic/pgt.c b/sys/dev/ic/pgt.c
index 38fca734bd0..856db67a74a 100644
--- a/sys/dev/ic/pgt.c
+++ b/sys/dev/ic/pgt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pgt.c,v 1.19 2006/10/01 21:49:08 claudio Exp $ */
+/* $OpenBSD: pgt.c,v 1.20 2006/10/01 22:03:25 claudio Exp $ */
/*
* Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org>
@@ -833,6 +833,12 @@ pgt_ieee80211_encap(struct pgt_softc *sc, struct ether_header *eh,
struct llc *snap;
ic = &sc->sc_ic;
+ if (ni != NULL && ic->ic_opmode == IEEE80211_M_MONITOR) {
+ *ni = ieee80211_ref_node(ic->ic_bss);
+ (*ni)->ni_inact = 0;
+ return (m);
+ }
+
M_PREPEND(m, sizeof(*frame) + sizeof(*snap), M_DONTWAIT);
if (m != NULL)
m = m_pullup(m, sizeof(*frame) + sizeof(*snap));
@@ -841,8 +847,7 @@ pgt_ieee80211_encap(struct pgt_softc *sc, struct ether_header *eh,
frame = mtod(m, struct ieee80211_frame *);
snap = (struct llc *)&frame[1];
if (ni != NULL) {
- if (ic->ic_opmode == IEEE80211_M_STA ||
- ic->ic_opmode == IEEE80211_M_MONITOR) {
+ if (ic->ic_opmode == IEEE80211_M_STA) {
*ni = ieee80211_ref_node(ic->ic_bss);
} else {
*ni = ieee80211_find_node(ic, eh->ether_shost);
@@ -900,9 +905,6 @@ pgt_ieee80211_encap(struct pgt_softc *sc, struct ether_header *eh,
IEEE80211_ADDR_COPY(frame->i_addr3, eh->ether_dhost);
break;
default:
- /*
- * What format do monitor-mode's frames take?
- */
break;
}
return (m);
@@ -917,6 +919,7 @@ pgt_input_frames(struct pgt_softc *sc, struct mbuf *m)
struct ieee80211_node *ni;
struct ieee80211com *ic;
struct pgt_rx_annex *pra;
+ struct pgt_rx_header *pha;
struct mbuf *next;
unsigned int n;
uint32_t rstamp;
@@ -928,6 +931,22 @@ pgt_input_frames(struct pgt_softc *sc, struct mbuf *m)
next = m->m_nextpkt;
m->m_nextpkt = NULL;
+ if (ic->ic_opmode == IEEE80211_M_MONITOR) {
+ if (m->m_len < sizeof(*pha)) {
+ m = m_pullup(m, sizeof(*pha));
+ if (m == NULL) {
+ if (sc->sc_debug & SC_DEBUG_UNEXPECTED)
+ printf("%s: m_pullup failure\n",
+ sc->sc_dev.dv_xname);
+ ifp->if_ierrors++;
+ continue;
+ }
+ }
+ pha = mtod(m, struct pgt_rx_header *);
+ pra = NULL;
+ goto input;
+ }
+
if (m->m_len < sizeof(*pra)) {
m = m_pullup(m, sizeof(*pra));
if (m == NULL) {
@@ -939,19 +958,19 @@ pgt_input_frames(struct pgt_softc *sc, struct mbuf *m)
}
}
pra = mtod(m, struct pgt_rx_annex *);
+ pha = &pra->pra_header;
if (sc->sc_debug & SC_DEBUG_RXANNEX)
- DPRINTF(("%s: rx annex: ? %04x ? %04x "
+ DPRINTF(("%s: rx annex: ? %04x "
"len %u clock %u flags %02x ? %02x rate %u ? %02x "
"freq %u ? %04x rssi %u pad %02x%02x%02x\n",
sc->sc_dev.dv_xname,
- letoh16(pdf.pdf_unknown),
- letoh16(pra->pra_unknown0),
- letoh16(pra->pra_length),
- letoh32(pra->pra_clock), pra->pra_flags,
- pra->pra_unknown1, pra->pra_rate,
- pra->pra_unknown2, letoh32(pra->pra_frequency),
- pra->pra_unknown3, pra->pra_rssi,
- pra->pra_pad[0], pra->pra_pad[1], pra->pra_pad[2]));
+ letoh16(pha->pra_unknown0),
+ letoh16(pha->pra_length),
+ letoh32(pha->pra_clock), pha->pra_flags,
+ pha->pra_unknown1, pha->pra_rate,
+ pha->pra_unknown2, letoh32(pha->pra_frequency),
+ pha->pra_unknown3, pha->pra_rssi,
+ pha->pra_pad[0], pha->pra_pad[1], pha->pra_pad[2]));
if (sc->sc_debug & SC_DEBUG_RXETHER)
DPRINTF(("%s: rx ether: "
"%02x:%02x:%02x:%02x:%02x:%02x < "
@@ -964,32 +983,40 @@ pgt_input_frames(struct pgt_softc *sc, struct mbuf *m)
pra->pra_ether_shost[2], pra->pra_ether_shost[3],
pra->pra_ether_shost[4], pra->pra_ether_shost[5],
ntohs(pra->pra_ether_type)));
+
+ memcpy(eh.ether_dhost, pra->pra_ether_dhost, ETHER_ADDR_LEN);
+ memcpy(eh.ether_shost, pra->pra_ether_shost, ETHER_ADDR_LEN);
+ eh.ether_type = pra->pra_ether_type;
+
+input:
/*
* This flag is set if e.g. packet could not be decrypted.
*/
- if (pra->pra_flags & PRA_FLAG_BAD) {
+ if (pha->pra_flags & PRA_FLAG_BAD) {
ifp->if_ierrors++;
m_freem(m);
continue;
}
- memcpy(eh.ether_dhost, pra->pra_ether_dhost, ETHER_ADDR_LEN);
- memcpy(eh.ether_shost, pra->pra_ether_shost, ETHER_ADDR_LEN);
- eh.ether_type = pra->pra_ether_type;
+
/*
* After getting what we want, chop off the annex, then
* turn into something that looks like it really was
* 802.11.
*/
- rssi = pra->pra_rssi;
- rstamp = letoh32(pra->pra_clock);
- rate = pra->pra_rate;
- n = ieee80211_mhz2ieee(letoh32(pra->pra_frequency), 0);
+ rssi = pha->pra_rssi;
+ rstamp = letoh32(pha->pra_clock);
+ rate = pha->pra_rate;
+ n = ieee80211_mhz2ieee(letoh32(pha->pra_frequency), 0);
if (n <= IEEE80211_CHAN_MAX)
chan = &ic->ic_channels[n];
else
chan = ic->ic_bss->ni_chan;
/* Send to 802.3 listeners. */
- m_adj(m, sizeof(*pra));
+ if (pra) {
+ m_adj(m, sizeof(*pra));
+ } else
+ m_adj(m, sizeof(*pha));
+
m = pgt_ieee80211_encap(sc, &eh, m, &ni);
if (m != NULL) {
#if NBPFILTER > 0
@@ -2963,7 +2990,7 @@ badopmode:
else
channel = 0;
} else
- channel = htole32(ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan));
+ channel = htole32(ieee80211_chan2ieee(ic, ic->ic_des_chan));
DPRINTF(("%s: set rates", sc->sc_dev.dv_xname));
for (i = 0; i < ic->ic_sup_rates[ic->ic_curmode].rs_nrates; i++) {
@@ -2991,7 +3018,7 @@ badopmode:
SETOID(PGT_OID_MODE, &mode, sizeof(mode));
SETOID(PGT_OID_BSS_TYPE, &bsstype, sizeof(bsstype));
- if (channel != 0 && channel != htole32(IEEE80211_CHAN_ANY))
+ if (channel != 0)
SETOID(PGT_OID_CHANNEL, &channel, sizeof(channel));
if (ic->ic_flags & IEEE80211_F_DESBSSID) {
diff --git a/sys/dev/ic/pgtreg.h b/sys/dev/ic/pgtreg.h
index 5f532dcb535..6055d81bf1e 100644
--- a/sys/dev/ic/pgtreg.h
+++ b/sys/dev/ic/pgtreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pgtreg.h,v 1.5 2006/10/01 21:49:08 claudio Exp $ */
+/* $OpenBSD: pgtreg.h,v 1.6 2006/10/01 22:03:25 claudio Exp $ */
/*
* Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org>
@@ -153,9 +153,7 @@ struct pgt_mgmt_frame {
/* data[]; */
} __attribute__((packed));
-struct pgt_rx_annex {
- uint8_t pra_ether_dhost[ETHER_ADDR_LEN];
- uint8_t pra_ether_shost[ETHER_ADDR_LEN];
+struct pgt_rx_header {
uint16_t pra_unknown0; /* always 0x0000 */
uint16_t pra_length; /* always 0x1400 */
uint32_t pra_clock; /* 1MHz timestamp */
@@ -168,6 +166,12 @@ struct pgt_rx_annex {
uint16_t pra_unknown3;
uint8_t pra_rssi;
uint8_t pra_pad[3];
+} __attribute__((packed));
+
+struct pgt_rx_annex {
+ uint8_t pra_ether_dhost[ETHER_ADDR_LEN];
+ uint8_t pra_ether_shost[ETHER_ADDR_LEN];
+ struct pgt_rx_header pra_header;
uint16_t pra_ether_type;
} __attribute__((packed));