hostapd: update hostapd to 2015-03-25
[openwrt/svn-archive/archive.git] / package / network / services / hostapd / patches / 710-Add-network-specific-BSSID-black-and-white-lists.patch
diff --git a/package/network/services/hostapd/patches/710-Add-network-specific-BSSID-black-and-white-lists.patch b/package/network/services/hostapd/patches/710-Add-network-specific-BSSID-black-and-white-lists.patch
deleted file mode 100644 (file)
index 5b42158..0000000
+++ /dev/null
@@ -1,649 +0,0 @@
-Add network specific BSSID black and white lists
-
-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.
-
-In many applications it is useful not just to enumerate a group of well
-known access points, but to use a address/mask notation to match an
-entire set of addresses (ca:ff:ee:00:00:00/ff:ff:ff:00:00:00).
-
-This change expands the data structures used by MAC lists to include a
-mask indicating the significant (non-masked) portions of an address and
-extends the list parser to recognize mask suffixes.
-
-Signed-off-by: Stefan Tomanek <stefan.tomanek@wertarbyte.de>
----
- src/utils/common.c                 |  86 ++++++++++++--
- src/utils/common.h                 |   3 +
- wpa_supplicant/config.c            | 223 ++++++++++++++++++++++++-------------
- wpa_supplicant/config_ssid.h       |  12 ++
- wpa_supplicant/events.c            |  45 ++++++++
- wpa_supplicant/p2p_supplicant.c    |  40 ++++---
- wpa_supplicant/wpa_supplicant.conf |  15 +++
- 7 files changed, 323 insertions(+), 101 deletions(-)
-
-diff --git a/src/utils/common.c b/src/utils/common.c
-index 9902004..dd6e4aa 100644
---- a/src/utils/common.c
-+++ b/src/utils/common.c
-@@ -36,6 +36,25 @@ int hex2byte(const char *hex)
- }
-+static const char * hwaddr_parse(const char *txt, u8 *addr)
-+{
-+      size_t i;
-+
-+      for (i = 0; i < ETH_ALEN; i++) {
-+              int a;
-+
-+              a = hex2byte(txt);
-+              if (a < 0)
-+                      return NULL;
-+              txt += 2;
-+              addr[i] = a;
-+              if (i < ETH_ALEN - 1 && *txt++ != ':')
-+                      return NULL;
-+      }
-+      return txt;
-+}
-+
-+
- /**
-  * hwaddr_aton - Convert ASCII string to MAC address (colon-delimited format)
-  * @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
-@@ -44,25 +63,46 @@ int hex2byte(const char *hex)
-  */
- int hwaddr_aton(const char *txt, u8 *addr)
- {
--      int i;
-+      return hwaddr_parse(txt, addr) ? 0 : -1;
-+}
--      for (i = 0; i < 6; i++) {
--              int a, b;
--              a = hex2num(*txt++);
--              if (a < 0)
--                      return -1;
--              b = hex2num(*txt++);
--              if (b < 0)
--                      return -1;
--              *addr++ = (a << 4) | b;
--              if (i < 5 && *txt++ != ':')
-+/**
-+ * hwaddr_masked_aton - Convert ASCII string with optional mask to MAC address (colon-delimited format)
-+ * @txt: MAC address with optional mask as a string (e.g., "00:11:22:33:44:55/ff:ff:ff:ff:00:00")
-+ * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
-+ * @mask: Buffer for the MAC address mask (ETH_ALEN = 6 bytes)
-+ * @maskable: Flag to indicate whether a mask is allowed
-+ * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
-+ */
-+int hwaddr_masked_aton(const char *txt, u8 *addr, u8 *mask, u8 maskable)
-+{
-+      const char *r;
-+
-+      /* parse address part */
-+      r = hwaddr_parse(txt, addr);
-+      if (!r)
-+              return -1;
-+
-+      /* check for optional mask */
-+      if (*r == '\0' || isspace(*r)) {
-+              /* no mask specified, assume default */
-+              os_memset(mask, 0xff, ETH_ALEN);
-+      } else if (maskable && *r == '/') {
-+              /* mask specified and allowed */
-+              r = hwaddr_parse(r + 1, mask);
-+              /* parser error? */
-+              if (!r)
-                       return -1;
-+      } else {
-+              /* mask specified but not allowed or trailing garbage */
-+              return -1;
-       }
-       return 0;
- }
-+
- /**
-  * hwaddr_compact_aton - Convert ASCII string to MAC address (no colon delimitors format)
-  * @txt: MAC address as a string (e.g., "001122334455")
-@@ -144,6 +184,30 @@ int hexstr2bin(const char *hex, u8 *buf, size_t len)
- }
-+int hwaddr_mask_txt(char *buf, size_t len, const u8 *addr, const u8 *mask)
-+{
-+      size_t i;
-+      int print_mask = 0;
-+      int res;
-+
-+      for (i = 0; i < ETH_ALEN; i++) {
-+              if (mask[i] != 0xff) {
-+                      print_mask = 1;
-+                      break;
-+              }
-+      }
-+
-+      if (print_mask)
-+              res = os_snprintf(buf, len, MACSTR "/" MACSTR,
-+                                MAC2STR(addr), MAC2STR(mask));
-+      else
-+              res = os_snprintf(buf, len, MACSTR, MAC2STR(addr));
-+      if (os_snprintf_error(len, res))
-+              return -1;
-+      return res;
-+}
-+
-+
- /**
-  * inc_byte_array - Increment arbitrary length byte array by one
-  * @counter: Pointer to byte array
-diff --git a/src/utils/common.h b/src/utils/common.h
-index 14d9ad1..1127074 100644
---- a/src/utils/common.h
-+++ b/src/utils/common.h
-@@ -468,6 +468,7 @@ typedef u64 __bitwise le64;
- #endif /* __must_check */
- int hwaddr_aton(const char *txt, u8 *addr);
-+int hwaddr_masked_aton(const char *txt, u8 *addr, u8 *mask, u8 maskable);
- int hwaddr_compact_aton(const char *txt, u8 *addr);
- int hwaddr_aton2(const char *txt, u8 *addr);
- int hex2byte(const char *hex);
-@@ -478,6 +479,8 @@ int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len);
- int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data,
-                              size_t len);
-+int hwaddr_mask_txt(char *buf, size_t len, const u8 *addr, const u8 *mask);
-+
- #ifdef CONFIG_NATIVE_WINDOWS
- void wpa_unicode2ascii_inplace(TCHAR *str);
- TCHAR * wpa_strdup_tchar(const char *str);
-diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
-index 8d1e1e0..7f742cb 100644
---- a/wpa_supplicant/config.c
-+++ b/wpa_supplicant/config.c
-@@ -235,6 +235,99 @@ static char * wpa_config_write_int(const struct parse_data *data,
- #endif /* NO_CONFIG_WRITE */
-+static int wpa_config_parse_addr_list(const struct parse_data *data,
-+                                    int line, const char *value,
-+                                    u8 **list, size_t *num, char *name,
-+                                    u8 abort_on_error, u8 masked)
-+{
-+      const char *pos;
-+      u8 *buf, *n, addr[2 * ETH_ALEN];
-+      size_t count;
-+
-+      buf = NULL;
-+      count = 0;
-+
-+      pos = value;
-+      while (pos && *pos) {
-+              while (*pos == ' ')
-+                      pos++;
-+
-+              if (hwaddr_masked_aton(pos, addr, &addr[ETH_ALEN], masked)) {
-+                      if (abort_on_error || count == 0) {
-+                              wpa_printf(MSG_ERROR,
-+                                         "Line %d: Invalid %s address '%s'",
-+                                         line, name, value);
-+                              os_free(buf);
-+                              return -1;
-+                      }
-+                      /* continue anyway since this could have been from a
-+                       * truncated configuration file line */
-+                      wpa_printf(MSG_INFO,
-+                                 "Line %d: Ignore likely truncated %s address '%s'",
-+                                 line, name, pos);
-+              } else {
-+                      n = os_realloc_array(buf, count + 1, 2 * ETH_ALEN);
-+                      if (n == NULL) {
-+                              os_free(buf);
-+                              return -1;
-+                      }
-+                      buf = n;
-+                      os_memmove(buf + 2 * ETH_ALEN, buf,
-+                                 count * 2 * ETH_ALEN);
-+                      os_memcpy(buf, addr, 2 * ETH_ALEN);
-+                      count++;
-+                      wpa_printf(MSG_MSGDUMP,
-+                                 "%s: addr=" MACSTR " mask=" MACSTR,
-+                                 name, MAC2STR(addr),
-+                                 MAC2STR(&addr[ETH_ALEN]));
-+              }
-+
-+              pos = os_strchr(pos, ' ');
-+      }
-+
-+      os_free(*list);
-+      *list = buf;
-+      *num = count;
-+
-+      return 0;
-+}
-+
-+
-+#ifndef NO_CONFIG_WRITE
-+static char * wpa_config_write_addr_list(const struct parse_data *data,
-+                                       const u8 *list, size_t num, char *name)
-+{
-+      char *value, *end, *pos;
-+      int res;
-+      size_t i;
-+
-+      if (list == NULL || num == 0)
-+              return NULL;
-+
-+      value = os_malloc(2 * 20 * num);
-+      if (value == NULL)
-+              return NULL;
-+      pos = value;
-+      end = value + 2 * 20 * num;
-+
-+      for (i = num; i > 0; i--) {
-+              const u8 *a = list + (i - 1) * 2 * ETH_ALEN;
-+              const u8 *m = a + ETH_ALEN;
-+
-+              if (i < num)
-+                      *pos++ = ' ';
-+              res = hwaddr_mask_txt(pos, end - pos, a, m);
-+              if (res < 0) {
-+                      os_free(value);
-+                      return NULL;
-+              }
-+              pos += res;
-+      }
-+
-+      return value;
-+}
-+#endif /* NO_CONFIG_WRITE */
-+
- static int wpa_config_parse_bssid(const struct parse_data *data,
-                                 struct wpa_ssid *ssid, int line,
-                                 const char *value)
-@@ -280,6 +373,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, 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, 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)
-@@ -1435,53 +1572,10 @@ static int wpa_config_parse_p2p_client_list(const struct parse_data *data,
-                                           struct wpa_ssid *ssid, int line,
-                                           const char *value)
- {
--      const char *pos;
--      u8 *buf, *n, addr[ETH_ALEN];
--      size_t count;
--
--      buf = NULL;
--      count = 0;
--
--      pos = value;
--      while (pos && *pos) {
--              while (*pos == ' ')
--                      pos++;
--
--              if (hwaddr_aton(pos, addr)) {
--                      if (count == 0) {
--                              wpa_printf(MSG_ERROR, "Line %d: Invalid "
--                                         "p2p_client_list address '%s'.",
--                                         line, value);
--                              os_free(buf);
--                              return -1;
--                      }
--                      /* continue anyway since this could have been from a
--                       * truncated configuration file line */
--                      wpa_printf(MSG_INFO, "Line %d: Ignore likely "
--                                 "truncated p2p_client_list address '%s'",
--                                 line, pos);
--              } else {
--                      n = os_realloc_array(buf, count + 1, ETH_ALEN);
--                      if (n == NULL) {
--                              os_free(buf);
--                              return -1;
--                      }
--                      buf = n;
--                      os_memmove(buf + ETH_ALEN, buf, count * ETH_ALEN);
--                      os_memcpy(buf, addr, ETH_ALEN);
--                      count++;
--                      wpa_hexdump(MSG_MSGDUMP, "p2p_client_list",
--                                  addr, ETH_ALEN);
--              }
--
--              pos = os_strchr(pos, ' ');
--      }
--
--      os_free(ssid->p2p_client_list);
--      ssid->p2p_client_list = buf;
--      ssid->num_p2p_clients = count;
--
--      return 0;
-+      return wpa_config_parse_addr_list(data, line, value,
-+                                        &ssid->p2p_client_list,
-+                                        &ssid->num_p2p_clients,
-+                                        "p2p_client_list", 0, 0);
- }
-@@ -1489,34 +1583,9 @@ static int wpa_config_parse_p2p_client_list(const struct parse_data *data,
- static char * wpa_config_write_p2p_client_list(const struct parse_data *data,
-                                              struct wpa_ssid *ssid)
- {
--      char *value, *end, *pos;
--      int res;
--      size_t i;
--
--      if (ssid->p2p_client_list == NULL || ssid->num_p2p_clients == 0)
--              return NULL;
--
--      value = os_malloc(20 * ssid->num_p2p_clients);
--      if (value == NULL)
--              return NULL;
--      pos = value;
--      end = value + 20 * ssid->num_p2p_clients;
--
--      for (i = ssid->num_p2p_clients; i > 0; i--) {
--              res = os_snprintf(pos, end - pos, MACSTR " ",
--                                MAC2STR(ssid->p2p_client_list +
--                                        (i - 1) * ETH_ALEN));
--              if (res < 0 || res >= end - pos) {
--                      os_free(value);
--                      return NULL;
--              }
--              pos += res;
--      }
--
--      if (pos > value)
--              pos[-1] = '\0';
--
--      return value;
-+      return wpa_config_write_addr_list(data, ssid->p2p_client_list,
-+                                        ssid->num_p2p_clients,
-+                                        "p2p_client_list");
- }
- #endif /* NO_CONFIG_WRITE */
-@@ -1667,6 +1736,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) },
-@@ -1971,6 +2042,8 @@ void wpa_config_free_ssid(struct wpa_ssid *ssid)
-       os_free(ssid->freq_list);
-       os_free(ssid->bgscan);
-       os_free(ssid->p2p_client_list);
-+      os_free(ssid->bssid_blacklist);
-+      os_free(ssid->bssid_whitelist);
- #ifdef CONFIG_HT_OVERRIDES
-       os_free(ssid->ht_mcs);
- #endif /* CONFIG_HT_OVERRIDES */
-diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
-index a4910d0..7443207 100644
---- a/wpa_supplicant/config_ssid.h
-+++ b/wpa_supplicant/config_ssid.h
-@@ -128,6 +128,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 6761c1a..855653c 100644
---- a/wpa_supplicant/events.c
-+++ b/wpa_supplicant/events.c
-@@ -703,6 +703,33 @@ static int bss_is_ess(struct wpa_bss *bss)
- }
-+static int match_mac_mask(const u8 *addr_a, const u8 *addr_b, const u8 *mask)
-+{
-+      size_t i;
-+
-+      for (i = 0; i < ETH_ALEN; i++) {
-+              if ((addr_a[i] & mask[i]) != (addr_b[i] & mask[i]))
-+                      return 0;
-+      }
-+      return 1;
-+}
-+
-+
-+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 * 2;
-+              const u8 *m = a + ETH_ALEN;
-+
-+              if (match_mac_mask(a, addr, m))
-+                      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,
-@@ -827,6 +854,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;
-diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
-index 8cd43df..60dcb5d 100644
---- a/wpa_supplicant/p2p_supplicant.c
-+++ b/wpa_supplicant/p2p_supplicant.c
-@@ -831,7 +831,7 @@ static void wpas_p2p_add_persistent_group_client(struct wpa_supplicant *wpa_s,
-               return;
-       for (i = 0; s->p2p_client_list && i < s->num_p2p_clients; i++) {
--              if (os_memcmp(s->p2p_client_list + i * ETH_ALEN, addr,
-+              if (os_memcmp(s->p2p_client_list + i * 2 * ETH_ALEN, addr,
-                             ETH_ALEN) != 0)
-                       continue;
-@@ -839,32 +839,42 @@ static void wpas_p2p_add_persistent_group_client(struct wpa_supplicant *wpa_s,
-                       return; /* already the most recent entry */
-               /* move the entry to mark it most recent */
--              os_memmove(s->p2p_client_list + i * ETH_ALEN,
--                         s->p2p_client_list + (i + 1) * ETH_ALEN,
--                         (s->num_p2p_clients - i - 1) * ETH_ALEN);
-+              os_memmove(s->p2p_client_list + i * 2 * ETH_ALEN,
-+                         s->p2p_client_list + (i + 1) * 2 * ETH_ALEN,
-+                         (s->num_p2p_clients - i - 1) * 2 * ETH_ALEN);
-               os_memcpy(s->p2p_client_list +
--                        (s->num_p2p_clients - 1) * ETH_ALEN, addr, ETH_ALEN);
-+                        (s->num_p2p_clients - 1) * 2 * ETH_ALEN, addr,
-+                        ETH_ALEN);
-+              os_memset(s->p2p_client_list +
-+                        (s->num_p2p_clients - 1) * 2 * ETH_ALEN + ETH_ALEN,
-+                        0xff, ETH_ALEN);
-               found = 1;
-               break;
-       }
-       if (!found && s->num_p2p_clients < P2P_MAX_STORED_CLIENTS) {
-               n = os_realloc_array(s->p2p_client_list,
--                                   s->num_p2p_clients + 1, ETH_ALEN);
-+                                   s->num_p2p_clients + 1, 2 * ETH_ALEN);
-               if (n == NULL)
-                       return;
--              os_memcpy(n + s->num_p2p_clients * ETH_ALEN, addr, ETH_ALEN);
-+              os_memcpy(n + s->num_p2p_clients * 2 * ETH_ALEN, addr,
-+                        ETH_ALEN);
-+              os_memset(n + s->num_p2p_clients * 2 * ETH_ALEN + ETH_ALEN,
-+                        0xff, ETH_ALEN);
-               s->p2p_client_list = n;
-               s->num_p2p_clients++;
-       } else if (!found && s->p2p_client_list) {
-               /* Not enough room for an additional entry - drop the oldest
-                * entry */
-               os_memmove(s->p2p_client_list,
--                         s->p2p_client_list + ETH_ALEN,
--                         (s->num_p2p_clients - 1) * ETH_ALEN);
-+                         s->p2p_client_list + 2 * ETH_ALEN,
-+                         (s->num_p2p_clients - 1) * 2 * ETH_ALEN);
-               os_memcpy(s->p2p_client_list +
--                        (s->num_p2p_clients - 1) * ETH_ALEN,
-+                        (s->num_p2p_clients - 1) * 2 * ETH_ALEN,
-                         addr, ETH_ALEN);
-+              os_memset(s->p2p_client_list +
-+                        (s->num_p2p_clients - 1) * 2 * ETH_ALEN + ETH_ALEN,
-+                        0xff, ETH_ALEN);
-       }
-       if (wpa_s->parent->conf->update_config &&
-@@ -3276,7 +3286,7 @@ static void wpas_remove_persistent_peer(struct wpa_supplicant *wpa_s,
-               return;
-       for (i = 0; ssid->p2p_client_list && i < ssid->num_p2p_clients; i++) {
--              if (os_memcmp(ssid->p2p_client_list + i * ETH_ALEN, peer,
-+              if (os_memcmp(ssid->p2p_client_list + i * 2 * ETH_ALEN, peer,
-                             ETH_ALEN) == 0)
-                       break;
-       }
-@@ -3296,9 +3306,9 @@ static void wpas_remove_persistent_peer(struct wpa_supplicant *wpa_s,
-                  "group %d client list%s",
-                  MAC2STR(peer), ssid->id,
-                  inv ? " due to invitation result" : "");
--      os_memmove(ssid->p2p_client_list + i * ETH_ALEN,
--                 ssid->p2p_client_list + (i + 1) * ETH_ALEN,
--                 (ssid->num_p2p_clients - i - 1) * ETH_ALEN);
-+      os_memmove(ssid->p2p_client_list + i * 2 * ETH_ALEN,
-+                 ssid->p2p_client_list + (i + 1) * 2 * ETH_ALEN,
-+                 (ssid->num_p2p_clients - i - 1) * 2 * ETH_ALEN);
-       ssid->num_p2p_clients--;
-       if (wpa_s->parent->conf->update_config &&
-           wpa_config_write(wpa_s->parent->confname, wpa_s->parent->conf))
-@@ -6925,7 +6935,7 @@ struct wpa_ssid * wpas_p2p_get_persistent(struct wpa_supplicant *wpa_s,
-               if (s->mode != WPAS_MODE_P2P_GO || s->p2p_client_list == NULL)
-                       continue;
-               for (i = 0; i < s->num_p2p_clients; i++) {
--                      if (os_memcmp(s->p2p_client_list + i * ETH_ALEN,
-+                      if (os_memcmp(s->p2p_client_list + i * 2 * ETH_ALEN,
-                                     addr, ETH_ALEN) == 0)
-                               return s; /* peer is P2P client in persistent
-                                          * group */
-diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
-index 0e8a28a..4bc08db 100644
---- a/wpa_supplicant/wpa_supplicant.conf
-+++ b/wpa_supplicant/wpa_supplicant.conf
-@@ -1408,6 +1408,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 not matching the masked address will be ignored.
-+network={
-+      ssid="example"
-+      psk="very secret passphrase"
-+      bssid_whitelist=02:55:ae:bc:00:00/ff:ff:ff:ff:00:00 00:00:77:66:55:44/00:00:ff:ff:ff:ff
-+}
- # Example config file that will only scan on channel 36.
- freq_list=5180
--- 
-2.1.3
-