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