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
This commit is contained in:
Sam Leffler 2005-08-08 03:30:57 +00:00
parent 9c3fd40489
commit d365f9c760
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=148843
10 changed files with 32 additions and 17 deletions

View File

@ -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));

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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];
};
/*

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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 */