summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/net80211/ieee80211.c2
-rw-r--r--sys/net80211/ieee80211_input.c16
-rw-r--r--sys/net80211/ieee80211_ioctl.c4
-rw-r--r--sys/net80211/ieee80211_node.c42
-rw-r--r--sys/net80211/ieee80211_node.h3
-rw-r--r--sys/net80211/ieee80211_proto.c41
-rw-r--r--sys/net80211/ieee80211_proto.h16
-rw-r--r--sys/net80211/ieee80211_var.h3
8 files changed, 70 insertions, 57 deletions
diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c
index 1e0db22..de56d17 100644
--- a/sys/net80211/ieee80211.c
+++ b/sys/net80211/ieee80211.c
@@ -558,7 +558,7 @@ ieee80211_watchdog(struct ifnet *ifp)
struct ieee80211com *ic = (void *)ifp;
if (ic->ic_mgt_timer && --ic->ic_mgt_timer == 0)
- ieee80211_new_state(ifp, IEEE80211_S_SCAN, -1);
+ ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
if (ic->ic_inact_timer && --ic->ic_inact_timer == 0)
ieee80211_timeout_nodes(ic);
diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c
index 2777ac9..dc4f462 100644
--- a/sys/net80211/ieee80211_input.c
+++ b/sys/net80211/ieee80211_input.c
@@ -592,7 +592,11 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, int subtype,
}
IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_SIZE);
IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN);
- if (chan > IEEE80211_CHAN_MAX || isclr(ic->ic_chan_active, chan)) {
+ if (
+#if IEEE80211_CHAN_MAX < 255
+ chan > IEEE80211_CHAN_MAX ||
+#endif
+ isclr(ic->ic_chan_active, chan)) {
IEEE80211_DPRINTF(("%s: ignore %s with invalid channel "
"%u\n", __func__,
ISPROBE(subtype) ? "probe response" : "beacon",
@@ -775,7 +779,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, int subtype,
case IEEE80211_M_IBSS:
if (ic->ic_state != IEEE80211_S_RUN || seq != 1)
return;
- ieee80211_new_state(&ic->ic_if, IEEE80211_S_AUTH,
+ ieee80211_new_state(ic, IEEE80211_S_AUTH,
wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
break;
@@ -822,7 +826,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, int subtype,
}
return;
}
- ieee80211_new_state(&ic->ic_if, IEEE80211_S_ASSOC,
+ ieee80211_new_state(ic, IEEE80211_S_ASSOC,
wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
break;
}
@@ -1011,7 +1015,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, int subtype,
IEEE80211_F_DOSORT | IEEE80211_F_DOFRATE |
IEEE80211_F_DONEGO | IEEE80211_F_DODEL);
if (ni->ni_rates.rs_nrates != 0)
- ieee80211_new_state(ifp, IEEE80211_S_RUN,
+ ieee80211_new_state(ic, IEEE80211_S_RUN,
wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
break;
}
@@ -1026,7 +1030,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, int subtype,
reason = le16toh(*(u_int16_t *)frm);
switch (ic->ic_opmode) {
case IEEE80211_M_STA:
- ieee80211_new_state(&ic->ic_if, IEEE80211_S_AUTH,
+ ieee80211_new_state(ic, IEEE80211_S_AUTH,
wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
break;
case IEEE80211_M_HOSTAP:
@@ -1055,7 +1059,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, int subtype,
reason = le16toh(*(u_int16_t *)frm);
switch (ic->ic_opmode) {
case IEEE80211_M_STA:
- ieee80211_new_state(&ic->ic_if, IEEE80211_S_ASSOC,
+ ieee80211_new_state(ic, IEEE80211_S_ASSOC,
wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
break;
case IEEE80211_M_HOSTAP:
diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c
index 46c015c..4ae0401 100644
--- a/sys/net80211/ieee80211_ioctl.c
+++ b/sys/net80211/ieee80211_ioctl.c
@@ -659,7 +659,7 @@ ieee80211_cfgset(struct ifnet *ifp, u_long cmd, caddr_t data)
if (ic->ic_opmode == IEEE80211_M_HOSTAP)
break;
/* NB: ignore channel list and tx rate parameters */
- error = ieee80211_new_state(ifp, IEEE80211_S_SCAN, -1);
+ error = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
break;
case WI_RID_SCAN_APS:
if (ic->ic_opmode == IEEE80211_M_HOSTAP)
@@ -703,7 +703,7 @@ ieee80211_cfgset(struct ifnet *ifp, u_long cmd, caddr_t data)
if (wreq.wi_type == WI_RID_CHANNEL_LIST)
error = ENETRESET;
else
- error = ieee80211_new_state(ifp, IEEE80211_S_SCAN, -1);
+ error = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
break;
default:
error = EINVAL;
diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c
index 9176ea7..a05c838 100644
--- a/sys/net80211/ieee80211_node.c
+++ b/sys/net80211/ieee80211_node.c
@@ -110,42 +110,48 @@ ieee80211_node_detach(struct ifnet *ifp)
* Initialize the active channel set based on the set
* of available channels and the current PHY mode.
*/
-void
+static void
ieee80211_reset_scan(struct ifnet *ifp)
{
struct ieee80211com *ic = (void *)ifp;
memcpy(ic->ic_chan_scan, ic->ic_chan_active,
sizeof(ic->ic_chan_active));
+ /* NB: hack, setup so next_scan starts with the first channel */
+ if (ic->ic_bss->ni_chan == IEEE80211_CHAN_ANYC)
+ ic->ic_bss->ni_chan = &ic->ic_channels[IEEE80211_CHAN_MAX];
}
/*
* Begin an active scan.
*/
void
-ieee80211_begin_scan(struct ifnet *ifp, struct ieee80211_node *ni)
+ieee80211_begin_scan(struct ifnet *ifp)
{
struct ieee80211com *ic = (void *)ifp;
+ /*
+ * In all but hostap mode scanning starts off in
+ * an active mode before switching to passive.
+ */
+ if (ic->ic_opmode != IEEE80211_M_HOSTAP)
+ ic->ic_flags |= IEEE80211_F_ASCAN;
if (ifp->if_flags & IFF_DEBUG)
if_printf(ifp, "begin %s scan\n",
- ic->ic_opmode != IEEE80211_M_HOSTAP ?
+ (ic->ic_flags & IEEE80211_F_ASCAN) ?
"active" : "passive");
-
- ieee80211_reset_scan(ifp);
/*
- * Flush any previously seen AP's. Note that this
- * assumes we don't act as both an AP and a station,
- * otherwise we'll potentially flush state of stations
- * associated with us.
+ * Clear scan state and flush any previously seen
+ * AP's. Note that the latter assumes we don't act
+ * as both an AP and a station, otherwise we'll
+ * potentially flush state of stations associated
+ * with us.
*/
+ ieee80211_reset_scan(ifp);
ieee80211_free_allnodes(ic);
- clrbit(ic->ic_chan_scan, ieee80211_chan2ieee(ic, ni->ni_chan));
- if (ic->ic_opmode != IEEE80211_M_HOSTAP) {
- ic->ic_flags |= IEEE80211_F_ASCAN;
- IEEE80211_SEND_MGMT(ic, ni, IEEE80211_FC0_SUBTYPE_PROBE_REQ, 0);
- }
+ /* Scan the next channel. */
+ ieee80211_next_scan(ifp);
}
/*
@@ -180,7 +186,7 @@ ieee80211_next_scan(struct ifnet *ifp)
ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan),
ieee80211_chan2ieee(ic, chan)));
ic->ic_bss->ni_chan = chan;
- ieee80211_new_state(ifp, IEEE80211_S_SCAN, -1);
+ ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
}
void
@@ -213,7 +219,7 @@ ieee80211_create_ibss(struct ieee80211com* ic, struct ieee80211_channel *chan)
ni->ni_fhdwell = 200; /* XXX */
ni->ni_fhindex = 1;
}
- ieee80211_new_state(ifp, IEEE80211_S_RUN, -1);
+ ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
}
/*
@@ -368,10 +374,10 @@ ieee80211_end_scan(struct ifnet *ifp)
goto notfound;
}
ieee80211_unref_node(&selbs);
- ieee80211_new_state(ifp, IEEE80211_S_RUN, -1);
+ ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
} else {
ieee80211_unref_node(&selbs);
- ieee80211_new_state(ifp, IEEE80211_S_AUTH, -1);
+ ieee80211_new_state(ic, IEEE80211_S_AUTH, -1);
}
}
diff --git a/sys/net80211/ieee80211_node.h b/sys/net80211/ieee80211_node.h
index 9085d47..49993b9 100644
--- a/sys/net80211/ieee80211_node.h
+++ b/sys/net80211/ieee80211_node.h
@@ -123,8 +123,7 @@ struct ieee80211com;
extern void ieee80211_node_attach(struct ifnet *);
extern void ieee80211_node_detach(struct ifnet *);
-extern void ieee80211_reset_scan(struct ifnet *);
-extern void ieee80211_begin_scan(struct ifnet *, struct ieee80211_node *);
+extern void ieee80211_begin_scan(struct ifnet *);
extern void ieee80211_next_scan(struct ifnet *);
extern void ieee80211_end_scan(struct ifnet *);
extern struct ieee80211_node *ieee80211_alloc_node(struct ieee80211com *,
diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c
index 7445dae..5520597 100644
--- a/sys/net80211/ieee80211_proto.c
+++ b/sys/net80211/ieee80211_proto.c
@@ -78,6 +78,15 @@ const char *ieee80211_mgt_subtype_name[] = {
"beacon", "atim", "disassoc", "auth",
"deauth", "reserved#13", "reserved#14", "reserved#15"
};
+const char *ieee80211_state_name[IEEE80211_S_MAX] = {
+ "INIT", /* IEEE80211_S_INIT */
+ "SCAN", /* IEEE80211_S_SCAN */
+ "AUTH", /* IEEE80211_S_AUTH */
+ "ASSOC", /* IEEE80211_S_ASSOC */
+ "RUN" /* IEEE80211_S_RUN */
+};
+
+static int ieee80211_newstate(struct ieee80211com *, enum ieee80211_state, int);
void
ieee80211_proto_attach(struct ifnet *ifp)
@@ -96,6 +105,9 @@ ieee80211_proto_attach(struct ifnet *ifp)
mtx_init(&ic->ic_mgtq.ifq_mtx, ifp->if_name, "mgmt send q", MTX_DEF);
+ /* protocol state change handler */
+ ic->ic_newstate = ieee80211_newstate;
+
/* initialize management frame handlers */
ic->ic_recv_mgmt = ieee80211_recv_mgmt;
ic->ic_send_mgmt = ieee80211_send_mgmt;
@@ -275,30 +287,17 @@ ieee80211_fix_rate(struct ieee80211com *ic, struct ieee80211_node *ni, int flags
#undef RV
}
-int
-ieee80211_new_state(struct ifnet *ifp, enum ieee80211_state nstate, int mgt)
+static int
+ieee80211_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int mgt)
{
- struct ieee80211com *ic = (void *)ifp;
+ struct ifnet *ifp = &ic->ic_if;
struct ieee80211_node *ni;
- int error, ostate;
-#ifdef IEEE80211_DEBUG
- static const char *stname[] =
- { "INIT", "SCAN", "AUTH", "ASSOC", "RUN" };
-#endif
+ enum ieee80211_state ostate;
ostate = ic->ic_state;
IEEE80211_DPRINTF(("%s: %s -> %s\n", __func__,
- stname[ostate], stname[nstate]));
- if (ic->ic_newstate) {
- error = (*ic->ic_newstate)(ic->ic_softc, nstate);
- if (error == EINPROGRESS)
- return 0;
- if (error != 0)
- return error;
- }
-
- /* state transition */
- ic->ic_state = nstate;
+ ieee80211_state_name[ostate], ieee80211_state_name[nstate]));
+ ic->ic_state = nstate; /* state transition */
ni = ic->ic_bss; /* NB: no reference held */
switch (nstate) {
case IEEE80211_S_INIT:
@@ -378,7 +377,7 @@ ieee80211_new_state(struct ifnet *ifp, enum ieee80211_state nstate, int mgt)
*/
ieee80211_create_ibss(ic, ic->ic_des_chan);
} else {
- ieee80211_begin_scan(ifp, ni);
+ ieee80211_begin_scan(ifp);
}
break;
case IEEE80211_S_SCAN:
@@ -406,7 +405,7 @@ ieee80211_new_state(struct ifnet *ifp, enum ieee80211_state nstate, int mgt)
ni->ni_fails++;
ieee80211_unref_node(&ni);
}
- ieee80211_begin_scan(ifp, ic->ic_bss);
+ ieee80211_begin_scan(ifp);
break;
}
break;
diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h
index 490e4ac..81627ff 100644
--- a/sys/net80211/ieee80211_proto.h
+++ b/sys/net80211/ieee80211_proto.h
@@ -39,12 +39,13 @@
*/
enum ieee80211_state {
- IEEE80211_S_INIT, /* default state */
- IEEE80211_S_SCAN, /* scanning */
- IEEE80211_S_AUTH, /* try to authenticate */
- IEEE80211_S_ASSOC, /* try to assoc */
- IEEE80211_S_RUN /* associated */
+ IEEE80211_S_INIT = 0, /* default state */
+ IEEE80211_S_SCAN = 1, /* scanning */
+ IEEE80211_S_AUTH = 2, /* try to authenticate */
+ IEEE80211_S_ASSOC = 3, /* try to assoc */
+ IEEE80211_S_RUN = 4, /* associated */
};
+#define IEEE80211_S_MAX (IEEE80211_S_RUN+1)
#define IEEE80211_SEND_MGMT(_ic,_ni,_type,_arg) \
((*(_ic)->ic_send_mgmt)(_ic, _ni, _type, _arg))
@@ -66,9 +67,12 @@ extern struct mbuf *ieee80211_encap(struct ifnet *, struct mbuf *);
extern struct mbuf *ieee80211_decap(struct ifnet *, struct mbuf *);
extern u_int8_t *ieee80211_add_rates(u_int8_t *frm,
const struct ieee80211_rateset *);
+#define ieee80211_new_state(_ic, _nstate, _arg) \
+ (((_ic)->ic_newstate)((_ic), (_nstate), (_arg)))
extern u_int8_t *ieee80211_add_xrates(u_int8_t *frm,
const struct ieee80211_rateset *);
-extern int ieee80211_new_state(struct ifnet *, enum ieee80211_state, int);
extern void ieee80211_print_essid(u_int8_t *, int);
extern void ieee80211_dump_pkt(u_int8_t *, int, int, int);
+
+extern const char *ieee80211_state_name[IEEE80211_S_MAX];
#endif /* _NET80211_IEEE80211_PROTO_H_ */
diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h
index 6956c37..2b2f0b0 100644
--- a/sys/net80211/ieee80211_var.h
+++ b/sys/net80211/ieee80211_var.h
@@ -137,7 +137,8 @@ struct ieee80211com {
struct mbuf *, int, int, u_int32_t, u_int);
int (*ic_send_mgmt)(struct ieee80211com *,
struct ieee80211_node *, int, int);
- int (*ic_newstate)(void *, enum ieee80211_state);
+ int (*ic_newstate)(struct ieee80211com *,
+ enum ieee80211_state, int);
void (*ic_newassoc)(struct ieee80211com *,
struct ieee80211_node *, int);
u_int8_t ic_myaddr[IEEE80211_ADDR_LEN];
OpenPOWER on IntegriCloud