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 <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2014-07-04 20:14:19 +03:00 committed by Jouni Malinen
parent 86bd36f0d5
commit 71a0e395b9
5 changed files with 71 additions and 2 deletions

View file

@ -809,6 +809,7 @@ struct ieee80211_vht_operation {
#define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs) #define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs)
* 00:50:F2 */ * 00:50:F2 */
#define WPA_IE_VENDOR_TYPE 0x0050f201 #define WPA_IE_VENDOR_TYPE 0x0050f201
#define WMM_IE_VENDOR_TYPE 0x0050f202
#define WPS_IE_VENDOR_TYPE 0x0050f204 #define WPS_IE_VENDOR_TYPE 0x0050f204
#define OUI_WFA 0x506f9a #define OUI_WFA 0x506f9a
#define P2P_IE_VENDOR_TYPE 0x506f9a09 #define P2P_IE_VENDOR_TYPE 0x506f9a09

View file

@ -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_add_device - Add peer entries based on scan results or P2P frames
* @p2p: P2P module context from p2p_init() * @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_parse_free(&msg);
p2p_update_peer_vendor_elems(dev, ies, ies_len);
if (dev->flags & P2P_DEV_REPORTED) if (dev->flags & P2P_DEV_REPORTED)
return 0; 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.wfd_subelems);
wpabuf_free(dev->info.vendor_elems);
wpabuf_free(dev->go_neg_conf); wpabuf_free(dev->go_neg_conf);
os_free(dev); os_free(dev);

View file

@ -230,6 +230,14 @@ struct p2p_peer_info {
* wfd_subelems - Wi-Fi Display subelements from WFD IE(s) * wfd_subelems - Wi-Fi Display subelements from WFD IE(s)
*/ */
struct wpabuf *wfd_subelems; 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 { enum p2p_prov_disc_status {

View file

@ -4715,6 +4715,22 @@ static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd,
return pos - buf; return pos - buf;
pos += res; 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; return pos - buf;
} }

View file

@ -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 wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_DEVICE_FOUND MACSTR
" p2p_dev_addr=" MACSTR " p2p_dev_addr=" MACSTR
" pri_dev_type=%s name='%s' config_methods=0x%x " " 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), MAC2STR(addr), MAC2STR(info->p2p_device_addr),
wps_dev_type_bin2str(info->pri_dev_type, devtype, wps_dev_type_bin2str(info->pri_dev_type, devtype,
sizeof(devtype)), sizeof(devtype)),
info->device_name, info->config_methods, info->device_name, info->config_methods,
info->dev_capab, info->group_capab, info->dev_capab, info->group_capab,
wfd_dev_info_hex ? " wfd_dev_info=0x" : "", 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); os_free(wfd_dev_info_hex);
#endif /* CONFIG_NO_STDOUT_DEBUG */ #endif /* CONFIG_NO_STDOUT_DEBUG */