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 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_parse_attribute(u8 id, const u8 *data, u16 len, 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message *msg) 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos; 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, nlen; 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char devtype[WPS_DEV_TYPE_BUFSIZE]; 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (id) { 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_CAPABILITY: 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 2) { 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Capability " 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "attribute (length %d)", len); 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->capability = data; 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Device Capability %02x " 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Group Capability %02x", 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data[0], data[1]); 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_DEVICE_ID: 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < ETH_ALEN) { 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Device ID " 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "attribute (length %d)", len); 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->device_id = data; 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Device ID " MACSTR, 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(msg->device_id)); 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_GROUP_OWNER_INTENT: 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) { 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short GO Intent " 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "attribute (length %d)", len); 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->go_intent = data; 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * GO Intent: Intent %u " 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Tie breaker %u", data[0] >> 1, data[0] & 0x01); 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_STATUS: 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) { 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Status " 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "attribute (length %d)", len); 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->status = data; 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Status: %d", data[0]); 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_LISTEN_CHANNEL: 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len == 0) { 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Listen Channel: Ignore " 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "null channel"); 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 5) { 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Listen Channel " 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "attribute (length %d)", len); 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->listen_channel = data; 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Listen Channel: " 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Country %c%c(0x%02x) Regulatory " 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Class %d Channel Number %d", data[0], data[1], 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data[2], data[3], data[4]); 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_OPERATING_CHANNEL: 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len == 0) { 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Operating Channel: " 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Ignore null channel"); 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 5) { 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Operating " 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Channel attribute (length %d)", len); 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->operating_channel = data; 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Operating Channel: " 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Country %c%c(0x%02x) Regulatory " 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Class %d Channel Number %d", data[0], data[1], 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data[2], data[3], data[4]); 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_CHANNEL_LIST: 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 3) { 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Channel List " 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "attribute (length %d)", len); 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->channel_list = data; 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->channel_list_len = len; 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Channel List: Country String " 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%c%c(0x%02x)'", data[0], data[1], data[2]); 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: Channel List", 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->channel_list, msg->channel_list_len); 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_GROUP_INFO: 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->group_info = data; 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->group_info_len = len; 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Group Info"); 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_DEVICE_INFO: 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < ETH_ALEN + 2 + 8 + 1) { 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Device Info " 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "attribute (length %d)", len); 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->p2p_device_info = data; 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->p2p_device_info_len = len; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = data; 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->p2p_device_addr = pos; 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ETH_ALEN; 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->config_methods = WPA_GET_BE16(pos); 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->pri_dev_type = pos; 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 8; 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->num_sec_dev_types = *pos++; 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->num_sec_dev_types * 8 > data + len - pos) { 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Device Info underflow"); 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += msg->num_sec_dev_types * 8; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data + len - pos < 4) { 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invalid Device Name " 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length %d", (int) (data + len - pos)); 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (WPA_GET_BE16(pos) != ATTR_DEV_NAME) { 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "P2P: Unexpected Device Name " 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "header", pos, 4); 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nlen = WPA_GET_BE16(pos); 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data + len - pos < (int) nlen || nlen > 32) { 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invalid Device Name " 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length %d (buf len %d)", (int) nlen, 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) (data + len - pos)); 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(msg->device_name, pos, nlen); 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->device_name[nlen] = '\0'; 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < nlen; i++) { 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->device_name[i] == '\0') 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->device_name[i] > 0 && 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->device_name[i] < 32) 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->device_name[i] = '_'; 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Device Info: addr " MACSTR 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " primary device type %s device name '%s' " 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "config methods 0x%x", 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(msg->p2p_device_addr), 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_dev_type_bin2str(msg->pri_dev_type, devtype, 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(devtype)), 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->device_name, msg->config_methods); 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_CONFIGURATION_TIMEOUT: 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 2) { 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Configuration " 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Timeout attribute (length %d)", len); 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->config_timeout = data; 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Configuration Timeout"); 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_INTENDED_INTERFACE_ADDR: 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < ETH_ALEN) { 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Intended P2P " 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Interface Address attribute (length %d)", 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len); 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->intended_addr = data; 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Intended P2P Interface Address: " 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, MAC2STR(msg->intended_addr)); 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_GROUP_BSSID: 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < ETH_ALEN) { 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short P2P Group BSSID " 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "attribute (length %d)", len); 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->group_bssid = data; 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * P2P Group BSSID: " MACSTR, 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(msg->group_bssid)); 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_GROUP_ID: 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < ETH_ALEN || len > ETH_ALEN + 32) { 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invalid P2P Group ID " 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "attribute length %d", len); 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->group_id = data; 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->group_id_len = len; 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * P2P Group ID: Device Address " 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, MAC2STR(msg->group_id)); 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "P2P: * P2P Group ID: SSID", 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->group_id + ETH_ALEN, 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->group_id_len - ETH_ALEN); 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_INVITATION_FLAGS: 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) { 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Invitation " 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Flag attribute (length %d)", len); 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->invitation_flags = data; 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Invitation Flags: bitmap 0x%x", 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data[0]); 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_MANAGEABILITY: 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) { 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Manageability " 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "attribute (length %d)", len); 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->manageability = data; 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Manageability: bitmap 0x%x", 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data[0]); 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_NOTICE_OF_ABSENCE: 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 2) { 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Notice of " 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Absence attribute (length %d)", len); 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->noa = data; 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->noa_len = len; 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Notice of Absence"); 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_EXT_LISTEN_TIMING: 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 4) { 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Extended Listen " 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Timing attribute (length %d)", len); 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->ext_listen_timing = data; 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Extended Listen Timing " 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(period %u msec interval %u msec)", 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_LE16(msg->ext_listen_timing), 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_LE16(msg->ext_listen_timing + 2)); 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_ATTR_MINOR_REASON_CODE: 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) { 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short Minor Reason " 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Code attribute (length %d)", len); 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->minor_reason_code = data; 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Minor Reason Code: %u", 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *msg->minor_reason_code); 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Skipped unknown attribute %d " 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(length %d)", id, len); 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_parse_p2p_ie - Parse P2P IE 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Concatenated P2P IE(s) payload 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @msg: Buffer for returning parsed attributes 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Note: Caller is responsible for clearing the msg data structure before 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * calling this function. 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_parse_p2p_ie(const struct wpabuf *buf, struct p2p_message *msg) 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos = wpabuf_head_u8(buf); 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *end = pos + wpabuf_len(buf); 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Parsing P2P IE"); 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < end) { 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 attr_len; 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 2 >= end) { 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invalid P2P attribute"); 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr_len = WPA_GET_LE16(pos + 1); 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Attribute %d length %u", 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos[0], attr_len); 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 3 + attr_len > end) { 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Attribute underflow " 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(len=%u left=%d)", 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr_len, (int) (end - pos - 3)); 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: Data", pos, end - pos); 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_attribute(pos[0], pos + 3, attr_len, msg)) 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3 + attr_len; 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_parse_wps_ie(const struct wpabuf *buf, struct p2p_message *msg) 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wps_parse_attr attr; 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Parsing WPS IE"); 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wps_parse_msg(buf, &attr)) 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (attr.dev_name && attr.dev_name_len < sizeof(msg->device_name) && 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !msg->device_name[0]) 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(msg->device_name, attr.dev_name, attr.dev_name_len); 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (attr.config_methods) { 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_config_methods = 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_BE16(attr.config_methods); 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Config Methods (WPS): 0x%x", 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_config_methods); 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (attr.dev_password_id) { 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->dev_password_id = WPA_GET_BE16(attr.dev_password_id); 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Device Password ID: %d", 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->dev_password_id); 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (attr.primary_dev_type) { 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char devtype[WPS_DEV_TYPE_BUFSIZE]; 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_pri_dev_type = attr.primary_dev_type; 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Primary Device Type (WPS): %s", 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_dev_type_bin2str(msg->wps_pri_dev_type, devtype, 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(devtype))); 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (attr.sec_dev_type_list) { 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list = attr.sec_dev_type_list; 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list_len = attr.sec_dev_type_list_len; 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_vendor_ext[i] = attr.vendor_ext[i]; 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_vendor_ext_len[i] = attr.vendor_ext_len[i]; 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->manufacturer = attr.manufacturer; 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->manufacturer_len = attr.manufacturer_len; 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_name = attr.model_name; 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_name_len = attr.model_name_len; 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_number = attr.model_number; 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_number_len = attr.model_number_len; 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->serial_number = attr.serial_number; 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->serial_number_len = attr.serial_number_len; 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_parse_ies - Parse P2P message IEs (both WPS and P2P IE) 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: IEs from the message 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of data buffer in octets 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @msg: Buffer for returning parsed attributes 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Note: Caller is responsible for clearing the msg data structure before 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * calling this function. 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Note: Caller must free temporary memory allocations by calling 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_parse_free() when the parsed data is not needed anymore. 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_parse_ies(const u8 *data, size_t len, struct p2p_message *msg) 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_11_elems elems; 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_11_parse_elems(data, len, &elems, 0); 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elems.ds_params && elems.ds_params_len >= 1) 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->ds_params = elems.ds_params; 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elems.ssid) 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->ssid = elems.ssid - 2; 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_attributes = ieee802_11_vendor_ie_concat(data, len, 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPS_DEV_OUI_WFA); 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->wps_attributes && 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_wps_ie(msg->wps_attributes, msg)) { 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(msg); 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->p2p_attributes = ieee802_11_vendor_ie_concat(data, len, 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_IE_VENDOR_TYPE); 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->p2p_attributes && 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_p2p_ie(msg->p2p_attributes, msg)) { 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to parse P2P IE data"); 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->p2p_attributes) 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_buf(MSG_MSGDUMP, "P2P: P2P IE data", 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->p2p_attributes); 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(msg); 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 41861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (elems.wfd) { 41961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt msg->wfd_subelems = ieee802_11_vendor_ie_concat( 42061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt data, len, WFD_IE_VENDOR_TYPE); 42161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 42261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 42361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_parse - Parse a P2P Action frame contents 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Action frame payload after Category and Code fields 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of data buffer in octets 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @msg: Buffer for returning parsed attributes 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Note: Caller must free temporary memory allocations by calling 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_parse_free() when the parsed data is not needed anymore. 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_parse(const u8 *data, size_t len, struct p2p_message *msg) 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(msg, 0, sizeof(*msg)); 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Parsing the received message"); 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) { 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: No Dialog Token in the message"); 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->dialog_token = data[0]; 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Dialog Token: %d", msg->dialog_token); 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_parse_ies(data + 1, len - 1, msg); 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_parse_free - Free temporary data from P2P parsing 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @msg: Parsed attributes 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_parse_free(struct p2p_message *msg) 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(msg->p2p_attributes); 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->p2p_attributes = NULL; 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(msg->wps_attributes); 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_attributes = NULL; 46361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 46461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(msg->wfd_subelems); 46561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt msg->wfd_subelems = NULL; 46661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_group_info_parse(const u8 *gi, size_t gi_len, 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_group_info *info) 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *g, *gend; 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(info, 0, sizeof(*info)); 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gi == NULL) 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt g = gi; 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gend = gi + gi_len; 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (g < gend) { 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_client_info *cli; 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *t, *cend; 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int count; 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli = &info->client[info->num_clients]; 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cend = g + 1 + g[0]; 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cend > gend) 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; /* invalid data */ 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* g at start of P2P Client Info Descriptor */ 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* t at Device Capability Bitmap */ 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt t = g + 1 + 2 * ETH_ALEN; 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (t > cend) 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; /* invalid data */ 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->p2p_device_addr = g + 1; 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->p2p_interface_addr = g + 1 + ETH_ALEN; 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->dev_capab = t[0]; 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (t + 1 + 2 + 8 + 1 > cend) 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; /* invalid data */ 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->config_methods = WPA_GET_BE16(&t[1]); 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->pri_dev_type = &t[3]; 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt t += 1 + 2 + 8; 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* t at Number of Secondary Device Types */ 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->num_sec_dev_types = *t++; 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (t + 8 * cli->num_sec_dev_types > cend) 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; /* invalid data */ 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->sec_dev_types = t; 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt t += 8 * cli->num_sec_dev_types; 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* t at Device Name in WPS TLV format */ 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (t + 2 + 2 > cend) 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; /* invalid data */ 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (WPA_GET_BE16(t) != ATTR_DEV_NAME) 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; /* invalid Device Name TLV */ 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt t += 2; 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count = WPA_GET_BE16(t); 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt t += 2; 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (count > cend - t) 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; /* invalid Device Name TLV */ 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (count >= 32) 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count = 32; 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->dev_name = (const char *) t; 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->dev_name_len = count; 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt g = cend; 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt info->num_clients++; 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (info->num_clients == P2P_MAX_GROUP_ENTRIES) 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_group_info_text(const u8 *gi, size_t gi_len, char *buf, 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *end) 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pos = buf; 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_group_info info; 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int i; 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_group_info_parse(gi, gi_len, &info) < 0) 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < info.num_clients; i++) { 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_client_info *cli; 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char name[33]; 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char devtype[WPS_DEV_TYPE_BUFSIZE]; 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 s; 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int count; 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli = &info.client[i]; 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "p2p_group_client: " 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dev=" MACSTR " iface=" MACSTR, 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(cli->p2p_device_addr), 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(cli->p2p_interface_addr)); 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " dev_capab=0x%x config_methods=0x%x " 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dev_type=%s", 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->dev_capab, cli->config_methods, 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_dev_type_bin2str(cli->pri_dev_type, 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt devtype, 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(devtype))); 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (s = 0; s < cli->num_sec_dev_types; s++) { 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, " dev_type=%s", 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_dev_type_bin2str( 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &cli->sec_dev_types[s * 8], 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt devtype, sizeof(devtype))); 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(name, cli->dev_name, cli->dev_name_len); 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name[cli->dev_name_len] = '\0'; 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count = (int) cli->dev_name_len - 1; 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (count >= 0) { 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (name[count] > 0 && name[count] < 32) 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name[count] = '_'; 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count--; 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, " dev_name='%s'\n", name); 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_attr_text - Build text format description of P2P IE attributes 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: P2P IE contents 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Buffer for returning text 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @end: Pointer to the end of the buf area 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of octets written to the buffer or -1 on faikure 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to parse P2P IE contents into text format 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * field=value lines. 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_attr_text(struct wpabuf *data, char *buf, char *end) 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pos = buf; 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_p2p_ie(data, &msg)) 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.capability) { 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "p2p_dev_capab=0x%x\n" 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "p2p_group_capab=0x%x\n", 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.capability[0], msg.capability[1]); 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.pri_dev_type) { 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char devtype[WPS_DEV_TYPE_BUFSIZE]; 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "p2p_primary_device_type=%s\n", 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_dev_type_bin2str(msg.pri_dev_type, 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt devtype, 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(devtype))); 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "p2p_device_name=%s\n", 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.device_name); 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.p2p_device_addr) { 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "p2p_device_addr=" MACSTR 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "\n", 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(msg.p2p_device_addr)); 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "p2p_config_methods=0x%x\n", 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.config_methods); 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = p2p_group_info_text(msg.group_info, msg.group_info_len, 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, end); 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_get_cross_connect_disallowed(const struct wpabuf *p2p_ie) 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_p2p_ie(p2p_ie, &msg)) 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!msg.manageability) 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return !(msg.manageability[0] & P2P_MAN_CROSS_CONNECTION_PERMITTED); 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu8 p2p_get_group_capab(const struct wpabuf *p2p_ie) 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_p2p_ie(p2p_ie, &msg)) 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!msg.capability) 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return msg.capability[1]; 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * p2p_get_go_dev_addr(const struct wpabuf *p2p_ie) 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_p2p_ie(p2p_ie, &msg)) 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.p2p_device_addr) 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return msg.p2p_device_addr; 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.device_id) 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return msg.device_id; 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 724