[PATCH v2 2/3] Add network specific AP black- & whitelists

Stefan Tomanek stefan.tomanek at wertarbyte.de
Mon Jan 5 15:08:49 EST 2015


This change adds the configuration options "bssid_whitelist" and
"bssid_blacklist" sued to limit the AP selection of a network to a specified
(finite) set or discard certain APs.

This can be useful for environments where multiple networks operate using the
same ESSID and roaming between those is not desired.

It is also useful to ignore a faulty or otherwise unwanted AP.

Signed-off-by: Stefan Tomanek <stefan.tomanek at wertarbyte.de>
---
 wpa_supplicant/config.c            | 44 ++++++++++++++++++++++++++++++++++++++
 wpa_supplicant/config_ssid.h       | 12 +++++++++++
 wpa_supplicant/events.c            | 26 ++++++++++++++++++++++
 wpa_supplicant/wpa_supplicant.conf | 15 +++++++++++++
 4 files changed, 97 insertions(+)

diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 206195e..d712522 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -367,6 +367,48 @@ static char * wpa_config_write_bssid(const struct parse_data *data,
 #endif /* NO_CONFIG_WRITE */
 
 
+static int wpa_config_parse_bssid_blacklist(const struct parse_data *data,
+					    struct wpa_ssid *ssid, int line,
+					    const char *value) {
+	return wpa_config_parse_addr_list(data, line, value,
+	                                  &ssid->bssid_blacklist,
+	                                  &ssid->num_bssid_blacklist,
+	                                  "bssid_blacklist", 1);
+}
+
+#ifndef NO_CONFIG_WRITE
+static char * wpa_config_write_bssid_blacklist(const struct parse_data *data,
+					   struct wpa_ssid *ssid)
+{
+	return wpa_config_write_addr_list(data,
+	                                  ssid->bssid_blacklist,
+	                                  ssid->num_bssid_blacklist,
+	                                  "bssid_blacklist");
+}
+#endif /* NO_CONFIG_WRITE */
+
+
+static int wpa_config_parse_bssid_whitelist(const struct parse_data *data,
+					    struct wpa_ssid *ssid, int line,
+					    const char *value) {
+	return wpa_config_parse_addr_list(data, line, value,
+	                                  &ssid->bssid_whitelist,
+	                                  &ssid->num_bssid_whitelist,
+	                                  "bssid_whitelist", 1);
+}
+
+#ifndef NO_CONFIG_WRITE
+static char * wpa_config_write_bssid_whitelist(const struct parse_data *data,
+					   struct wpa_ssid *ssid)
+{
+	return wpa_config_write_addr_list(data,
+	                                  ssid->bssid_whitelist,
+	                                  ssid->num_bssid_whitelist,
+	                                  "bssid_whitelist");
+}
+#endif /* NO_CONFIG_WRITE */
+
+
 static int wpa_config_parse_psk(const struct parse_data *data,
 				struct wpa_ssid *ssid, int line,
 				const char *value)
@@ -1796,6 +1838,8 @@ static const struct parse_data ssid_fields[] = {
 	{ STR_RANGE(ssid, 0, MAX_SSID_LEN) },
 	{ INT_RANGE(scan_ssid, 0, 1) },
 	{ FUNC(bssid) },
+	{ FUNC(bssid_blacklist) },
+	{ FUNC(bssid_whitelist) },
 	{ FUNC_KEY(psk) },
 	{ FUNC(proto) },
 	{ FUNC(key_mgmt) },
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index c5cd6e7..2547741 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -133,6 +133,18 @@ struct wpa_ssid {
 	u8 bssid[ETH_ALEN];
 
 	/**
+	 * bssid_blacklist - list of inacceptable BSSIDs
+	 */
+	u8 *bssid_blacklist;
+	size_t num_bssid_blacklist;
+
+	/**
+	 * bssid_blacklist - list of acceptable BSSIDs
+	 */
+	u8 *bssid_whitelist;
+	size_t num_bssid_whitelist;
+
+	/**
 	 * bssid_set - Whether BSSID is configured for this network
 	 */
 	int bssid_set;
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 983c2ce..263b677 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -697,6 +697,16 @@ static int bss_is_ess(struct wpa_bss *bss)
 		IEEE80211_CAP_ESS);
 }
 
+static int addr_in_list(u8 *addr, u8 *list, size_t num) {
+	size_t i;
+	for (i = 0; i < num; i++) {
+		u8 *a = list + (i*ETH_ALEN);
+		if (os_memcmp(a, addr, ETH_ALEN) == 0) {
+			return 1;
+		}
+	}
+	return 0;
+}
 
 static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
 					    int i, struct wpa_bss *bss,
@@ -822,6 +832,22 @@ static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
 			continue;
 		}
 
+		/* check blacklist */
+		if (ssid->num_bssid_blacklist) {
+			if (addr_in_list(bss->bssid, ssid->bssid_blacklist, ssid->num_bssid_blacklist)) {
+				wpa_dbg(wpa_s, MSG_DEBUG, "   skip - BSSID blacklisted");
+				continue;
+			}
+		}
+
+		/* if there is a whitelist, only accept those APs */
+		if (ssid->num_bssid_whitelist) {
+			if (! addr_in_list(bss->bssid, ssid->bssid_whitelist, ssid->num_bssid_whitelist)) {
+				wpa_dbg(wpa_s, MSG_DEBUG, "   skip - BSSID not in whitelist");
+				continue;
+			}
+		}
+
 		if (!wpa_supplicant_ssid_bss_match(wpa_s, ssid, bss))
 			continue;
 
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index e78c0dd..a80bf21 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -1431,6 +1431,21 @@ network={
 	key_mgmt=NONE
 }
 
+# Example configuration blacklisting two APs - these will be ignored
+# for this network
+network={
+	ssid="example"
+	psk="very secret passphrase"
+	bssid_blacklist=ca:fe:ba:be:d0:0d de:ad:be:ef:00:00
+}
+
+# Example configuration limiting AP selection to a specific set of APs;
+# any other AP will be ignored for this network entry
+network={
+	ssid="example"
+	psk="very secret passphrase"
+	bssid_whitelist=ca:fe:ba:be:d0:0d de:ad:be:ef:00:00
+}
 
 # Example config file that will only scan on channel 36.
 freq_list=5180
-- 
2.1.3


More information about the HostAP mailing list