diff options
author | sam <sam@FreeBSD.org> | 2003-11-13 05:23:58 +0000 |
---|---|---|
committer | sam <sam@FreeBSD.org> | 2003-11-13 05:23:58 +0000 |
commit | 5bfac52170643473ecffbdd7b8bcdbf46cae0887 (patch) | |
tree | 41f67c7614385518fc015d7526a230fa7dc9436c /sys/net80211 | |
parent | 64b81ef0ad84feb9d95a8b5468c68d73e1babd6b (diff) | |
download | FreeBSD-src-5bfac52170643473ecffbdd7b8bcdbf46cae0887.zip FreeBSD-src-5bfac52170643473ecffbdd7b8bcdbf46cae0887.tar.gz |
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).
Diffstat (limited to 'sys/net80211')
-rw-r--r-- | sys/net80211/ieee80211_ioctl.c | 57 |
1 files changed, 44 insertions, 13 deletions
diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c index c6cfa7c..64a8879 100644 --- a/sys/net80211/ieee80211_ioctl.c +++ b/sys/net80211/ieee80211_ioctl.c @@ -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: |