From 0a70f34f22162331cb515ffda9f125a68be12dec Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 7 Feb 2012 16:23:21 +0200 Subject: [PATCH] P2P: Allow BSS entry to be fetched based on GO P2P Device Address "BSS p2p_dev_addr=" can now be used to fetch a specific BSS entry based on the P2P Device Address of the GO to avoid having to iterate through the full BSS table when an external program needs to figure out whether a specific peer is currently operating as a GO. Signed-hostap: Jouni Malinen --- src/p2p/p2p.c | 26 ++++++++++++++++++++++++++ src/p2p/p2p.h | 9 +++++++++ wpa_supplicant/bss.c | 17 +++++++++++++++++ wpa_supplicant/bss.h | 2 ++ wpa_supplicant/ctrl_iface.c | 7 +++++++ 5 files changed, 61 insertions(+) diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 2f4c1147c..e7ce2308f 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -2096,6 +2096,32 @@ int p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf, char *end) } +int p2p_parse_dev_addr(const u8 *ies, size_t ies_len, u8 *dev_addr) +{ + struct wpabuf *p2p_ie; + struct p2p_message msg; + + p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len, + P2P_IE_VENDOR_TYPE); + if (p2p_ie == NULL) + return -1; + os_memset(&msg, 0, sizeof(msg)); + if (p2p_parse_p2p_ie(p2p_ie, &msg)) { + wpabuf_free(p2p_ie); + return -1; + } + + if (msg.p2p_device_addr == NULL) { + wpabuf_free(p2p_ie); + return -1; + } + + os_memcpy(dev_addr, msg.p2p_device_addr, ETH_ALEN); + wpabuf_free(p2p_ie); + return 0; +} + + static void p2p_clear_go_neg(struct p2p_data *p2p) { p2p->go_neg_peer = NULL; diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 0924db5cc..9c4070c93 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -1376,6 +1376,15 @@ int p2p_ie_text(struct wpabuf *p2p_ie, char *buf, char *end); */ int p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf, char *end); +/** + * p2p_parse_dev_addr - Parse P2P Device Address from P2P IE(s) + * @ies: Information elements from scan results + * @ies_len: ies buffer length in octets + * @dev_addr: Buffer for returning P2P Device Address + * Returns: 0 on success or -1 if P2P Device Address could not be parsed + */ +int p2p_parse_dev_addr(const u8 *ies, size_t ies_len, u8 *dev_addr); + /** * p2p_assoc_req_ie - Build P2P IE for (Re)Association Request frame * @p2p: P2P module context from p2p_init() diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c index 078e22d7c..1e7965895 100644 --- a/wpa_supplicant/bss.c +++ b/wpa_supplicant/bss.c @@ -540,6 +540,23 @@ struct wpa_bss * wpa_bss_get_bssid(struct wpa_supplicant *wpa_s, } +#ifdef CONFIG_P2P +struct wpa_bss * wpa_bss_get_p2p_dev_addr(struct wpa_supplicant *wpa_s, + const u8 *dev_addr) +{ + struct wpa_bss *bss; + dl_list_for_each_reverse(bss, &wpa_s->bss, struct wpa_bss, list) { + u8 addr[ETH_ALEN]; + if (p2p_parse_dev_addr((const u8 *) (bss + 1), bss->ie_len, + addr) == 0 && + os_memcmp(addr, dev_addr, ETH_ALEN) == 0) + return bss; + } + return NULL; +} +#endif /* CONFIG_P2P */ + + struct wpa_bss * wpa_bss_get_id(struct wpa_supplicant *wpa_s, unsigned int id) { struct wpa_bss *bss; diff --git a/wpa_supplicant/bss.h b/wpa_supplicant/bss.h index bb19f492c..9f1329868 100644 --- a/wpa_supplicant/bss.h +++ b/wpa_supplicant/bss.h @@ -94,6 +94,8 @@ struct wpa_bss * wpa_bss_get(struct wpa_supplicant *wpa_s, const u8 *bssid, const u8 *ssid, size_t ssid_len); struct wpa_bss * wpa_bss_get_bssid(struct wpa_supplicant *wpa_s, const u8 *bssid); +struct wpa_bss * wpa_bss_get_p2p_dev_addr(struct wpa_supplicant *wpa_s, + const u8 *dev_addr); struct wpa_bss * wpa_bss_get_id(struct wpa_supplicant *wpa_s, unsigned int id); const u8 * wpa_bss_get_ie(const struct wpa_bss *bss, u8 ie); const u8 * wpa_bss_get_vendor_ie(const struct wpa_bss *bss, u32 vendor_type); diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 6a3223e36..7f4fb0974 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -2210,6 +2210,13 @@ static int wpa_supplicant_ctrl_iface_bss(struct wpa_supplicant *wpa_s, bss = dl_list_entry(next, struct wpa_bss, list_id); } +#ifdef CONFIG_P2P + } else if (os_strncmp(cmd, "p2p_dev_addr=", 13) == 0) { + if (hwaddr_aton(cmd + 13, bssid) == 0) + bss = wpa_bss_get_p2p_dev_addr(wpa_s, bssid); + else + bss = NULL; +#endif /* CONFIG_P2P */ } else if (hwaddr_aton(cmd, bssid) == 0) bss = wpa_bss_get_bssid(wpa_s, bssid); else {