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:
parent
9fad706c68
commit
b766a9a293
4 changed files with 97 additions and 11 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue