18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * P2P - IE parser 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2009-2010, Atheros Communications 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_common.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps/wps_i.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_i.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtvoid p2p_copy_filter_devname(char *dst, size_t dst_len, 19d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const void *src, size_t src_len) 20d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 21d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt size_t i; 22d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 23d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (src_len >= dst_len) 24d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt src_len = dst_len - 1; 25d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_memcpy(dst, src, src_len); 26d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt dst[src_len] = '\0'; 27d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt for (i = 0; i < src_len; i++) { 28d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (dst[i] == '\0') 29d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 30d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (is_ctrl_char(dst[i])) 31d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt dst[i] = '_'; 32d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 33d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 34d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 35d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_parse_attribute(u8 id, const u8 *data, u16 len, 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message *msg) 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos; 40d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt u16 nlen; 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char devtype[WPS_DEV_TYPE_BUFSIZE]; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (id) { 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_CAPABILITY: 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 2) { 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Capability " 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "attribute (length %d)", len); 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->capability = data; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Device Capability %02x " 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Group Capability %02x", 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data[0], data[1]); 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_DEVICE_ID: 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < ETH_ALEN) { 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Device ID " 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "attribute (length %d)", len); 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->device_id = data; 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Device ID " MACSTR, 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(msg->device_id)); 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_GROUP_OWNER_INTENT: 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) { 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short GO Intent " 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "attribute (length %d)", len); 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->go_intent = data; 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * GO Intent: Intent %u " 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Tie breaker %u", data[0] >> 1, data[0] & 0x01); 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_STATUS: 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) { 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Status " 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "attribute (length %d)", len); 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->status = data; 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Status: %d", data[0]); 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_LISTEN_CHANNEL: 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len == 0) { 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Listen Channel: Ignore " 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "null channel"); 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 5) { 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Listen Channel " 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "attribute (length %d)", len); 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel = data; 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Listen Channel: " 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Country %c%c(0x%02x) Regulatory " 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Class %d Channel Number %d", data[0], data[1], 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data[2], data[3], data[4]); 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_OPERATING_CHANNEL: 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len == 0) { 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Operating Channel: " 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Ignore null channel"); 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 5) { 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Operating " 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Channel attribute (length %d)", len); 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->operating_channel = data; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Operating Channel: " 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Country %c%c(0x%02x) Regulatory " 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Class %d Channel Number %d", data[0], data[1], 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data[2], data[3], data[4]); 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_CHANNEL_LIST: 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 3) { 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Channel List " 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "attribute (length %d)", len); 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->channel_list = data; 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->channel_list_len = len; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Channel List: Country String " 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%c%c(0x%02x)'", data[0], data[1], data[2]); 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: Channel List", 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->channel_list, msg->channel_list_len); 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_GROUP_INFO: 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->group_info = data; 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->group_info_len = len; 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Group Info"); 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_DEVICE_INFO: 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < ETH_ALEN + 2 + 8 + 1) { 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Device Info " 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "attribute (length %d)", len); 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->p2p_device_info = data; 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->p2p_device_info_len = len; 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = data; 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->p2p_device_addr = pos; 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ETH_ALEN; 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->config_methods = WPA_GET_BE16(pos); 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->pri_dev_type = pos; 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 8; 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->num_sec_dev_types = *pos++; 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->num_sec_dev_types * 8 > data + len - pos) { 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Device Info underflow"); 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += msg->num_sec_dev_types * 8; 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data + len - pos < 4) { 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invalid Device Name " 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length %d", (int) (data + len - pos)); 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (WPA_GET_BE16(pos) != ATTR_DEV_NAME) { 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "P2P: Unexpected Device Name " 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "header", pos, 4); 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nlen = WPA_GET_BE16(pos); 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 170d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (nlen > data + len - pos || nlen > WPS_DEV_NAME_MAX_LEN) { 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invalid Device Name " 172d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "length %u (buf len %d)", nlen, 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) (data + len - pos)); 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 176d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt p2p_copy_filter_devname(msg->device_name, 177d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt sizeof(msg->device_name), pos, nlen); 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Device Info: addr " MACSTR 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " primary device type %s device name '%s' " 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "config methods 0x%x", 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(msg->p2p_device_addr), 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_dev_type_bin2str(msg->pri_dev_type, devtype, 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(devtype)), 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->device_name, msg->config_methods); 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_CONFIGURATION_TIMEOUT: 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 2) { 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Configuration " 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Timeout attribute (length %d)", len); 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->config_timeout = data; 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Configuration Timeout"); 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_INTENDED_INTERFACE_ADDR: 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < ETH_ALEN) { 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Intended P2P " 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Interface Address attribute (length %d)", 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len); 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->intended_addr = data; 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Intended P2P Interface Address: " 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, MAC2STR(msg->intended_addr)); 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_GROUP_BSSID: 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < ETH_ALEN) { 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short P2P Group BSSID " 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "attribute (length %d)", len); 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->group_bssid = data; 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * P2P Group BSSID: " MACSTR, 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(msg->group_bssid)); 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_GROUP_ID: 2179d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt if (len < ETH_ALEN || len > ETH_ALEN + SSID_MAX_LEN) { 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invalid P2P Group ID " 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "attribute length %d", len); 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->group_id = data; 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->group_id_len = len; 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * P2P Group ID: Device Address " 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, MAC2STR(msg->group_id)); 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: * P2P Group ID: SSID", 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->group_id + ETH_ALEN, 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->group_id_len - ETH_ALEN); 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_INVITATION_FLAGS: 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) { 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Invitation " 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Flag attribute (length %d)", len); 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->invitation_flags = data; 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Invitation Flags: bitmap 0x%x", 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data[0]); 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_MANAGEABILITY: 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) { 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Manageability " 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "attribute (length %d)", len); 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->manageability = data; 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Manageability: bitmap 0x%x", 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data[0]); 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_NOTICE_OF_ABSENCE: 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 2) { 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Notice of " 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Absence attribute (length %d)", len); 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->noa = data; 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->noa_len = len; 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Notice of Absence"); 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_EXT_LISTEN_TIMING: 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 4) { 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Extended Listen " 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Timing attribute (length %d)", len); 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->ext_listen_timing = data; 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Extended Listen Timing " 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(period %u msec interval %u msec)", 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_LE16(msg->ext_listen_timing), 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_LE16(msg->ext_listen_timing + 2)); 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_MINOR_REASON_CODE: 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) { 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Minor Reason " 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Code attribute (length %d)", len); 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->minor_reason_code = data; 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Minor Reason Code: %u", 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *msg->minor_reason_code); 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 282cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt case P2P_ATTR_OOB_GO_NEG_CHANNEL: 283cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (len < 6) { 284cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short OOB GO Neg " 285cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "Channel attribute (length %d)", len); 286cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 287cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 288cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt msg->oob_go_neg_channel = data; 289cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * OOB GO Neg Channel: " 290cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "Country %c%c(0x%02x) Operating Class %d " 291cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "Channel Number %d Role %d", 292cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt data[0], data[1], data[2], data[3], data[4], 293cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt data[5]); 294cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt break; 295216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case P2P_ATTR_SERVICE_HASH: 296216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (len < P2PS_HASH_LEN) { 297216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_DEBUG, 298216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt "P2P: Too short Service Hash (length %u)", 299216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt len); 300216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return -1; 301216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 302216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg->service_hash_count = len / P2PS_HASH_LEN; 303216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg->service_hash = data; 304216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "P2P: * Service Hash(s)", data, len); 305216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt break; 306216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case P2P_ATTR_SESSION_INFORMATION_DATA: 307216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg->session_info = data; 308216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg->session_info_len = len; 309216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Service Instance: %u bytes - %p", 310216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt len, data); 311216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt break; 312216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case P2P_ATTR_CONNECTION_CAPABILITY: 313216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (len < 1) { 314216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_DEBUG, 315216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt "P2P: Too short Connection Capability (length %u)", 316216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt len); 317216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return -1; 318216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 319216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg->conn_cap = data; 320216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Connection Capability: 0x%x", 321216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt *msg->conn_cap); 322216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt break; 323216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case P2P_ATTR_ADVERTISEMENT_ID: 324216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (len < 10) { 325216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_DEBUG, 326216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt "P2P: Too short Advertisement ID (length %u)", 327216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt len); 328216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return -1; 329216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 330216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg->adv_id = data; 331216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg->adv_mac = &data[sizeof(u32)]; 332216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Advertisement ID %x", 333216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt WPA_GET_LE32(data)); 334216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt break; 335216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case P2P_ATTR_ADVERTISED_SERVICE: 336216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (len < 8) { 337216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_DEBUG, 338216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt "P2P: Too short Service Instance (length %u)", 339216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt len); 340216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return -1; 341216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 342216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg->adv_service_instance = data; 343216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg->adv_service_instance_len = len; 344216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (len <= 255 + 8) { 345216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt char str[256]; 346216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt u8 namelen; 347216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 348216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt namelen = data[6]; 349216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (namelen > len - 7) 350216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt break; 351216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt os_memcpy(str, &data[7], namelen); 352216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt str[namelen] = '\0'; 353216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Service Instance: %x-%s", 354216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt WPA_GET_LE32(data), str); 355216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } else { 356216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Service Instance: %p", 357216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt data); 358216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 359216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt break; 360216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case P2P_ATTR_SESSION_ID: 361216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (len < sizeof(u32) + ETH_ALEN) { 362216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_DEBUG, 363216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt "P2P: Too short Session ID Info (length %u)", 364216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt len); 365216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return -1; 366216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 367216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg->session_id = data; 368216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg->session_mac = &data[sizeof(u32)]; 369216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Session ID: %x " MACSTR, 370216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt WPA_GET_LE32(data), MAC2STR(msg->session_mac)); 371216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt break; 372216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case P2P_ATTR_FEATURE_CAPABILITY: 373216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt if (!len) { 374216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_DEBUG, 375216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt "P2P: Too short Feature Capability (length %u)", 376216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt len); 377216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return -1; 378216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 379216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg->feature_cap = data; 380216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg->feature_cap_len = len; 381216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Feature Cap (length=%u)", len); 382216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt break; 383216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt case P2P_ATTR_PERSISTENT_GROUP: 384216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt { 3859d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt if (len < ETH_ALEN || len > ETH_ALEN + SSID_MAX_LEN) { 386216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_DEBUG, 3879d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt "P2P: Invalid Persistent Group Info (length %u)", 388216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt len); 389216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt return -1; 390216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 391216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt 392216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg->persistent_dev = data; 393216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg->persistent_ssid_len = len - ETH_ALEN; 394216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg->persistent_ssid = &data[ETH_ALEN]; 395216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Persistent Group: " MACSTR " %s", 396216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt MAC2STR(msg->persistent_dev), 397216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt wpa_ssid_txt(msg->persistent_ssid, 398216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt msg->persistent_ssid_len)); 399216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt break; 400216983bceec7c450951e2fbcd076b5c75d432e57Dmitry Shmidt } 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Skipped unknown attribute %d " 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(length %d)", id, len); 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_parse_p2p_ie - Parse P2P IE 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Concatenated P2P IE(s) payload 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @msg: Buffer for returning parsed attributes 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Note: Caller is responsible for clearing the msg data structure before 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * calling this function. 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_parse_p2p_ie(const struct wpabuf *buf, struct p2p_message *msg) 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos = wpabuf_head_u8(buf); 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *end = pos + wpabuf_len(buf); 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Parsing P2P IE"); 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < end) { 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 attr_len; 4296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt u8 id; 4306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 4316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (end - pos < 3) { 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invalid P2P attribute"); 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt id = *pos++; 4366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt attr_len = WPA_GET_LE16(pos); 4376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt pos += 2; 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Attribute %d length %u", 4396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt id, attr_len); 4406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (attr_len > end - pos) { 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Attribute underflow " 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(len=%u left=%d)", 4436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt attr_len, (int) (end - pos)); 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: Data", pos, end - pos); 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4476c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (p2p_parse_attribute(id, pos, attr_len, msg)) 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt pos += attr_len; 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_parse_wps_ie(const struct wpabuf *buf, struct p2p_message *msg) 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wps_parse_attr attr; 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Parsing WPS IE"); 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wps_parse_msg(buf, &attr)) 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (attr.dev_name && attr.dev_name_len < sizeof(msg->device_name) && 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !msg->device_name[0]) 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(msg->device_name, attr.dev_name, attr.dev_name_len); 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (attr.config_methods) { 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_config_methods = 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_BE16(attr.config_methods); 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Config Methods (WPS): 0x%x", 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_config_methods); 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (attr.dev_password_id) { 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->dev_password_id = WPA_GET_BE16(attr.dev_password_id); 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Device Password ID: %d", 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->dev_password_id); 477cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt msg->dev_password_id_present = 1; 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (attr.primary_dev_type) { 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char devtype[WPS_DEV_TYPE_BUFSIZE]; 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_pri_dev_type = attr.primary_dev_type; 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Primary Device Type (WPS): %s", 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_dev_type_bin2str(msg->wps_pri_dev_type, devtype, 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(devtype))); 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (attr.sec_dev_type_list) { 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list = attr.sec_dev_type_list; 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list_len = attr.sec_dev_type_list_len; 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_vendor_ext[i] = attr.vendor_ext[i]; 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_vendor_ext_len[i] = attr.vendor_ext_len[i]; 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->manufacturer = attr.manufacturer; 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->manufacturer_len = attr.manufacturer_len; 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_name = attr.model_name; 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_name_len = attr.model_name_len; 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_number = attr.model_number; 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_number_len = attr.model_number_len; 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->serial_number = attr.serial_number; 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->serial_number_len = attr.serial_number_len; 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 505cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt msg->oob_dev_password = attr.oob_dev_password; 506cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt msg->oob_dev_password_len = attr.oob_dev_password_len; 507cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_parse_ies - Parse P2P message IEs (both WPS and P2P IE) 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: IEs from the message 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of data buffer in octets 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @msg: Buffer for returning parsed attributes 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Note: Caller is responsible for clearing the msg data structure before 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * calling this function. 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Note: Caller must free temporary memory allocations by calling 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_parse_free() when the parsed data is not needed anymore. 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_parse_ies(const u8 *data, size_t len, struct p2p_message *msg) 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_11_elems elems; 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_11_parse_elems(data, len, &elems, 0); 5309d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt if (elems.ds_params) 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->ds_params = elems.ds_params; 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elems.ssid) 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->ssid = elems.ssid - 2; 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_attributes = ieee802_11_vendor_ie_concat(data, len, 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPS_DEV_OUI_WFA); 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->wps_attributes && 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_wps_ie(msg->wps_attributes, msg)) { 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(msg); 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->p2p_attributes = ieee802_11_vendor_ie_concat(data, len, 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_IE_VENDOR_TYPE); 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->p2p_attributes && 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_p2p_ie(msg->p2p_attributes, msg)) { 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to parse P2P IE data"); 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->p2p_attributes) 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_buf(MSG_MSGDUMP, "P2P: P2P IE data", 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->p2p_attributes); 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(msg); 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 55561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 55661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (elems.wfd) { 55761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt msg->wfd_subelems = ieee802_11_vendor_ie_concat( 55861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt data, len, WFD_IE_VENDOR_TYPE); 55961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 56061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 56161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 562d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt msg->pref_freq_list = elems.pref_freq_list; 563d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt msg->pref_freq_list_len = elems.pref_freq_list_len; 564d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_parse - Parse a P2P Action frame contents 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Action frame payload after Category and Code fields 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of data buffer in octets 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @msg: Buffer for returning parsed attributes 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Note: Caller must free temporary memory allocations by calling 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_parse_free() when the parsed data is not needed anymore. 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_parse(const u8 *data, size_t len, struct p2p_message *msg) 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(msg, 0, sizeof(*msg)); 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Parsing the received message"); 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) { 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: No Dialog Token in the message"); 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->dialog_token = data[0]; 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Dialog Token: %d", msg->dialog_token); 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_parse_ies(data + 1, len - 1, msg); 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 594cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtint p2p_parse_ies_separate(const u8 *wsc, size_t wsc_len, const u8 *p2p, 595cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt size_t p2p_len, struct p2p_message *msg) 596cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 597cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memset(msg, 0, sizeof(*msg)); 598cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 599cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt msg->wps_attributes = wpabuf_alloc_copy(wsc, wsc_len); 600cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (msg->wps_attributes && 601cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_parse_wps_ie(msg->wps_attributes, msg)) { 602cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_parse_free(msg); 603cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 604cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 605cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 606cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt msg->p2p_attributes = wpabuf_alloc_copy(p2p, p2p_len); 607cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (msg->p2p_attributes && 608cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_parse_p2p_ie(msg->p2p_attributes, msg)) { 609cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to parse P2P IE data"); 610cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (msg->p2p_attributes) 611cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_hexdump_buf(MSG_MSGDUMP, "P2P: P2P IE data", 612cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt msg->p2p_attributes); 613cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_parse_free(msg); 614cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 615cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 616cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 617cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return 0; 618cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 619cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 620cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_parse_free - Free temporary data from P2P parsing 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @msg: Parsed attributes 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_parse_free(struct p2p_message *msg) 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(msg->p2p_attributes); 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->p2p_attributes = NULL; 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(msg->wps_attributes); 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_attributes = NULL; 63161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 63261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(msg->wfd_subelems); 63361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt msg->wfd_subelems = NULL; 63461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_group_info_parse(const u8 *gi, size_t gi_len, 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_group_info *info) 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *g, *gend; 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(info, 0, sizeof(*info)); 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gi == NULL) 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt g = gi; 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gend = gi + gi_len; 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (g < gend) { 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_client_info *cli; 651d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const u8 *cend; 652d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt u16 count; 653d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt u8 len; 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli = &info->client[info->num_clients]; 656d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt len = *g++; 657d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (len > gend - g || len < 2 * ETH_ALEN + 1 + 2 + 8 + 1) 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; /* invalid data */ 659d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt cend = g + len; 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* g at start of P2P Client Info Descriptor */ 661d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt cli->p2p_device_addr = g; 662d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt g += ETH_ALEN; 663d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt cli->p2p_interface_addr = g; 664d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt g += ETH_ALEN; 665d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt cli->dev_capab = *g++; 666d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 667d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt cli->config_methods = WPA_GET_BE16(g); 668d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt g += 2; 669d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt cli->pri_dev_type = g; 670d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt g += 8; 671d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 672d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* g at Number of Secondary Device Types */ 673d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt len = *g++; 674d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (8 * len > cend - g) 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; /* invalid data */ 676d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt cli->num_sec_dev_types = len; 677d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt cli->sec_dev_types = g; 678d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt g += 8 * len; 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 680d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* g at Device Name in WPS TLV format */ 681d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (cend - g < 2 + 2) 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; /* invalid data */ 683d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (WPA_GET_BE16(g) != ATTR_DEV_NAME) 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; /* invalid Device Name TLV */ 685d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt g += 2; 686d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt count = WPA_GET_BE16(g); 687d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt g += 2; 688d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (count > cend - g) 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; /* invalid Device Name TLV */ 6909d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt if (count >= WPS_DEV_NAME_MAX_LEN) 6919d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt count = WPS_DEV_NAME_MAX_LEN; 692d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt cli->dev_name = (const char *) g; 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->dev_name_len = count; 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt g = cend; 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt info->num_clients++; 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (info->num_clients == P2P_MAX_GROUP_ENTRIES) 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_group_info_text(const u8 *gi, size_t gi_len, char *buf, 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *end) 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pos = buf; 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_group_info info; 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int i; 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_group_info_parse(gi, gi_len, &info) < 0) 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < info.num_clients; i++) { 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_client_info *cli; 7199d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt char name[WPS_DEV_NAME_MAX_LEN + 1]; 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char devtype[WPS_DEV_TYPE_BUFSIZE]; 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 s; 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int count; 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli = &info.client[i]; 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "p2p_group_client: " 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dev=" MACSTR " iface=" MACSTR, 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(cli->p2p_device_addr), 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(cli->p2p_interface_addr)); 7296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(end - pos, ret)) 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " dev_capab=0x%x config_methods=0x%x " 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dev_type=%s", 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->dev_capab, cli->config_methods, 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_dev_type_bin2str(cli->pri_dev_type, 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt devtype, 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(devtype))); 7406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(end - pos, ret)) 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (s = 0; s < cli->num_sec_dev_types; s++) { 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, " dev_type=%s", 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_dev_type_bin2str( 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &cli->sec_dev_types[s * 8], 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt devtype, sizeof(devtype))); 7496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(end - pos, ret)) 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(name, cli->dev_name, cli->dev_name_len); 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name[cli->dev_name_len] = '\0'; 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count = (int) cli->dev_name_len - 1; 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (count >= 0) { 7589d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt if (is_ctrl_char(name[count])) 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name[count] = '_'; 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count--; 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, " dev_name='%s'\n", name); 7646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(end - pos, ret)) 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_attr_text - Build text format description of P2P IE attributes 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: P2P IE contents 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Buffer for returning text 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @end: Pointer to the end of the buf area 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of octets written to the buffer or -1 on faikure 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to parse P2P IE contents into text format 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * field=value lines. 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_attr_text(struct wpabuf *data, char *buf, char *end) 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pos = buf; 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_p2p_ie(data, &msg)) 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.capability) { 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "p2p_dev_capab=0x%x\n" 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "p2p_group_capab=0x%x\n", 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.capability[0], msg.capability[1]); 7986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(end - pos, ret)) 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.pri_dev_type) { 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char devtype[WPS_DEV_TYPE_BUFSIZE]; 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "p2p_primary_device_type=%s\n", 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_dev_type_bin2str(msg.pri_dev_type, 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt devtype, 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(devtype))); 8106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(end - pos, ret)) 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "p2p_device_name=%s\n", 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.device_name); 8176c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(end - pos, ret)) 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.p2p_device_addr) { 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "p2p_device_addr=" MACSTR 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "\n", 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(msg.p2p_device_addr)); 8256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(end - pos, ret)) 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "p2p_config_methods=0x%x\n", 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.config_methods); 8326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (os_snprintf_error(end - pos, ret)) 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = p2p_group_info_text(msg.group_info, msg.group_info_len, 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, end); 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_get_cross_connect_disallowed(const struct wpabuf *p2p_ie) 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_p2p_ie(p2p_ie, &msg)) 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!msg.manageability) 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return !(msg.manageability[0] & P2P_MAN_CROSS_CONNECTION_PERMITTED); 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu8 p2p_get_group_capab(const struct wpabuf *p2p_ie) 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_p2p_ie(p2p_ie, &msg)) 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!msg.capability) 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return msg.capability[1]; 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * p2p_get_go_dev_addr(const struct wpabuf *p2p_ie) 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_p2p_ie(p2p_ie, &msg)) 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.p2p_device_addr) 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return msg.p2p_device_addr; 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.device_id) 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return msg.device_id; 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 891