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; 271cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt case P2P_ATTR_OOB_GO_NEG_CHANNEL: 272cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (len < 6) { 273cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Too short OOB GO Neg " 274cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "Channel attribute (length %d)", len); 275cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 276cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 277cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt msg->oob_go_neg_channel = data; 278cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * OOB GO Neg Channel: " 279cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "Country %c%c(0x%02x) Operating Class %d " 280cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt "Channel Number %d Role %d", 281cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt data[0], data[1], data[2], data[3], data[4], 282cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt data[5]); 283cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt break; 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Skipped unknown attribute %d " 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(length %d)", id, len); 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_parse_p2p_ie - Parse P2P IE 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Concatenated P2P IE(s) payload 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @msg: Buffer for returning parsed attributes 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Note: Caller is responsible for clearing the msg data structure before 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * calling this function. 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_parse_p2p_ie(const struct wpabuf *buf, struct p2p_message *msg) 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos = wpabuf_head_u8(buf); 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *end = pos + wpabuf_len(buf); 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Parsing P2P IE"); 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < end) { 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 attr_len; 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 2 >= end) { 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Invalid P2P attribute"); 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr_len = WPA_GET_LE16(pos + 1); 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Attribute %d length %u", 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos[0], attr_len); 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 3 + attr_len > end) { 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Attribute underflow " 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(len=%u left=%d)", 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt attr_len, (int) (end - pos - 3)); 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "P2P: Data", pos, end - pos); 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_attribute(pos[0], pos + 3, attr_len, msg)) 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 3 + attr_len; 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_parse_wps_ie(const struct wpabuf *buf, struct p2p_message *msg) 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wps_parse_attr attr; 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Parsing WPS IE"); 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wps_parse_msg(buf, &attr)) 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (attr.dev_name && attr.dev_name_len < sizeof(msg->device_name) && 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !msg->device_name[0]) 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(msg->device_name, attr.dev_name, attr.dev_name_len); 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (attr.config_methods) { 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_config_methods = 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_BE16(attr.config_methods); 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Config Methods (WPS): 0x%x", 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_config_methods); 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (attr.dev_password_id) { 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->dev_password_id = WPA_GET_BE16(attr.dev_password_id); 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Device Password ID: %d", 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->dev_password_id); 356cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt msg->dev_password_id_present = 1; 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (attr.primary_dev_type) { 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char devtype[WPS_DEV_TYPE_BUFSIZE]; 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_pri_dev_type = attr.primary_dev_type; 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Primary Device Type (WPS): %s", 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_dev_type_bin2str(msg->wps_pri_dev_type, devtype, 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(devtype))); 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (attr.sec_dev_type_list) { 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list = attr.sec_dev_type_list; 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_sec_dev_type_list_len = attr.sec_dev_type_list_len; 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_vendor_ext[i] = attr.vendor_ext[i]; 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_vendor_ext_len[i] = attr.vendor_ext_len[i]; 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->manufacturer = attr.manufacturer; 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->manufacturer_len = attr.manufacturer_len; 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_name = attr.model_name; 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_name_len = attr.model_name_len; 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_number = attr.model_number; 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->model_number_len = attr.model_number_len; 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->serial_number = attr.serial_number; 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->serial_number_len = attr.serial_number_len; 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 384cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt msg->oob_dev_password = attr.oob_dev_password; 385cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt msg->oob_dev_password_len = attr.oob_dev_password_len; 386cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_parse_ies - Parse P2P message IEs (both WPS and P2P IE) 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: IEs from the message 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of data buffer in octets 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @msg: Buffer for returning parsed attributes 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Note: Caller is responsible for clearing the msg data structure before 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * calling this function. 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Note: Caller must free temporary memory allocations by calling 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_parse_free() when the parsed data is not needed anymore. 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_parse_ies(const u8 *data, size_t len, struct p2p_message *msg) 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_11_elems elems; 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_11_parse_elems(data, len, &elems, 0); 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elems.ds_params && elems.ds_params_len >= 1) 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->ds_params = elems.ds_params; 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elems.ssid) 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->ssid = elems.ssid - 2; 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_attributes = ieee802_11_vendor_ie_concat(data, len, 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPS_DEV_OUI_WFA); 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->wps_attributes && 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_wps_ie(msg->wps_attributes, msg)) { 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(msg); 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->p2p_attributes = ieee802_11_vendor_ie_concat(data, len, 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt P2P_IE_VENDOR_TYPE); 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->p2p_attributes && 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_p2p_ie(msg->p2p_attributes, msg)) { 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to parse P2P IE data"); 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg->p2p_attributes) 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_buf(MSG_MSGDUMP, "P2P: P2P IE data", 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->p2p_attributes); 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p2p_parse_free(msg); 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 43561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (elems.wfd) { 43661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt msg->wfd_subelems = ieee802_11_vendor_ie_concat( 43761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt data, len, WFD_IE_VENDOR_TYPE); 43861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 43961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 44061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_parse - Parse a P2P Action frame contents 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Action frame payload after Category and Code fields 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of data buffer in octets 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @msg: Buffer for returning parsed attributes 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Note: Caller must free temporary memory allocations by calling 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_parse_free() when the parsed data is not needed anymore. 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_parse(const u8 *data, size_t len, struct p2p_message *msg) 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(msg, 0, sizeof(*msg)); 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Parsing the received message"); 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 1) { 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: No Dialog Token in the message"); 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->dialog_token = data[0]; 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: * Dialog Token: %d", msg->dialog_token); 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return p2p_parse_ies(data + 1, len - 1, msg); 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 470cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtint p2p_parse_ies_separate(const u8 *wsc, size_t wsc_len, const u8 *p2p, 471cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt size_t p2p_len, struct p2p_message *msg) 472cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{ 473cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt os_memset(msg, 0, sizeof(*msg)); 474cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 475cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt msg->wps_attributes = wpabuf_alloc_copy(wsc, wsc_len); 476cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (msg->wps_attributes && 477cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_parse_wps_ie(msg->wps_attributes, msg)) { 478cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_parse_free(msg); 479cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 480cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 481cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 482cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt msg->p2p_attributes = wpabuf_alloc_copy(p2p, p2p_len); 483cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (msg->p2p_attributes && 484cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_parse_p2p_ie(msg->p2p_attributes, msg)) { 485cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_printf(MSG_DEBUG, "P2P: Failed to parse P2P IE data"); 486cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt if (msg->p2p_attributes) 487cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt wpa_hexdump_buf(MSG_MSGDUMP, "P2P: P2P IE data", 488cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt msg->p2p_attributes); 489cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt p2p_parse_free(msg); 490cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return -1; 491cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt } 492cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 493cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt return 0; 494cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt} 495cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 496cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_parse_free - Free temporary data from P2P parsing 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @msg: Parsed attributes 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid p2p_parse_free(struct p2p_message *msg) 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(msg->p2p_attributes); 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->p2p_attributes = NULL; 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(msg->wps_attributes); 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg->wps_attributes = NULL; 50761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY 50861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpabuf_free(msg->wfd_subelems); 50961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt msg->wfd_subelems = NULL; 51061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */ 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_group_info_parse(const u8 *gi, size_t gi_len, 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_group_info *info) 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *g, *gend; 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(info, 0, sizeof(*info)); 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gi == NULL) 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt g = gi; 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gend = gi + gi_len; 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (g < gend) { 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_client_info *cli; 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *t, *cend; 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int count; 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli = &info->client[info->num_clients]; 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cend = g + 1 + g[0]; 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (cend > gend) 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; /* invalid data */ 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* g at start of P2P Client Info Descriptor */ 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* t at Device Capability Bitmap */ 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt t = g + 1 + 2 * ETH_ALEN; 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (t > cend) 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; /* invalid data */ 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->p2p_device_addr = g + 1; 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->p2p_interface_addr = g + 1 + ETH_ALEN; 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->dev_capab = t[0]; 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (t + 1 + 2 + 8 + 1 > cend) 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; /* invalid data */ 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->config_methods = WPA_GET_BE16(&t[1]); 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->pri_dev_type = &t[3]; 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt t += 1 + 2 + 8; 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* t at Number of Secondary Device Types */ 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->num_sec_dev_types = *t++; 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (t + 8 * cli->num_sec_dev_types > cend) 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; /* invalid data */ 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->sec_dev_types = t; 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt t += 8 * cli->num_sec_dev_types; 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* t at Device Name in WPS TLV format */ 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (t + 2 + 2 > cend) 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; /* invalid data */ 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (WPA_GET_BE16(t) != ATTR_DEV_NAME) 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; /* invalid Device Name TLV */ 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt t += 2; 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count = WPA_GET_BE16(t); 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt t += 2; 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (count > cend - t) 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; /* invalid Device Name TLV */ 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (count >= 32) 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count = 32; 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->dev_name = (const char *) t; 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->dev_name_len = count; 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt g = cend; 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt info->num_clients++; 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (info->num_clients == P2P_MAX_GROUP_ENTRIES) 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int p2p_group_info_text(const u8 *gi, size_t gi_len, char *buf, 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *end) 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pos = buf; 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_group_info info; 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int i; 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_group_info_parse(gi, gi_len, &info) < 0) 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < info.num_clients; i++) { 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_client_info *cli; 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char name[33]; 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char devtype[WPS_DEV_TYPE_BUFSIZE]; 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 s; 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int count; 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli = &info.client[i]; 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "p2p_group_client: " 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dev=" MACSTR " iface=" MACSTR, 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(cli->p2p_device_addr), 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(cli->p2p_interface_addr)); 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " dev_capab=0x%x config_methods=0x%x " 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "dev_type=%s", 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cli->dev_capab, cli->config_methods, 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_dev_type_bin2str(cli->pri_dev_type, 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt devtype, 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(devtype))); 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (s = 0; s < cli->num_sec_dev_types; s++) { 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, " dev_type=%s", 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_dev_type_bin2str( 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &cli->sec_dev_types[s * 8], 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt devtype, sizeof(devtype))); 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(name, cli->dev_name, cli->dev_name_len); 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name[cli->dev_name_len] = '\0'; 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count = (int) cli->dev_name_len - 1; 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (count >= 0) { 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (name[count] > 0 && name[count] < 32) 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name[count] = '_'; 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count--; 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, " dev_name='%s'\n", name); 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * p2p_attr_text - Build text format description of P2P IE attributes 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: P2P IE contents 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Buffer for returning text 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @end: Pointer to the end of the buf area 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of octets written to the buffer or -1 on faikure 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to parse P2P IE contents into text format 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * field=value lines. 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_attr_text(struct wpabuf *data, char *buf, char *end) 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pos = buf; 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_p2p_ie(data, &msg)) 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.capability) { 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "p2p_dev_capab=0x%x\n" 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "p2p_group_capab=0x%x\n", 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.capability[0], msg.capability[1]); 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.pri_dev_type) { 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char devtype[WPS_DEV_TYPE_BUFSIZE]; 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "p2p_primary_device_type=%s\n", 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_dev_type_bin2str(msg.pri_dev_type, 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt devtype, 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(devtype))); 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "p2p_device_name=%s\n", 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.device_name); 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.p2p_device_addr) { 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "p2p_device_addr=" MACSTR 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "\n", 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(msg.p2p_device_addr)); 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = os_snprintf(pos, end - pos, "p2p_config_methods=0x%x\n", 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg.config_methods); 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0 || ret >= end - pos) 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = p2p_group_info_text(msg.group_info, msg.group_info_len, 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, end); 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ret; 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos - buf; 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint p2p_get_cross_connect_disallowed(const struct wpabuf *p2p_ie) 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_p2p_ie(p2p_ie, &msg)) 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!msg.manageability) 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return !(msg.manageability[0] & P2P_MAN_CROSS_CONNECTION_PERMITTED); 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu8 p2p_get_group_capab(const struct wpabuf *p2p_ie) 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_p2p_ie(p2p_ie, &msg)) 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!msg.capability) 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return msg.capability[1]; 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * p2p_get_go_dev_addr(const struct wpabuf *p2p_ie) 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct p2p_message msg; 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&msg, 0, sizeof(msg)); 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p2p_parse_p2p_ie(p2p_ie, &msg)) 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.p2p_device_addr) 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return msg.p2p_device_addr; 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg.device_id) 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return msg.device_id; 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 768