From 9ec876662b7630fe555b4c6838331f45e8a95ba1 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 7 Sep 2013 15:42:53 -0700 Subject: [PATCH] P2P: Allow GO P2P Device Address to be used for scan result matching 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 --- wpa_supplicant/config.c | 47 ++++++++++++++++++++++++++++++++++++ wpa_supplicant/config_file.c | 10 ++++++++ wpa_supplicant/config_ssid.h | 5 ++++ wpa_supplicant/events.c | 26 ++++++++++++++++++++ 4 files changed, 88 insertions(+) diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 19bcecebd..180827367 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -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 */ diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index cb2dde8e2..ed5cdfffc 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -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 */ diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h index 2a8be6bd4..0102da94c 100644 --- a/wpa_supplicant/config_ssid.h +++ b/wpa_supplicant/config_ssid.h @@ -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) */ diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index fc66225b1..44937723f 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -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