mirror of
https://github.com/freebsd/freebsd-src
synced 2024-11-05 18:22:52 +00:00
o insure the current channel is in a good state before starting an AP scan
o reject scan requests for a device that isn't marked up This fixes a problem where requesting a scan before marking the device up would cause a panic because the current channel was set to "any" (0xffff).
This commit is contained in:
parent
f7bbe2c0f1
commit
93685685f4
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=122600
1 changed files with 44 additions and 13 deletions
|
@ -376,6 +376,43 @@ findrate(struct ieee80211com *ic, enum ieee80211_phymode mode, int rate)
|
|||
#undef IEEERATE
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare to do a user-initiated scan for AP's. If no
|
||||
* current/default channel is setup or the current channel
|
||||
* is invalid then pick the first available channel from
|
||||
* the active list as the place to start the scan.
|
||||
*/
|
||||
static int
|
||||
ieee80211_setupscan(struct ieee80211com *ic)
|
||||
{
|
||||
u_char *chanlist = ic->ic_chan_active;
|
||||
int i;
|
||||
|
||||
if (ic->ic_ibss_chan == NULL ||
|
||||
isclr(chanlist, ieee80211_chan2ieee(ic, ic->ic_ibss_chan))) {
|
||||
for (i = 0; i <= IEEE80211_CHAN_MAX; i++)
|
||||
if (isset(chanlist, i)) {
|
||||
ic->ic_ibss_chan = &ic->ic_channels[i];
|
||||
goto found;
|
||||
}
|
||||
return EINVAL; /* no active channels */
|
||||
found:
|
||||
;
|
||||
}
|
||||
if (ic->ic_bss->ni_chan == IEEE80211_CHAN_ANYC ||
|
||||
isclr(chanlist, ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan)))
|
||||
ic->ic_bss->ni_chan = ic->ic_ibss_chan;
|
||||
/*
|
||||
* XXX don't permit a scan to be started unless we
|
||||
* know the device is ready. For the moment this means
|
||||
* the device is marked up as this is the required to
|
||||
* initialize the hardware. It would be better to permit
|
||||
* scanning prior to being up but that'll require some
|
||||
* changes to the infrastructure.
|
||||
*/
|
||||
return (ic->ic_if.if_flags & IFF_UP) ? 0 : ENETRESET;
|
||||
}
|
||||
|
||||
int
|
||||
ieee80211_cfgset(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
{
|
||||
|
@ -659,8 +696,9 @@ ieee80211_cfgset(struct ifnet *ifp, u_long cmd, caddr_t data)
|
|||
case WI_RID_SCAN_REQ: /* XXX wicontrol */
|
||||
if (ic->ic_opmode == IEEE80211_M_HOSTAP)
|
||||
break;
|
||||
/* NB: ignore channel list and tx rate parameters */
|
||||
error = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
|
||||
error = ieee80211_setupscan(ic);
|
||||
if (error == 0)
|
||||
error = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
|
||||
break;
|
||||
case WI_RID_SCAN_APS:
|
||||
if (ic->ic_opmode == IEEE80211_M_HOSTAP)
|
||||
|
@ -692,18 +730,11 @@ ieee80211_cfgset(struct ifnet *ifp, u_long cmd, caddr_t data)
|
|||
}
|
||||
memcpy(ic->ic_chan_active, chanlist,
|
||||
sizeof(ic->ic_chan_active));
|
||||
if (isclr(chanlist, ieee80211_chan2ieee(ic, ic->ic_ibss_chan))) {
|
||||
for (i = 0; i <= IEEE80211_CHAN_MAX; i++)
|
||||
if (isset(chanlist, i)) {
|
||||
ic->ic_ibss_chan = &ic->ic_channels[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isclr(chanlist, ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan)))
|
||||
ic->ic_bss->ni_chan = ic->ic_ibss_chan;
|
||||
if (wreq.wi_type == WI_RID_CHANNEL_LIST)
|
||||
error = ieee80211_setupscan(ic);
|
||||
if (wreq.wi_type == WI_RID_CHANNEL_LIST) {
|
||||
/* NB: ignore error from ieee80211_setupscan */
|
||||
error = ENETRESET;
|
||||
else
|
||||
} else if (error == 0)
|
||||
error = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
|
||||
break;
|
||||
default:
|
||||
|
|
Loading…
Reference in a new issue