aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2010-03-27 05:45:50 (GMT)
committerJouni Malinen <j@w1.fi>2010-03-27 05:45:50 (GMT)
commitb766a9a2938b555521b05eecb12685e73b29df1b (patch)
treece4ea8e77beef0a3752ff201e2a8fedf326189d4
parent9fad706c686dff097bcbffe3d335eb93f76ab135 (diff)
downloadhostap-b766a9a2938b555521b05eecb12685e73b29df1b.zip
hostap-b766a9a2938b555521b05eecb12685e73b29df1b.tar.gz
hostap-b766a9a2938b555521b05eecb12685e73b29df1b.tar.bz2
Add freq_list network configuration parameter
This can be used to limit which frequencies are considered when selecting a BSS. This is somewhat similar to scan_freq, but will also affect any scan results regardless of which program triggered the scan.
-rw-r--r--wpa_supplicant/config.c67
-rw-r--r--wpa_supplicant/config_ssid.h10
-rw-r--r--wpa_supplicant/events.c26
-rw-r--r--wpa_supplicant/wpa_supplicant.conf5
4 files changed, 97 insertions, 11 deletions
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 6aa8e9b..7e2a5b4 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -917,9 +917,9 @@ static char * wpa_config_write_auth_alg(const struct parse_data *data,
#endif /* NO_CONFIG_WRITE */
-static int wpa_config_parse_scan_freq(const struct parse_data *data,
- struct wpa_ssid *ssid, int line,
- const char *value)
+static int * wpa_config_parse_freqs(const struct parse_data *data,
+ struct wpa_ssid *ssid, int line,
+ const char *value)
{
int *freqs;
size_t used, len;
@@ -929,7 +929,7 @@ static int wpa_config_parse_scan_freq(const struct parse_data *data,
len = 10;
freqs = os_zalloc((len + 1) * sizeof(int));
if (freqs == NULL)
- return -1;
+ return NULL;
pos = value;
while (pos) {
@@ -941,7 +941,7 @@ static int wpa_config_parse_scan_freq(const struct parse_data *data,
n = os_realloc(freqs, (len * 2 + 1) * sizeof(int));
if (n == NULL) {
os_free(freqs);
- return -1;
+ return NULL;
}
for (i = len; i <= len * 2; i++)
n[i] = 0;
@@ -956,6 +956,19 @@ static int wpa_config_parse_scan_freq(const struct parse_data *data,
pos = os_strchr(pos + 1, ' ');
}
+ return freqs;
+}
+
+
+static int wpa_config_parse_scan_freq(const struct parse_data *data,
+ struct wpa_ssid *ssid, int line,
+ const char *value)
+{
+ int *freqs;
+
+ freqs = wpa_config_parse_freqs(data, ssid, line, value);
+ if (freqs == NULL)
+ return -1;
os_free(ssid->scan_freq);
ssid->scan_freq = freqs;
@@ -963,19 +976,35 @@ static int wpa_config_parse_scan_freq(const struct parse_data *data,
}
+static int wpa_config_parse_freq_list(const struct parse_data *data,
+ struct wpa_ssid *ssid, int line,
+ const char *value)
+{
+ int *freqs;
+
+ freqs = wpa_config_parse_freqs(data, ssid, line, value);
+ if (freqs == NULL)
+ return -1;
+ os_free(ssid->freq_list);
+ ssid->freq_list = freqs;
+
+ return 0;
+}
+
+
#ifndef NO_CONFIG_WRITE
-static char * wpa_config_write_scan_freq(const struct parse_data *data,
- struct wpa_ssid *ssid)
+static char * wpa_config_write_freqs(const struct parse_data *data,
+ const int *freqs)
{
char *buf, *pos, *end;
int i, ret;
size_t count;
- if (ssid->scan_freq == NULL)
+ if (freqs == NULL)
return NULL;
count = 0;
- for (i = 0; ssid->scan_freq[i]; i++)
+ for (i = 0; freqs[i]; i++)
count++;
pos = buf = os_zalloc(10 * count + 1);
@@ -983,9 +1012,9 @@ static char * wpa_config_write_scan_freq(const struct parse_data *data,
return NULL;
end = buf + 10 * count + 1;
- for (i = 0; ssid->scan_freq[i]; i++) {
+ for (i = 0; freqs[i]; i++) {
ret = os_snprintf(pos, end - pos, "%s%u",
- i == 0 ? "" : " ", ssid->scan_freq[i]);
+ i == 0 ? "" : " ", freqs[i]);
if (ret < 0 || ret >= end - pos) {
end[-1] = '\0';
return buf;
@@ -995,6 +1024,20 @@ static char * wpa_config_write_scan_freq(const struct parse_data *data,
return buf;
}
+
+
+static char * wpa_config_write_scan_freq(const struct parse_data *data,
+ struct wpa_ssid *ssid)
+{
+ return wpa_config_write_freqs(data, ssid->scan_freq);
+}
+
+
+static char * wpa_config_write_freq_list(const struct parse_data *data,
+ struct wpa_ssid *ssid)
+{
+ return wpa_config_write_freqs(data, ssid->freq_list);
+}
#endif /* NO_CONFIG_WRITE */
@@ -1399,6 +1442,7 @@ static const struct parse_data ssid_fields[] = {
{ FUNC(group) },
{ FUNC(auth_alg) },
{ FUNC(scan_freq) },
+ { FUNC(freq_list) },
#ifdef IEEE8021X_EAPOL
{ FUNC(eap) },
{ STR_LENe(identity) },
@@ -1624,6 +1668,7 @@ void wpa_config_free_ssid(struct wpa_ssid *ssid)
#endif /* IEEE8021X_EAPOL */
os_free(ssid->id_str);
os_free(ssid->scan_freq);
+ os_free(ssid->freq_list);
os_free(ssid->bgscan);
os_free(ssid);
}
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index 6056c9c..25e87aa 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -363,6 +363,16 @@ struct wpa_ssid {
* <bgscan module name>:<module parameters>
*/
char *bgscan;
+
+ /**
+ * freq_list - Array of allowed frequencies or %NULL for all
+ *
+ * This is an optional zero-terminated array of frequencies in
+ * megahertz (MHz) to allow for selecting the BSS. If set, scan results
+ * that do not match any of the specified frequencies are not
+ * considered when selecting a BSS.
+ */
+ int *freq_list;
};
#endif /* CONFIG_SSID_H */
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 3604454..70dccac 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -394,6 +394,20 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
}
+static int freq_allowed(int *freqs, int freq)
+{
+ int i;
+
+ if (freqs == NULL)
+ return 1;
+
+ for (i = 0; freqs[i]; i++)
+ if (freqs[i] == freq)
+ return 1;
+ return 0;
+}
+
+
static struct wpa_bss *
wpa_supplicant_select_bss_wpa(struct wpa_supplicant *wpa_s,
struct wpa_scan_results *scan_res,
@@ -477,6 +491,12 @@ wpa_supplicant_select_bss_wpa(struct wpa_supplicant *wpa_s,
if (!wpa_supplicant_ssid_bss_match(wpa_s, ssid, bss))
continue;
+ if (!freq_allowed(ssid->freq_list, bss->freq)) {
+ wpa_printf(MSG_DEBUG, " skip - "
+ "frequency not allowed");
+ continue;
+ }
+
wpa_printf(MSG_DEBUG, " selected WPA AP "
MACSTR " ssid='%s'",
MAC2STR(bss->bssid),
@@ -604,6 +624,12 @@ wpa_supplicant_select_bss_non_wpa(struct wpa_supplicant *wpa_s,
continue;
}
+ if (!freq_allowed(ssid->freq_list, bss->freq)) {
+ wpa_printf(MSG_DEBUG, " skip - "
+ "frequency not allowed");
+ continue;
+ }
+
wpa_printf(MSG_DEBUG, " selected non-WPA AP "
MACSTR " ssid='%s'",
MAC2STR(bss->bssid),
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index 39058d8..0cd5b02 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -288,6 +288,11 @@ fast_reauth=1
# be used to optimize scanning to not occur on channels that the network does
# not use. Example: scan_freq=2412 2437 2462
#
+# freq_list: Array of allowed frequencies
+# Space-separated list of frequencies in MHz to allow for selecting the BSS. If
+# set, scan results that do not match any of the specified frequencies are not
+# considered when selecting a BSS.
+#
# proto: list of accepted protocols
# WPA = WPA/IEEE 802.11i/D3.0
# RSN = WPA2/IEEE 802.11i (also WPA2 can be used as an alias for RSN)