]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Allow GO P2P Device Address to be used for scan result matching
authorJouni Malinen <jouni@qca.qualcomm.com>
Sat, 7 Sep 2013 22:42:53 +0000 (15:42 -0700)
committerJouni Malinen <j@w1.fi>
Thu, 7 Nov 2013 11:49:01 +0000 (13:49 +0200)
This is a better way of matching P2P groups based on the unique P2P
Device Address (e.g., from P2P Group ID) and SSID pair instead of using
the not necessarily unique P2P Interface Address.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>

wpa_supplicant/config.c
wpa_supplicant/config_file.c
wpa_supplicant/config_ssid.h
wpa_supplicant/events.c

index 19bcecebd0b9fb9303dcc2d9a7c26a2820cf3ec7..180827367c3f8d5f0de97cf119e67d0409233ee8 100644 (file)
@@ -1321,6 +1321,52 @@ static char * wpa_config_write_wep_key3(const struct parse_data *data,
 
 #ifdef CONFIG_P2P
 
+static int wpa_config_parse_go_p2p_dev_addr(const struct parse_data *data,
+                                           struct wpa_ssid *ssid, int line,
+                                           const char *value)
+{
+       if (value[0] == '\0' || os_strcmp(value, "\"\"") == 0 ||
+           os_strcmp(value, "any") == 0) {
+               os_memset(ssid->go_p2p_dev_addr, 0, ETH_ALEN);
+               wpa_printf(MSG_MSGDUMP, "GO P2P Device Address any");
+               return 0;
+       }
+       if (hwaddr_aton(value, ssid->go_p2p_dev_addr)) {
+               wpa_printf(MSG_ERROR, "Line %d: Invalid GO P2P Device Address '%s'.",
+                          line, value);
+               return -1;
+       }
+       ssid->bssid_set = 1;
+       wpa_printf(MSG_MSGDUMP, "GO P2P Device Address " MACSTR,
+                  MAC2STR(ssid->go_p2p_dev_addr));
+       return 0;
+}
+
+
+#ifndef NO_CONFIG_WRITE
+static char * wpa_config_write_go_p2p_dev_addr(const struct parse_data *data,
+                                              struct wpa_ssid *ssid)
+{
+       char *value;
+       int res;
+
+       if (is_zero_ether_addr(ssid->go_p2p_dev_addr))
+               return NULL;
+
+       value = os_malloc(20);
+       if (value == NULL)
+               return NULL;
+       res = os_snprintf(value, 20, MACSTR, MAC2STR(ssid->go_p2p_dev_addr));
+       if (res < 0 || res >= 20) {
+               os_free(value);
+               return NULL;
+       }
+       value[20 - 1] = '\0';
+       return value;
+}
+#endif /* NO_CONFIG_WRITE */
+
+
 static int wpa_config_parse_p2p_client_list(const struct parse_data *data,
                                            struct wpa_ssid *ssid, int line,
                                            const char *value)
@@ -1632,6 +1678,7 @@ static const struct parse_data ssid_fields[] = {
        { STR(bgscan) },
        { INT_RANGE(ignore_broadcast_ssid, 0, 2) },
 #ifdef CONFIG_P2P
+       { FUNC(go_p2p_dev_addr) },
        { FUNC(p2p_client_list) },
        { FUNC(psk_list) },
 #endif /* CONFIG_P2P */
index cb2dde8e2ee098e1d85b09ea5e4051329346c5ef..ed5cdfffcd3c2c4ef7fd0e6e122610c5a00f8d97 100644 (file)
@@ -606,6 +606,15 @@ static void write_wep_key(FILE *f, int idx, struct wpa_ssid *ssid)
 
 #ifdef CONFIG_P2P
 
+static void write_go_p2p_dev_addr(FILE *f, struct wpa_ssid *ssid)
+{
+       char *value = wpa_config_get(ssid, "go_p2p_dev_addr");
+       if (value == NULL)
+               return;
+       fprintf(f, "\tgo_p2p_dev_addr=%s\n", value);
+       os_free(value);
+}
+
 static void write_p2p_client_list(FILE *f, struct wpa_ssid *ssid)
 {
        char *value = wpa_config_get(ssid, "p2p_client_list");
@@ -714,6 +723,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
 #endif /* CONFIG_IEEE80211W */
        STR(id_str);
 #ifdef CONFIG_P2P
+       write_go_p2p_dev_addr(f, ssid);
        write_p2p_client_list(f, ssid);
        write_psk_list(f, ssid);
 #endif /* CONFIG_P2P */
index 2a8be6bd4427e41589be110f0932f6d997421bcc..0102da94ca102cf20c6b2fbaa8d8493668ece9fe 100644 (file)
@@ -130,6 +130,11 @@ struct wpa_ssid {
         */
        int bssid_set;
 
+       /**
+        * go_p2p_dev_addr - GO's P2P Device Address or all zeros if not set
+        */
+       u8 go_p2p_dev_addr[ETH_ALEN];
+
        /**
         * psk - WPA pre-shared key (256 bits)
         */
index fc66225b1fe9a02fa06ddfb408c3f5dd36503d01..44937723f7352127d54e05363e7c4d41f941df64 100644 (file)
@@ -866,6 +866,32 @@ static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
                        continue;
                }
 
+               if (!is_zero_ether_addr(ssid->go_p2p_dev_addr)) {
+                       struct wpabuf *p2p_ie;
+                       u8 dev_addr[ETH_ALEN];
+
+                       ie = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE);
+                       if (ie == NULL) {
+                               wpa_dbg(wpa_s, MSG_DEBUG, "   skip - no P2P element");
+                               continue;
+                       }
+                       p2p_ie = wpa_bss_get_vendor_ie_multi(
+                               bss, P2P_IE_VENDOR_TYPE);
+                       if (p2p_ie == NULL) {
+                               wpa_dbg(wpa_s, MSG_DEBUG, "   skip - could not fetch P2P element");
+                               continue;
+                       }
+
+                       if (p2p_parse_dev_addr_in_p2p_ie(p2p_ie, dev_addr) < 0
+                           || os_memcmp(dev_addr, ssid->go_p2p_dev_addr,
+                                        ETH_ALEN) != 0) {
+                               wpa_dbg(wpa_s, MSG_DEBUG, "   skip - no matching GO P2P Device Address in P2P element");
+                               wpabuf_free(p2p_ie);
+                               continue;
+                       }
+                       wpabuf_free(p2p_ie);
+               }
+
                /*
                 * TODO: skip the AP if its P2P IE has Group Formation
                 * bit set in the P2P Group Capability Bitmap and we