summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2005-08-08 03:30:57 +0000
committersam <sam@FreeBSD.org>2005-08-08 03:30:57 +0000
commita71123cebfbc9af46b53dec14375534ae5c7076e (patch)
treeb61ffe07bac4a6b4eaff6820d88a3707be5fc831
parent3060bdb6720112effa149af05f489daf4dc779ff (diff)
downloadFreeBSD-src-a71123cebfbc9af46b53dec14375534ae5c7076e.zip
FreeBSD-src-a71123cebfbc9af46b53dec14375534ae5c7076e.tar.gz
Cleanup beacon/listen interval handling:
o separate configured beacon interval from listen interval; this avoids potential use of one value for the other (e.g. setting powersavesleep to 0 clobbers the beacon interval used in hostap or ibss mode) o bounds check the beacon interval received in probe response and beacon frames and drop frames with bogus settings; not clear if we should instead clamp the value as any alteration would result in mismatched sta+ap configuration and probably be more confusing (don't want to log to the console but perhaps ok with rate limiting) o while here up max beacon interval to reflect WiFi standard Noticed by: Martin <nakal@nurfuerspam.de> MFC after: 1 week
-rw-r--r--sys/dev/awi/awi.c2
-rw-r--r--sys/dev/ipw/if_ipw.c2
-rw-r--r--sys/dev/wi/if_wi.c2
-rw-r--r--sys/net80211/ieee80211.c8
-rw-r--r--sys/net80211/ieee80211_input.c16
-rw-r--r--sys/net80211/ieee80211_ioctl.c2
-rw-r--r--sys/net80211/ieee80211_ioctl.h3
-rw-r--r--sys/net80211/ieee80211_node.c4
-rw-r--r--sys/net80211/ieee80211_output.c6
-rw-r--r--sys/net80211/ieee80211_var.h4
10 files changed, 32 insertions, 17 deletions
diff --git a/sys/dev/awi/awi.c b/sys/dev/awi/awi.c
index 838e3fb..4e2aab1 100644
--- a/sys/dev/awi/awi.c
+++ b/sys/dev/awi/awi.c
@@ -660,7 +660,7 @@ awi_init(struct ifnet *ifp)
if (ic->ic_opmode == IEEE80211_M_AHDEMO ||
ic->ic_opmode == IEEE80211_M_HOSTAP) {
ni->ni_chan = ic->ic_ibss_chan;
- ni->ni_intval = ic->ic_lintval;
+ ni->ni_intval = ic->ic_bintval;
ni->ni_rssi = 0;
ni->ni_rstamp = 0;
memset(&ni->ni_tstamp, 0, sizeof(ni->ni_tstamp));
diff --git a/sys/dev/ipw/if_ipw.c b/sys/dev/ipw/if_ipw.c
index 60ec63f..75af5ac 100644
--- a/sys/dev/ipw/if_ipw.c
+++ b/sys/dev/ipw/if_ipw.c
@@ -2001,7 +2001,7 @@ ipw_config(struct ipw_softc *sc)
#endif
if (ic->ic_opmode == IEEE80211_M_IBSS) {
- data = htole32(ic->ic_lintval);
+ data = htole32(ic->ic_bintval);
DPRINTF(("Setting beacon interval to %u\n", le32toh(data)));
error = ipw_cmd(sc, IPW_CMD_SET_BEACON_INTERVAL, &data,
sizeof data);
diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c
index c80c939..bb545e6 100644
--- a/sys/dev/wi/if_wi.c
+++ b/sys/dev/wi/if_wi.c
@@ -739,7 +739,7 @@ wi_init(void *arg)
if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
sc->sc_firmware_type == WI_INTERSIL) {
- wi_write_val(sc, WI_RID_OWN_BEACON_INT, ic->ic_lintval);
+ wi_write_val(sc, WI_RID_OWN_BEACON_INT, ic->ic_bintval);
wi_write_val(sc, WI_RID_BASIC_RATE, 0x03); /* 1, 2 */
wi_write_val(sc, WI_RID_SUPPORT_RATE, 0x0f); /* 1, 2, 5.5, 11 */
wi_write_val(sc, WI_RID_DTIM_PERIOD, 1);
diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c
index ea75fa0..a34f875 100644
--- a/sys/net80211/ieee80211.c
+++ b/sys/net80211/ieee80211.c
@@ -182,12 +182,14 @@ ieee80211_ifattach(struct ieee80211com *ic)
#endif
(void) ieee80211_setmode(ic, ic->ic_curmode);
- if (ic->ic_lintval == 0)
- ic->ic_lintval = IEEE80211_BINTVAL_DEFAULT;
- ic->ic_bmisstimeout = 7*ic->ic_lintval; /* default 7 beacons */
+ if (ic->ic_bintval == 0)
+ ic->ic_bintval = IEEE80211_BINTVAL_DEFAULT;
+ ic->ic_bmisstimeout = 7*ic->ic_bintval; /* default 7 beacons */
ic->ic_dtim_period = IEEE80211_DTIM_DEFAULT;
IEEE80211_BEACON_LOCK_INIT(ic, "beacon");
+ if (ic->ic_lintval == 0)
+ ic->ic_lintval = ic->ic_bintval;
ic->ic_txpowlimit = IEEE80211_TXPOWER_MAX;
ieee80211_node_attach(ic);
diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c
index 808479d..8a6a499 100644
--- a/sys/net80211/ieee80211_input.c
+++ b/sys/net80211/ieee80211_input.c
@@ -1901,6 +1901,16 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
ic->ic_stats.is_rx_chanmismatch++;
return;
}
+ if (!(IEEE80211_BINTVAL_MIN <= bintval &&
+ bintval <= IEEE80211_BINTVAL_MAX)) {
+ IEEE80211_DISCARD(ic,
+ IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT,
+ wh, ieee80211_mgt_subtype_name[subtype >>
+ IEEE80211_FC0_SUBTYPE_SHIFT],
+ "bogus beacon interval", bintval);
+ ic->ic_stats.is_rx_badbintval++;
+ return;
+ }
/*
* Count frame now that we know it's to be processed.
@@ -2201,7 +2211,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: {
- u_int16_t capinfo, bintval;
+ u_int16_t capinfo, lintval;
struct ieee80211_rsnparms rsn;
u_int8_t reason;
@@ -2238,7 +2248,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
return;
}
capinfo = le16toh(*(u_int16_t *)frm); frm += 2;
- bintval = le16toh(*(u_int16_t *)frm); frm += 2;
+ lintval = le16toh(*(u_int16_t *)frm); frm += 2;
if (reassoc)
frm += 6; /* ignore current AP info */
ssid = rates = xrates = wpa = wme = NULL;
@@ -2366,7 +2376,7 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
}
ni->ni_rssi = rssi;
ni->ni_rstamp = rstamp;
- ni->ni_intval = bintval;
+ ni->ni_intval = lintval;
ni->ni_capinfo = capinfo;
ni->ni_chan = ic->ic_bss->ni_chan;
ni->ni_fhdwell = ic->ic_bss->ni_fhdwell;
diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c
index 3396934..61d8cc4 100644
--- a/sys/net80211/ieee80211_ioctl.c
+++ b/sys/net80211/ieee80211_ioctl.c
@@ -2317,7 +2317,7 @@ ieee80211_ioctl_set80211(struct ieee80211com *ic, u_long cmd, struct ieee80211re
return EINVAL;
if (IEEE80211_BINTVAL_MIN <= ireq->i_val &&
ireq->i_val <= IEEE80211_BINTVAL_MAX) {
- ic->ic_lintval = ireq->i_val;
+ ic->ic_bintval = ireq->i_val;
error = ENETRESET; /* requires restart */
} else
error = EINVAL;
diff --git a/sys/net80211/ieee80211_ioctl.h b/sys/net80211/ieee80211_ioctl.h
index 4c211fe..83ff118 100644
--- a/sys/net80211/ieee80211_ioctl.h
+++ b/sys/net80211/ieee80211_ioctl.h
@@ -180,7 +180,8 @@ struct ieee80211_stats {
u_int32_t is_ff_split; /* fast frame rx split error */
u_int32_t is_ff_decap; /* fast frames decap'd */
u_int32_t is_ff_encap; /* fast frames encap'd for tx */
- u_int32_t is_spare[10];
+ u_int32_t is_rx_badbintval; /* rx frame w/ bogus bintval */
+ u_int32_t is_spare[9];
};
/*
diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c
index 12ff342..ff8cfcd 100644
--- a/sys/net80211/ieee80211_node.c
+++ b/sys/net80211/ieee80211_node.c
@@ -389,7 +389,7 @@ ieee80211_create_ibss(struct ieee80211com* ic, struct ieee80211_channel *chan)
ni->ni_esslen = ic->ic_des_esslen;
memcpy(ni->ni_essid, ic->ic_des_essid, ni->ni_esslen);
copy_bss(ni, ic->ic_bss);
- ni->ni_intval = ic->ic_lintval;
+ ni->ni_intval = ic->ic_bintval;
if (ic->ic_flags & IEEE80211_F_PRIVACY)
ni->ni_capinfo |= IEEE80211_CAPINFO_PRIVACY;
if (ic->ic_phytype == IEEE80211_T_FH) {
@@ -441,7 +441,7 @@ ieee80211_reset_bss(struct ieee80211com *ic)
ic->ic_bss = ieee80211_ref_node(ni);
if (obss != NULL) {
copy_bss(ni, obss);
- ni->ni_intval = ic->ic_lintval;
+ ni->ni_intval = ic->ic_bintval;
ieee80211_free_node(obss);
}
}
diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c
index 78b62d0..85e610d 100644
--- a/sys/net80211/ieee80211_output.c
+++ b/sys/net80211/ieee80211_output.c
@@ -1686,13 +1686,13 @@ ieee80211_pwrsave(struct ieee80211com *ic, struct ieee80211_node *ni,
* using this information.
*/
/* XXX handle overflow? */
- age = ((ni->ni_intval * ic->ic_lintval) << 2) / 1024; /* TU -> secs */
+ age = ((ni->ni_intval * ic->ic_bintval) << 2) / 1024; /* TU -> secs */
_IEEE80211_NODE_SAVEQ_ENQUEUE(ni, m, qlen, age);
IEEE80211_NODE_SAVEQ_UNLOCK(ni);
IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
- "[%s] save frame, %u now queued\n",
- ether_sprintf(ni->ni_macaddr), qlen);
+ "[%s] save frame with age %d, %u now queued\n",
+ ether_sprintf(ni->ni_macaddr), age, qlen);
if (qlen == 1)
ic->ic_set_tim(ni, 1);
diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h
index e06673d..2ef0e54 100644
--- a/sys/net80211/ieee80211_var.h
+++ b/sys/net80211/ieee80211_var.h
@@ -65,7 +65,8 @@
#define IEEE80211_DTIM_MIN 1 /* min DTIM period */
#define IEEE80211_DTIM_DEFAULT 1 /* default DTIM period */
-#define IEEE80211_BINTVAL_MAX 500 /* max beacon interval (TU's) */
+/* NB: min+max come from WiFi requirements */
+#define IEEE80211_BINTVAL_MAX 1000 /* max beacon interval (TU's) */
#define IEEE80211_BINTVAL_MIN 25 /* min beacon interval (TU's) */
#define IEEE80211_BINTVAL_DEFAULT 100 /* default beacon interval (TU's) */
@@ -143,6 +144,7 @@ struct ieee80211com {
void (*ic_node_cleanup)(struct ieee80211_node *);
u_int8_t (*ic_node_getrssi)(const struct ieee80211_node*);
u_int16_t ic_lintval; /* listen interval */
+ u_int16_t ic_bintval; /* beacon interval */
u_int16_t ic_holdover; /* PM hold over duration */
u_int16_t ic_txmin; /* min tx retry count */
u_int16_t ic_txmax; /* max tx retry count */
OpenPOWER on IntegriCloud