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.
This commit is contained in:
Jouni Malinen 2010-03-26 22:45:50 -07:00
parent 9fad706c68
commit b766a9a293
4 changed files with 97 additions and 11 deletions

View file

@ -917,9 +917,9 @@ static char * wpa_config_write_auth_alg(const struct parse_data *data,
#endif /* NO_CONFIG_WRITE */ #endif /* NO_CONFIG_WRITE */
static int wpa_config_parse_scan_freq(const struct parse_data *data, static int * wpa_config_parse_freqs(const struct parse_data *data,
struct wpa_ssid *ssid, int line, struct wpa_ssid *ssid, int line,
const char *value) const char *value)
{ {
int *freqs; int *freqs;
size_t used, len; size_t used, len;
@ -929,7 +929,7 @@ static int wpa_config_parse_scan_freq(const struct parse_data *data,
len = 10; len = 10;
freqs = os_zalloc((len + 1) * sizeof(int)); freqs = os_zalloc((len + 1) * sizeof(int));
if (freqs == NULL) if (freqs == NULL)
return -1; return NULL;
pos = value; pos = value;
while (pos) { 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)); n = os_realloc(freqs, (len * 2 + 1) * sizeof(int));
if (n == NULL) { if (n == NULL) {
os_free(freqs); os_free(freqs);
return -1; return NULL;
} }
for (i = len; i <= len * 2; i++) for (i = len; i <= len * 2; i++)
n[i] = 0; n[i] = 0;
@ -956,6 +956,19 @@ static int wpa_config_parse_scan_freq(const struct parse_data *data,
pos = os_strchr(pos + 1, ' '); 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); os_free(ssid->scan_freq);
ssid->scan_freq = freqs; 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 #ifndef NO_CONFIG_WRITE
static char * wpa_config_write_scan_freq(const struct parse_data *data, static char * wpa_config_write_freqs(const struct parse_data *data,
struct wpa_ssid *ssid) const int *freqs)
{ {
char *buf, *pos, *end; char *buf, *pos, *end;
int i, ret; int i, ret;
size_t count; size_t count;
if (ssid->scan_freq == NULL) if (freqs == NULL)
return NULL; return NULL;
count = 0; count = 0;
for (i = 0; ssid->scan_freq[i]; i++) for (i = 0; freqs[i]; i++)
count++; count++;
pos = buf = os_zalloc(10 * count + 1); 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; return NULL;
end = buf + 10 * count + 1; 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", ret = os_snprintf(pos, end - pos, "%s%u",
i == 0 ? "" : " ", ssid->scan_freq[i]); i == 0 ? "" : " ", freqs[i]);
if (ret < 0 || ret >= end - pos) { if (ret < 0 || ret >= end - pos) {
end[-1] = '\0'; end[-1] = '\0';
return buf; return buf;
@ -995,6 +1024,20 @@ static char * wpa_config_write_scan_freq(const struct parse_data *data,
return buf; 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 */ #endif /* NO_CONFIG_WRITE */
@ -1399,6 +1442,7 @@ static const struct parse_data ssid_fields[] = {
{ FUNC(group) }, { FUNC(group) },
{ FUNC(auth_alg) }, { FUNC(auth_alg) },
{ FUNC(scan_freq) }, { FUNC(scan_freq) },
{ FUNC(freq_list) },
#ifdef IEEE8021X_EAPOL #ifdef IEEE8021X_EAPOL
{ FUNC(eap) }, { FUNC(eap) },
{ STR_LENe(identity) }, { STR_LENe(identity) },
@ -1624,6 +1668,7 @@ void wpa_config_free_ssid(struct wpa_ssid *ssid)
#endif /* IEEE8021X_EAPOL */ #endif /* IEEE8021X_EAPOL */
os_free(ssid->id_str); os_free(ssid->id_str);
os_free(ssid->scan_freq); os_free(ssid->scan_freq);
os_free(ssid->freq_list);
os_free(ssid->bgscan); os_free(ssid->bgscan);
os_free(ssid); os_free(ssid);
} }

View file

@ -363,6 +363,16 @@ struct wpa_ssid {
* <bgscan module name>:<module parameters> * <bgscan module name>:<module parameters>
*/ */
char *bgscan; 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 */ #endif /* CONFIG_SSID_H */

View file

@ -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 * static struct wpa_bss *
wpa_supplicant_select_bss_wpa(struct wpa_supplicant *wpa_s, wpa_supplicant_select_bss_wpa(struct wpa_supplicant *wpa_s,
struct wpa_scan_results *scan_res, 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)) if (!wpa_supplicant_ssid_bss_match(wpa_s, ssid, bss))
continue; 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 " wpa_printf(MSG_DEBUG, " selected WPA AP "
MACSTR " ssid='%s'", MACSTR " ssid='%s'",
MAC2STR(bss->bssid), MAC2STR(bss->bssid),
@ -604,6 +624,12 @@ wpa_supplicant_select_bss_non_wpa(struct wpa_supplicant *wpa_s,
continue; 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 " wpa_printf(MSG_DEBUG, " selected non-WPA AP "
MACSTR " ssid='%s'", MACSTR " ssid='%s'",
MAC2STR(bss->bssid), MAC2STR(bss->bssid),

View file

@ -288,6 +288,11 @@ fast_reauth=1
# be used to optimize scanning to not occur on channels that the network does # be used to optimize scanning to not occur on channels that the network does
# not use. Example: scan_freq=2412 2437 2462 # 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 # proto: list of accepted protocols
# WPA = WPA/IEEE 802.11i/D3.0 # WPA = WPA/IEEE 802.11i/D3.0
# RSN = WPA2/IEEE 802.11i (also WPA2 can be used as an alias for RSN) # RSN = WPA2/IEEE 802.11i (also WPA2 can be used as an alias for RSN)