]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Add network specific BSSID black and white lists
authorStefan Tomanek <stefan.tomanek@wertarbyte.de>
Mon, 5 Jan 2015 20:08:49 +0000 (21:08 +0100)
committerJouni Malinen <j@w1.fi>
Sat, 10 Jan 2015 15:35:53 +0000 (17:35 +0200)
This change adds the configuration options "bssid_whitelist" and
"bssid_blacklist" used 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 SSID 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@wertarbyte.de>
wpa_supplicant/config.c
wpa_supplicant/config_ssid.h
wpa_supplicant/events.c
wpa_supplicant/wpa_supplicant.conf

index e0703573747a2e8d3e53b1e06b7d1fe105f43289..8925705a3c91075d5ec10b5075bf745b82b4e216 100644 (file)
@@ -368,6 +368,50 @@ 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)
@@ -1744,6 +1788,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) },
index 18ce67fc9975c3e9baf4d4b610c59d405c982eeb..f744895a3a6c389ba20035c6e52ec3a8f7df5d90 100644 (file)
@@ -131,6 +131,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
         */
index 7f90393fae1d35a5aefc6b909a9093d6aa3cb95e..4dd9bc6112fa35087a4915a6de0710581dbb33f4 100644 (file)
@@ -698,6 +698,20 @@ static int bss_is_ess(struct wpa_bss *bss)
 }
 
 
+static int addr_in_list(const u8 *addr, const u8 *list, size_t num)
+{
+       size_t i;
+
+       for (i = 0; i < num; i++) {
+               const 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,
                                            struct wpa_ssid *group,
@@ -822,6 +836,24 @@ static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
                        continue;
                }
 
+               /* check blacklist */
+               if (ssid->num_bssid_blacklist &&
+                   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 &&
+                   !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;
 
index e78c0dd99d7e4bdbcf229ab424e9f1a27bfce07a..4b2c3cc0e5bf3978c0724eb2da87ff80d2abfbe9 100644 (file)
@@ -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=02:11:22:33:44:55 02:22:aa:44:55:66
+}
+
+# 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=02:55:ae:bc:de:f0 02:88:77:66:55:44
+}
 
 # Example config file that will only scan on channel 36.
 freq_list=5180