From 097131fffe766b8e52cbbcfe201ed496cea6f297 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Mon, 6 Mar 2006 17:23:26 +0000 Subject: [PATCH] when scanning channels marked passive defer probe request until 802.11 traffic is seen; fixes problems with ap's hiding their ssid Obtained from: atheros MFC after: 1 week --- sys/net80211/ieee80211_input.c | 12 ++++++++++++ sys/net80211/ieee80211_node.c | 27 +++++++++++++++++++++++++++ sys/net80211/ieee80211_node.h | 1 + sys/net80211/ieee80211_proto.c | 16 ++++------------ sys/net80211/ieee80211_var.h | 1 + 5 files changed, 45 insertions(+), 12 deletions(-) diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c index 1c2fa869dc3e..965e3725611a 100644 --- a/sys/net80211/ieee80211_input.c +++ b/sys/net80211/ieee80211_input.c @@ -1953,6 +1953,18 @@ ieee80211_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, * If scanning, just pass information to the scan module. */ if (ic->ic_flags & IEEE80211_F_SCAN) { + if (ic->ic_flags_ext & IEEE80211_FEXT_PROBECHAN) { + /* + * Actively scanning a channel marked passive; + * send a probe request now that we know there + * is 802.11 traffic present. + * + * XXX check if the beacon we recv'd gives + * us what we need and suppress the probe req + */ + ieee80211_probe_curchan(ic, 1); + ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN; + } ieee80211_add_scan(ic, &scan, wh, subtype, rssi, rstamp); return; diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c index 9466d7387cff..3108dd5d117a 100644 --- a/sys/net80211/ieee80211_node.c +++ b/sys/net80211/ieee80211_node.c @@ -321,6 +321,7 @@ ieee80211_next_scan(struct ieee80211com *ic) * flushing anything queued in the driver and below. */ ic->ic_mgt_timer = 0; + ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN; chan = ic->ic_curchan; do { @@ -347,6 +348,31 @@ ieee80211_next_scan(struct ieee80211com *ic) return 0; } +/* + * Probe the curent channel, if allowed, while scanning. + * If the channel is not marked passive-only then send + * a probe request immediately. Otherwise mark state and + * listen for beacons on the channel; if we receive something + * then we'll transmit a probe request. + */ +void +ieee80211_probe_curchan(struct ieee80211com *ic, int force) +{ + struct ifnet *ifp = ic->ic_ifp; + + if ((ic->ic_curchan->ic_flags & IEEE80211_CHAN_PASSIVE) == 0 || force) { + /* + * XXX send both broadcast+directed probe request + */ + ieee80211_send_probereq(ic->ic_bss, + ic->ic_myaddr, ifp->if_broadcastaddr, + ifp->if_broadcastaddr, + ic->ic_des_essid, ic->ic_des_esslen, + ic->ic_opt_ie, ic->ic_opt_ie_len); + } else + ic->ic_flags_ext |= IEEE80211_FEXT_PROBECHAN; +} + static __inline void copy_bss(struct ieee80211_node *nbss, const struct ieee80211_node *obss) { @@ -596,6 +622,7 @@ ieee80211_cancel_scan(struct ieee80211com *ic) (ic->ic_flags & IEEE80211_F_ASCAN) ? "active" : "passive"); ic->ic_flags &= ~(IEEE80211_F_SCAN | IEEE80211_F_ASCAN); + ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN; } /* diff --git a/sys/net80211/ieee80211_node.h b/sys/net80211/ieee80211_node.h index 65acdc01283f..a86f582c6681 100644 --- a/sys/net80211/ieee80211_node.h +++ b/sys/net80211/ieee80211_node.h @@ -187,6 +187,7 @@ void ieee80211_node_unauthorize(struct ieee80211_node *); void ieee80211_begin_scan(struct ieee80211com *, int); int ieee80211_next_scan(struct ieee80211com *); +void ieee80211_probe_curchan(struct ieee80211com *, int); void ieee80211_create_ibss(struct ieee80211com*, struct ieee80211_channel *); void ieee80211_reset_bss(struct ieee80211com *); void ieee80211_cancel_scan(struct ieee80211com *); diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c index bb755ed08211..0e9b5818fb6a 100644 --- a/sys/net80211/ieee80211_proto.c +++ b/sys/net80211/ieee80211_proto.c @@ -978,19 +978,11 @@ ieee80211_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg break; case IEEE80211_S_SCAN: /* - * Scan next. If doing an active scan and the - * channel is not marked passive-only then send - * a probe request. Otherwise just listen for - * beacons on the channel. + * Scan next. If doing an active scan probe + * for the requested ap (if any). */ - if ((ic->ic_flags & IEEE80211_F_ASCAN) && - (ic->ic_curchan->ic_flags & IEEE80211_CHAN_PASSIVE) == 0) { - ieee80211_send_probereq(ni, - ic->ic_myaddr, ifp->if_broadcastaddr, - ifp->if_broadcastaddr, - ic->ic_des_essid, ic->ic_des_esslen, - ic->ic_opt_ie, ic->ic_opt_ie_len); - } + if (ic->ic_flags & IEEE80211_F_ASCAN) + ieee80211_probe_curchan(ic, 0); break; case IEEE80211_S_RUN: /* beacon miss */ diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h index 3bfce30ab636..7402801d77ad 100644 --- a/sys/net80211/ieee80211_var.h +++ b/sys/net80211/ieee80211_var.h @@ -254,6 +254,7 @@ struct ieee80211com { #define IEEE80211_FEXT_BGSCAN 0x00000008 /* STATUS: enable full bgscan completion */ #define IEEE80211_FEXT_ERPUPDATE 0x00000200 /* STATUS: update ERP element */ #define IEEE80211_FEXT_SWBMISS 0x00000400 /* CONF: do bmiss in s/w */ +#define IEEE80211_FEXT_PROBECHAN 0x00020000 /* CONF: probe passive channel*/ /* ic_caps */ #define IEEE80211_C_WEP 0x00000001 /* CAPABILITY: WEP available */