[PATCH 2/2] wpa_supplicant: Check rate sets before joining BSS
Christian Lamparter
chunkeey
Wed Oct 19 04:09:34 PDT 2011
802.11-2007 7.3.2.2 demands that in order
to join a BSS all required rates have to
be supported by the hardware.
Signed-off-by: Christian Lamparter <chunkeey at googlemail.com>
---
wpa_supplicant/events.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 108 insertions(+), 0 deletions(-)
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 43b22ab..96896b4 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -477,6 +477,108 @@ static int freq_allowed(int *freqs, int freq)
}
+static int rate_match(struct wpa_supplicant *wpa_s, struct wpa_scan_res *bss)
+{
+ const struct hostapd_hw_modes *mode = NULL, *modes;
+ const u8 scan_ie[2] = { WLAN_EID_SUPP_RATES, WLAN_EID_EXT_SUPP_RATES };
+ const u8 *rate_ie;
+ int i, j, k, match = 0;
+
+ modes = wpa_s->hw.modes;
+ if (modes == NULL) {
+ /*
+ * The driver does not provide any additional information
+ * about the utilized hardware. But we don't fail in this
+ * event since accesspoints can also validate the stations
+ * supported rate set and deny the bss join request if it
+ * does not comply with the minimal required standard of
+ * the BSS.
+ */
+ return 1;
+ }
+
+ for (i = 0; i < wpa_s->hw.num_modes; i++) {
+ for (j = 0; j < modes[i].num_channels; j++) {
+ int freq = modes[i].channels[j].freq;
+ if (freq == bss->freq) {
+ mode = &modes[i];
+ break;
+ }
+ }
+ }
+
+ if (mode == NULL)
+ return 0;
+
+ for (i = 0; i < sizeof(scan_ie); i++) {
+ rate_ie = wpa_scan_get_ie(bss, scan_ie[i]);
+ if (rate_ie == NULL)
+ continue;
+
+ for (j = 2; j < rate_ie[1] + 2; j++) {
+ int flagged = !!(rate_ie[j] & 0x80);
+ int r = (rate_ie[j] & 0x7f) * 5;
+
+ /*
+ * 802.11n-2009 7.3.2.2
+ * The new BSS Membership selector value encoding
+ * is encoded like a legacy rate. But it is not
+ * a rate and only indicates if the BSS members
+ * are required to support the mandatory features
+ * of Clause 20 [HT PHY] in order to join the BSS.
+ */
+ if (flagged && ((rate_ie[j] & 0x7f) ==
+ BSS_MEMBERSHIP_SELECTOR_HT_PHY)) {
+ /*
+ * 802.11n-2009 20.1.1
+ *
+ * An HT non-AP STA shall support all EQM
+ * rates for one spatial stream.
+ */
+ if (mode->mcs_set[0] != 0xff) {
+ wpa_dbg(wpa_s, MSG_DEBUG, " hardware "
+ "does not support HT PHY");
+ return 0;
+ }
+ continue;
+ }
+
+ /* check for legacy [basic] rates */
+
+ /*
+ * Shortcut. We have already found a matching rate
+ * and this particular rate is not marked as basic.
+ * Therefore it's not necessary to support the rate
+ * and we can skip the expensive check.
+ */
+ if (match && !flagged)
+ continue;
+
+ for (k = 0; k < mode->num_rates; k++) {
+ if (mode->rates[k] == r) {
+ match = 1;
+ break;
+ }
+ }
+ if (flagged && (k == mode->num_rates)) {
+ /*
+ * 802.11-2007 7.3.2.2 demands that in
+ * order to join a BSS all required rates
+ * have to be supported by the hardware.
+ */
+ wpa_dbg(wpa_s, MSG_DEBUG, " hardware does not"
+ " support required rate %d.%d Mbit",
+ r / 10, r % 10);
+
+ match = 0;
+ break;
+ }
+ }
+ }
+ return match;
+}
+
+
static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
int i, struct wpa_scan_res *bss,
struct wpa_ssid *group)
@@ -609,6 +711,12 @@ static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
continue;
}
+ if (!rate_match(wpa_s, bss)) {
+ wpa_dbg(wpa_s, MSG_DEBUG, " skip - rate sets do "
+ "not match");
+ continue;
+ }
+
#ifdef CONFIG_P2P
/*
* TODO: skip the AP if its P2P IE has Group Formation
--
1.7.7
More information about the Hostap
mailing list