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 */
|
#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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue