From 71a0e395b9619a47c07e37adaaa60ecab18bf6f9 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 4 Jul 2014 20:14:19 +0300 Subject: [PATCH] P2P: Make unrecognized vendor elements available in P2P_PEER This allows external programs to use vendor specific information from P2P peers without wpa_supplicant having to be able to parse and understand all such vendor specific elements. Signed-off-by: Jouni Malinen --- src/common/ieee802_11_defs.h | 1 + src/p2p/p2p.c | 43 +++++++++++++++++++++++++++++++++ src/p2p/p2p.h | 8 ++++++ wpa_supplicant/ctrl_iface.c | 16 ++++++++++++ wpa_supplicant/p2p_supplicant.c | 5 ++-- 5 files changed, 71 insertions(+), 2 deletions(-) diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index b8e9254f6..6de71e9e3 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -809,6 +809,7 @@ struct ieee80211_vht_operation { #define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs) * 00:50:F2 */ #define WPA_IE_VENDOR_TYPE 0x0050f201 +#define WMM_IE_VENDOR_TYPE 0x0050f202 #define WPS_IE_VENDOR_TYPE 0x0050f204 #define OUI_WFA 0x506f9a #define P2P_IE_VENDOR_TYPE 0x506f9a09 diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 69ee0d028..565cbdbd2 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -609,6 +609,46 @@ static void p2p_copy_wps_info(struct p2p_data *p2p, struct p2p_device *dev, } +static void p2p_update_peer_vendor_elems(struct p2p_device *dev, const u8 *ies, + size_t ies_len) +{ + const u8 *pos, *end; + u8 id, len; + + wpabuf_free(dev->info.vendor_elems); + dev->info.vendor_elems = NULL; + + end = ies + ies_len; + + for (pos = ies; pos + 1 < end; pos += len) { + id = *pos++; + len = *pos++; + + if (pos + len > end) + break; + + if (id != WLAN_EID_VENDOR_SPECIFIC || len < 3) + continue; + + if (len >= 4) { + u32 type = WPA_GET_BE32(pos); + + if (type == WPA_IE_VENDOR_TYPE || + type == WMM_IE_VENDOR_TYPE || + type == WPS_IE_VENDOR_TYPE || + type == P2P_IE_VENDOR_TYPE || + type == WFD_IE_VENDOR_TYPE) + continue; + } + + /* Unknown vendor element - make raw IE data available */ + if (wpabuf_resize(&dev->info.vendor_elems, 2 + len) < 0) + break; + wpabuf_put_data(dev->info.vendor_elems, pos - 2, 2 + len); + } +} + + /** * p2p_add_device - Add peer entries based on scan results or P2P frames * @p2p: P2P module context from p2p_init() @@ -757,6 +797,8 @@ int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq, p2p_parse_free(&msg); + p2p_update_peer_vendor_elems(dev, ies, ies_len); + if (dev->flags & P2P_DEV_REPORTED) return 0; @@ -826,6 +868,7 @@ static void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev) } wpabuf_free(dev->info.wfd_subelems); + wpabuf_free(dev->info.vendor_elems); wpabuf_free(dev->go_neg_conf); os_free(dev); diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index c4bc0d235..dee79dfb5 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -230,6 +230,14 @@ struct p2p_peer_info { * wfd_subelems - Wi-Fi Display subelements from WFD IE(s) */ struct wpabuf *wfd_subelems; + + /** + * vendor_elems - Unrecognized vendor elements + * + * This buffer includes any other vendor element than P2P, WPS, and WFD + * IE(s) from the frame that was used to discover the peer. + */ + struct wpabuf *vendor_elems; }; enum p2p_prov_disc_status { diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 143c854cd..f612b494d 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -4715,6 +4715,22 @@ static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd, return pos - buf; pos += res; + if (info->vendor_elems) { + res = os_snprintf(pos, end - pos, "vendor_elems="); + if (res < 0 || res >= end - pos) + return pos - buf; + pos += res; + + pos += wpa_snprintf_hex(pos, end - pos, + wpabuf_head(info->vendor_elems), + wpabuf_len(info->vendor_elems)); + + res = os_snprintf(pos, end - pos, "\n"); + if (res < 0 || res >= end - pos) + return pos - buf; + pos += res; + } + return pos - buf; } diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 0af5e3264..bcad4caa7 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -1693,14 +1693,15 @@ static void wpas_dev_found(void *ctx, const u8 *addr, wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_DEVICE_FOUND MACSTR " p2p_dev_addr=" MACSTR " pri_dev_type=%s name='%s' config_methods=0x%x " - "dev_capab=0x%x group_capab=0x%x%s%s", + "dev_capab=0x%x group_capab=0x%x%s%s%s", MAC2STR(addr), MAC2STR(info->p2p_device_addr), wps_dev_type_bin2str(info->pri_dev_type, devtype, sizeof(devtype)), info->device_name, info->config_methods, info->dev_capab, info->group_capab, wfd_dev_info_hex ? " wfd_dev_info=0x" : "", - wfd_dev_info_hex ? wfd_dev_info_hex : ""); + wfd_dev_info_hex ? wfd_dev_info_hex : "", + info->vendor_elems ? " vendor_elems=1" : ""); os_free(wfd_dev_info_hex); #endif /* CONFIG_NO_STDOUT_DEBUG */