Add BSSID filter for testing purposes
wpa_supplicant can now be configured to filter out scan results based on a BSSID filter. Space-separated set of allowed BSSIDs can be set with wpa_cli set bssid_filter command. Filtering mechanism can be disabled by setting this variable to an empty list. When set, only the BSSes that have a matching entry in this list will be accepted from scan results. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
b2ff168128
commit
d445a5cd8e
6 changed files with 94 additions and 0 deletions
|
@ -61,6 +61,8 @@ struct wpa_bss * wpa_bss_get(struct wpa_supplicant *wpa_s, const u8 *bssid,
|
||||||
const u8 *ssid, size_t ssid_len)
|
const u8 *ssid, size_t ssid_len)
|
||||||
{
|
{
|
||||||
struct wpa_bss *bss;
|
struct wpa_bss *bss;
|
||||||
|
if (!wpa_supplicant_filter_bssid_match(wpa_s, bssid))
|
||||||
|
return NULL;
|
||||||
dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
|
dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
|
||||||
if (os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0 &&
|
if (os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0 &&
|
||||||
bss->ssid_len == ssid_len &&
|
bss->ssid_len == ssid_len &&
|
||||||
|
@ -526,6 +528,8 @@ struct wpa_bss * wpa_bss_get_bssid(struct wpa_supplicant *wpa_s,
|
||||||
const u8 *bssid)
|
const u8 *bssid)
|
||||||
{
|
{
|
||||||
struct wpa_bss *bss;
|
struct wpa_bss *bss;
|
||||||
|
if (!wpa_supplicant_filter_bssid_match(wpa_s, bssid))
|
||||||
|
return NULL;
|
||||||
dl_list_for_each_reverse(bss, &wpa_s->bss, struct wpa_bss, list) {
|
dl_list_for_each_reverse(bss, &wpa_s->bss, struct wpa_bss, list) {
|
||||||
if (os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0)
|
if (os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0)
|
||||||
return bss;
|
return bss;
|
||||||
|
|
|
@ -114,6 +114,41 @@ static int pno_stop(struct wpa_supplicant *wpa_s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int set_bssid_filter(struct wpa_supplicant *wpa_s, char *val)
|
||||||
|
{
|
||||||
|
char *pos;
|
||||||
|
u8 addr[ETH_ALEN], *filter = NULL, *n;
|
||||||
|
size_t count = 0;
|
||||||
|
|
||||||
|
pos = val;
|
||||||
|
while (pos) {
|
||||||
|
if (*pos == '\0')
|
||||||
|
break;
|
||||||
|
if (hwaddr_aton(pos, addr))
|
||||||
|
return -1;
|
||||||
|
n = os_realloc(filter, (count + 1) * ETH_ALEN);
|
||||||
|
if (n == NULL) {
|
||||||
|
os_free(filter);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
filter = n;
|
||||||
|
os_memcpy(filter + count * ETH_ALEN, addr, ETH_ALEN);
|
||||||
|
count++;
|
||||||
|
|
||||||
|
pos = os_strchr(pos, ' ');
|
||||||
|
if (pos)
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpa_hexdump(MSG_DEBUG, "bssid_filter", filter, count * ETH_ALEN);
|
||||||
|
os_free(wpa_s->bssid_filter);
|
||||||
|
wpa_s->bssid_filter = filter;
|
||||||
|
wpa_s->bssid_filter_count = count;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
|
static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
|
||||||
char *cmd)
|
char *cmd)
|
||||||
{
|
{
|
||||||
|
@ -241,6 +276,8 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
|
||||||
}
|
}
|
||||||
} else if (os_strcasecmp(cmd, "ps") == 0) {
|
} else if (os_strcasecmp(cmd, "ps") == 0) {
|
||||||
ret = wpa_drv_set_p2p_powersave(wpa_s, atoi(value), -1, -1);
|
ret = wpa_drv_set_p2p_powersave(wpa_s, atoi(value), -1, -1);
|
||||||
|
} else if (os_strcasecmp(cmd, "bssid_filter") == 0) {
|
||||||
|
ret = set_bssid_filter(wpa_s, value);
|
||||||
} else {
|
} else {
|
||||||
value[-1] = '=';
|
value[-1] = '=';
|
||||||
ret = wpa_config_process_global(wpa_s->conf, cmd, -1);
|
ret = wpa_config_process_global(wpa_s->conf, cmd, -1);
|
||||||
|
|
|
@ -1235,6 +1235,50 @@ static void dump_scan_res(struct wpa_scan_results *scan_res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wpa_supplicant_filter_bssid_match(struct wpa_supplicant *wpa_s,
|
||||||
|
const u8 *bssid)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (wpa_s->bssid_filter == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
for (i = 0; i < wpa_s->bssid_filter_count; i++) {
|
||||||
|
if (os_memcmp(wpa_s->bssid_filter + i * ETH_ALEN, bssid,
|
||||||
|
ETH_ALEN) == 0)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void filter_scan_res(struct wpa_supplicant *wpa_s,
|
||||||
|
struct wpa_scan_results *res)
|
||||||
|
{
|
||||||
|
size_t i, j;
|
||||||
|
|
||||||
|
if (wpa_s->bssid_filter == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0, j = 0; i < res->num; i++) {
|
||||||
|
if (wpa_supplicant_filter_bssid_match(wpa_s,
|
||||||
|
res->res[i]->bssid)) {
|
||||||
|
res->res[j++] = res->res[i];
|
||||||
|
} else {
|
||||||
|
os_free(res->res[i]);
|
||||||
|
res->res[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res->num != j) {
|
||||||
|
wpa_printf(MSG_DEBUG, "Filtered out %d scan results",
|
||||||
|
(int) (res->num - j));
|
||||||
|
res->num = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wpa_supplicant_get_scan_results - Get scan results
|
* wpa_supplicant_get_scan_results - Get scan results
|
||||||
* @wpa_s: Pointer to wpa_supplicant data
|
* @wpa_s: Pointer to wpa_supplicant data
|
||||||
|
@ -1259,6 +1303,7 @@ wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s,
|
||||||
wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get scan results");
|
wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get scan results");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
filter_scan_res(wpa_s, scan_res);
|
||||||
|
|
||||||
#ifdef CONFIG_WPS
|
#ifdef CONFIG_WPS
|
||||||
if (wpas_wps_in_progress(wpa_s)) {
|
if (wpas_wps_in_progress(wpa_s)) {
|
||||||
|
|
|
@ -32,5 +32,7 @@ struct wpabuf * wpa_scan_get_vendor_ie_multi(const struct wpa_scan_res *res,
|
||||||
u32 vendor_type);
|
u32 vendor_type);
|
||||||
struct wpabuf * wpa_scan_get_vendor_ie_multi_beacon(
|
struct wpabuf * wpa_scan_get_vendor_ie_multi_beacon(
|
||||||
const struct wpa_scan_res *res, u32 vendor_type);
|
const struct wpa_scan_res *res, u32 vendor_type);
|
||||||
|
int wpa_supplicant_filter_bssid_match(struct wpa_supplicant *wpa_s,
|
||||||
|
const u8 *bssid);
|
||||||
|
|
||||||
#endif /* SCAN_H */
|
#endif /* SCAN_H */
|
||||||
|
|
|
@ -445,6 +445,9 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
|
||||||
wpa_s->gas = NULL;
|
wpa_s->gas = NULL;
|
||||||
|
|
||||||
free_hw_features(wpa_s);
|
free_hw_features(wpa_s);
|
||||||
|
|
||||||
|
os_free(wpa_s->bssid_filter);
|
||||||
|
wpa_s->bssid_filter = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -280,6 +280,9 @@ struct wpa_supplicant {
|
||||||
void *drv_priv; /* private data used by driver_ops */
|
void *drv_priv; /* private data used by driver_ops */
|
||||||
void *global_drv_priv;
|
void *global_drv_priv;
|
||||||
|
|
||||||
|
u8 *bssid_filter;
|
||||||
|
size_t bssid_filter_count;
|
||||||
|
|
||||||
/* previous scan was wildcard when interleaving between
|
/* previous scan was wildcard when interleaving between
|
||||||
* wildcard scans and specific SSID scan when max_ssids=1 */
|
* wildcard scans and specific SSID scan when max_ssids=1 */
|
||||||
int prev_scan_wildcard;
|
int prev_scan_wildcard;
|
||||||
|
|
Loading…
Reference in a new issue