1 /* 2 * P2P - IE parser 3 * Copyright (c) 2009-2010, Atheros Communications 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9 #include "includes.h" 10 11 #include "common.h" 12 #include "common/ieee802_11_defs.h" 13 #include "common/ieee802_11_common.h" 14 #include "wps/wps_i.h" 15 #include "p2p_i.h" 16 17 18 void p2p_copy_filter_devname(char *dst, size_t dst_len, 19 const void *src, size_t src_len) 20 { 21 size_t i; 22 23 if (src_len >= dst_len) 24 src_len = dst_len - 1; 25 os_memcpy(dst, src, src_len); 26 dst[src_len] = '\0'; 27 for (i = 0; i < src_len; i++) { 28 if (dst[i] == '\0') 29 break; 30 if (is_ctrl_char(dst[i])) 31 dst[i] = '_'; 32 } 33 } 34 35 36 static int p2p_parse_attribute(u8 id, const u8 *data, u16 len, 37 struct p2p_message *msg) 38 { 39 const u8 *pos; 40 u16 nlen; 41 char devtype[WPS_DEV_TYPE_BUFSIZE]; 42 43 switch (id) { 44 case P2P_ATTR_CAPABILITY: 45 if (len < 2) { 46 wpa_printf(MSG_DEBUG, "P2P: Too short Capability " 47 "attribute (length %d)", len); 48 return -1; 49 } 50 msg->capability = data; 51 wpa_printf(MSG_DEBUG, "P2P: * Device Capability %02x " 52 "Group Capability %02x", 53 data[0], data[1]); 54 break; 55 case P2P_ATTR_DEVICE_ID: 56 if (len < ETH_ALEN) { 57 wpa_printf(MSG_DEBUG, "P2P: Too short Device ID " 58 "attribute (length %d)", len); 59 return -1; 60 } 61 msg->device_id = data; 62 wpa_printf(MSG_DEBUG, "P2P: * Device ID " MACSTR, 63 MAC2STR(msg->device_id)); 64 break; 65 case P2P_ATTR_GROUP_OWNER_INTENT: 66 if (len < 1) { 67 wpa_printf(MSG_DEBUG, "P2P: Too short GO Intent " 68 "attribute (length %d)", len); 69 return -1; 70 } 71 msg->go_intent = data; 72 wpa_printf(MSG_DEBUG, "P2P: * GO Intent: Intent %u " 73 "Tie breaker %u", data[0] >> 1, data[0] & 0x01); 74 break; 75 case P2P_ATTR_STATUS: 76 if (len < 1) { 77 wpa_printf(MSG_DEBUG, "P2P: Too short Status " 78 "attribute (length %d)", len); 79 return -1; 80 } 81 msg->status = data; 82 wpa_printf(MSG_DEBUG, "P2P: * Status: %d", data[0]); 83 break; 84 case P2P_ATTR_LISTEN_CHANNEL: 85 if (len == 0) { 86 wpa_printf(MSG_DEBUG, "P2P: * Listen Channel: Ignore " 87 "null channel"); 88 break; 89 } 90 if (len < 5) { 91 wpa_printf(MSG_DEBUG, "P2P: Too short Listen Channel " 92 "attribute (length %d)", len); 93 return -1; 94 } 95 msg->listen_channel = data; 96 if (has_ctrl_char(data, 2)) { 97 wpa_printf(MSG_DEBUG, 98 "P2P: * Listen Channel: Country(binary) %02x %02x (0x%02x) Regulatory Class %d Channel Number %d", 99 data[0], data[1], data[2], data[3], data[4]); 100 break; 101 } 102 wpa_printf(MSG_DEBUG, "P2P: * Listen Channel: " 103 "Country %c%c(0x%02x) Regulatory " 104 "Class %d Channel Number %d", data[0], data[1], 105 data[2], data[3], data[4]); 106 break; 107 case P2P_ATTR_OPERATING_CHANNEL: 108 if (len == 0) { 109 wpa_printf(MSG_DEBUG, "P2P: * Operating Channel: " 110 "Ignore null channel"); 111 break; 112 } 113 if (len < 5) { 114 wpa_printf(MSG_DEBUG, "P2P: Too short Operating " 115 "Channel attribute (length %d)", len); 116 return -1; 117 } 118 msg->operating_channel = data; 119 if (has_ctrl_char(data, 2)) { 120 wpa_printf(MSG_DEBUG, 121 "P2P: * Operating Channel: Country(binary) %02x %02x (0x%02x) Regulatory Class %d Channel Number %d", 122 data[0], data[1], data[2], data[3], data[4]); 123 break; 124 } 125 wpa_printf(MSG_DEBUG, "P2P: * Operating Channel: " 126 "Country %c%c(0x%02x) Regulatory " 127 "Class %d Channel Number %d", data[0], data[1], 128 data[2], data[3], data[4]); 129 break; 130 case P2P_ATTR_CHANNEL_LIST: 131 if (len < 3) { 132 wpa_printf(MSG_DEBUG, "P2P: Too short Channel List " 133 "attribute (length %d)", len); 134 return -1; 135 } 136 msg->channel_list = data; 137 msg->channel_list_len = len; 138 if (has_ctrl_char(data, 2)) { 139 wpa_printf(MSG_DEBUG, 140 "P2P: * Channel List: Country String (binary) %02x %02x (0x%02x)", 141 data[0], data[1], data[2]); 142 } else { 143 wpa_printf(MSG_DEBUG, 144 "P2P: * Channel List: Country String '%c%c(0x%02x)'", 145 data[0], data[1], data[2]); 146 } 147 wpa_hexdump(MSG_MSGDUMP, "P2P: Channel List", 148 msg->channel_list, msg->channel_list_len); 149 break; 150 case P2P_ATTR_GROUP_INFO: 151 msg->group_info = data; 152 msg->group_info_len = len; 153 wpa_printf(MSG_DEBUG, "P2P: * Group Info"); 154 break; 155 case P2P_ATTR_DEVICE_INFO: 156 if (len < ETH_ALEN + 2 + 8 + 1) { 157 wpa_printf(MSG_DEBUG, "P2P: Too short Device Info " 158 "attribute (length %d)", len); 159 return -1; 160 } 161 msg->p2p_device_info = data; 162 msg->p2p_device_info_len = len; 163 pos = data; 164 msg->p2p_device_addr = pos; 165 pos += ETH_ALEN; 166 msg->config_methods = WPA_GET_BE16(pos); 167 pos += 2; 168 msg->pri_dev_type = pos; 169 pos += 8; 170 msg->num_sec_dev_types = *pos++; 171 if (msg->num_sec_dev_types * 8 > data + len - pos) { 172 wpa_printf(MSG_DEBUG, "P2P: Device Info underflow"); 173 return -1; 174 } 175 pos += msg->num_sec_dev_types * 8; 176 if (data + len - pos < 4) { 177 wpa_printf(MSG_DEBUG, "P2P: Invalid Device Name " 178 "length %d", (int) (data + len - pos)); 179 return -1; 180 } 181 if (WPA_GET_BE16(pos) != ATTR_DEV_NAME) { 182 wpa_hexdump(MSG_DEBUG, "P2P: Unexpected Device Name " 183 "header", pos, 4); 184 return -1; 185 } 186 pos += 2; 187 nlen = WPA_GET_BE16(pos); 188 pos += 2; 189 if (nlen > data + len - pos || nlen > WPS_DEV_NAME_MAX_LEN) { 190 wpa_printf(MSG_DEBUG, "P2P: Invalid Device Name " 191 "length %u (buf len %d)", nlen, 192 (int) (data + len - pos)); 193 return -1; 194 } 195 p2p_copy_filter_devname(msg->device_name, 196 sizeof(msg->device_name), pos, nlen); 197 wpa_printf(MSG_DEBUG, "P2P: * Device Info: addr " MACSTR 198 " primary device type %s device name '%s' " 199 "config methods 0x%x", 200 MAC2STR(msg->p2p_device_addr), 201 wps_dev_type_bin2str(msg->pri_dev_type, devtype, 202 sizeof(devtype)), 203 msg->device_name, msg->config_methods); 204 break; 205 case P2P_ATTR_CONFIGURATION_TIMEOUT: 206 if (len < 2) { 207 wpa_printf(MSG_DEBUG, "P2P: Too short Configuration " 208 "Timeout attribute (length %d)", len); 209 return -1; 210 } 211 msg->config_timeout = data; 212 wpa_printf(MSG_DEBUG, "P2P: * Configuration Timeout"); 213 break; 214 case P2P_ATTR_INTENDED_INTERFACE_ADDR: 215 if (len < ETH_ALEN) { 216 wpa_printf(MSG_DEBUG, "P2P: Too short Intended P2P " 217 "Interface Address attribute (length %d)", 218 len); 219 return -1; 220 } 221 msg->intended_addr = data; 222 wpa_printf(MSG_DEBUG, "P2P: * Intended P2P Interface Address: " 223 MACSTR, MAC2STR(msg->intended_addr)); 224 break; 225 case P2P_ATTR_GROUP_BSSID: 226 if (len < ETH_ALEN) { 227 wpa_printf(MSG_DEBUG, "P2P: Too short P2P Group BSSID " 228 "attribute (length %d)", len); 229 return -1; 230 } 231 msg->group_bssid = data; 232 wpa_printf(MSG_DEBUG, "P2P: * P2P Group BSSID: " MACSTR, 233 MAC2STR(msg->group_bssid)); 234 break; 235 case P2P_ATTR_GROUP_ID: 236 if (len < ETH_ALEN || len > ETH_ALEN + SSID_MAX_LEN) { 237 wpa_printf(MSG_DEBUG, "P2P: Invalid P2P Group ID " 238 "attribute length %d", len); 239 return -1; 240 } 241 msg->group_id = data; 242 msg->group_id_len = len; 243 wpa_printf(MSG_DEBUG, "P2P: * P2P Group ID: Device Address " 244 MACSTR, MAC2STR(msg->group_id)); 245 wpa_hexdump_ascii(MSG_DEBUG, "P2P: * P2P Group ID: SSID", 246 msg->group_id + ETH_ALEN, 247 msg->group_id_len - ETH_ALEN); 248 break; 249 case P2P_ATTR_INVITATION_FLAGS: 250 if (len < 1) { 251 wpa_printf(MSG_DEBUG, "P2P: Too short Invitation " 252 "Flag attribute (length %d)", len); 253 return -1; 254 } 255 msg->invitation_flags = data; 256 wpa_printf(MSG_DEBUG, "P2P: * Invitation Flags: bitmap 0x%x", 257 data[0]); 258 break; 259 case P2P_ATTR_MANAGEABILITY: 260 if (len < 1) { 261 wpa_printf(MSG_DEBUG, "P2P: Too short Manageability " 262 "attribute (length %d)", len); 263 return -1; 264 } 265 msg->manageability = data; 266 wpa_printf(MSG_DEBUG, "P2P: * Manageability: bitmap 0x%x", 267 data[0]); 268 break; 269 case P2P_ATTR_NOTICE_OF_ABSENCE: 270 if (len < 2) { 271 wpa_printf(MSG_DEBUG, "P2P: Too short Notice of " 272 "Absence attribute (length %d)", len); 273 return -1; 274 } 275 msg->noa = data; 276 msg->noa_len = len; 277 wpa_printf(MSG_DEBUG, "P2P: * Notice of Absence"); 278 break; 279 case P2P_ATTR_EXT_LISTEN_TIMING: 280 if (len < 4) { 281 wpa_printf(MSG_DEBUG, "P2P: Too short Extended Listen " 282 "Timing attribute (length %d)", len); 283 return -1; 284 } 285 msg->ext_listen_timing = data; 286 wpa_printf(MSG_DEBUG, "P2P: * Extended Listen Timing " 287 "(period %u msec interval %u msec)", 288 WPA_GET_LE16(msg->ext_listen_timing), 289 WPA_GET_LE16(msg->ext_listen_timing + 2)); 290 break; 291 case P2P_ATTR_MINOR_REASON_CODE: 292 if (len < 1) { 293 wpa_printf(MSG_DEBUG, "P2P: Too short Minor Reason " 294 "Code attribute (length %d)", len); 295 return -1; 296 } 297 msg->minor_reason_code = data; 298 wpa_printf(MSG_DEBUG, "P2P: * Minor Reason Code: %u", 299 *msg->minor_reason_code); 300 break; 301 case P2P_ATTR_OOB_GO_NEG_CHANNEL: 302 if (len < 6) { 303 wpa_printf(MSG_DEBUG, "P2P: Too short OOB GO Neg " 304 "Channel attribute (length %d)", len); 305 return -1; 306 } 307 msg->oob_go_neg_channel = data; 308 wpa_printf(MSG_DEBUG, "P2P: * OOB GO Neg Channel: " 309 "Country %c%c(0x%02x) Operating Class %d " 310 "Channel Number %d Role %d", 311 data[0], data[1], data[2], data[3], data[4], 312 data[5]); 313 break; 314 case P2P_ATTR_SERVICE_HASH: 315 if (len < P2PS_HASH_LEN) { 316 wpa_printf(MSG_DEBUG, 317 "P2P: Too short Service Hash (length %u)", 318 len); 319 return -1; 320 } 321 msg->service_hash_count = len / P2PS_HASH_LEN; 322 msg->service_hash = data; 323 wpa_hexdump(MSG_DEBUG, "P2P: * Service Hash(s)", data, len); 324 break; 325 case P2P_ATTR_SESSION_INFORMATION_DATA: 326 msg->session_info = data; 327 msg->session_info_len = len; 328 wpa_printf(MSG_DEBUG, "P2P: * Service Instance: %u bytes - %p", 329 len, data); 330 break; 331 case P2P_ATTR_CONNECTION_CAPABILITY: 332 if (len < 1) { 333 wpa_printf(MSG_DEBUG, 334 "P2P: Too short Connection Capability (length %u)", 335 len); 336 return -1; 337 } 338 msg->conn_cap = data; 339 wpa_printf(MSG_DEBUG, "P2P: * Connection Capability: 0x%x", 340 *msg->conn_cap); 341 break; 342 case P2P_ATTR_ADVERTISEMENT_ID: 343 if (len < 10) { 344 wpa_printf(MSG_DEBUG, 345 "P2P: Too short Advertisement ID (length %u)", 346 len); 347 return -1; 348 } 349 msg->adv_id = data; 350 msg->adv_mac = &data[sizeof(u32)]; 351 wpa_printf(MSG_DEBUG, "P2P: * Advertisement ID %x", 352 WPA_GET_LE32(data)); 353 break; 354 case P2P_ATTR_ADVERTISED_SERVICE: 355 if (len < 8) { 356 wpa_printf(MSG_DEBUG, 357 "P2P: Too short Service Instance (length %u)", 358 len); 359 return -1; 360 } 361 msg->adv_service_instance = data; 362 msg->adv_service_instance_len = len; 363 if (len <= 255 + 8) { 364 char str[256]; 365 u8 namelen; 366 367 namelen = data[6]; 368 if (namelen > len - 7) 369 break; 370 os_memcpy(str, &data[7], namelen); 371 str[namelen] = '\0'; 372 wpa_printf(MSG_DEBUG, "P2P: * Service Instance: %x-%s", 373 WPA_GET_LE32(data), str); 374 } else { 375 wpa_printf(MSG_DEBUG, "P2P: * Service Instance: %p", 376 data); 377 } 378 break; 379 case P2P_ATTR_SESSION_ID: 380 if (len < sizeof(u32) + ETH_ALEN) { 381 wpa_printf(MSG_DEBUG, 382 "P2P: Too short Session ID Info (length %u)", 383 len); 384 return -1; 385 } 386 msg->session_id = data; 387 msg->session_mac = &data[sizeof(u32)]; 388 wpa_printf(MSG_DEBUG, "P2P: * Session ID: %x " MACSTR, 389 WPA_GET_LE32(data), MAC2STR(msg->session_mac)); 390 break; 391 case P2P_ATTR_FEATURE_CAPABILITY: 392 if (!len) { 393 wpa_printf(MSG_DEBUG, 394 "P2P: Too short Feature Capability (length %u)", 395 len); 396 return -1; 397 } 398 msg->feature_cap = data; 399 msg->feature_cap_len = len; 400 wpa_printf(MSG_DEBUG, "P2P: * Feature Cap (length=%u)", len); 401 break; 402 case P2P_ATTR_PERSISTENT_GROUP: 403 { 404 if (len < ETH_ALEN || len > ETH_ALEN + SSID_MAX_LEN) { 405 wpa_printf(MSG_DEBUG, 406 "P2P: Invalid Persistent Group Info (length %u)", 407 len); 408 return -1; 409 } 410 411 msg->persistent_dev = data; 412 msg->persistent_ssid_len = len - ETH_ALEN; 413 msg->persistent_ssid = &data[ETH_ALEN]; 414 wpa_printf(MSG_DEBUG, "P2P: * Persistent Group: " MACSTR " %s", 415 MAC2STR(msg->persistent_dev), 416 wpa_ssid_txt(msg->persistent_ssid, 417 msg->persistent_ssid_len)); 418 break; 419 } 420 default: 421 wpa_printf(MSG_DEBUG, "P2P: Skipped unknown attribute %d " 422 "(length %d)", id, len); 423 break; 424 } 425 426 return 0; 427 } 428 429 430 /** 431 * p2p_parse_p2p_ie - Parse P2P IE 432 * @buf: Concatenated P2P IE(s) payload 433 * @msg: Buffer for returning parsed attributes 434 * Returns: 0 on success, -1 on failure 435 * 436 * Note: Caller is responsible for clearing the msg data structure before 437 * calling this function. 438 */ 439 int p2p_parse_p2p_ie(const struct wpabuf *buf, struct p2p_message *msg) 440 { 441 const u8 *pos = wpabuf_head_u8(buf); 442 const u8 *end = pos + wpabuf_len(buf); 443 444 wpa_printf(MSG_DEBUG, "P2P: Parsing P2P IE"); 445 446 while (pos < end) { 447 u16 attr_len; 448 u8 id; 449 450 if (end - pos < 3) { 451 wpa_printf(MSG_DEBUG, "P2P: Invalid P2P attribute"); 452 return -1; 453 } 454 id = *pos++; 455 attr_len = WPA_GET_LE16(pos); 456 pos += 2; 457 wpa_printf(MSG_DEBUG, "P2P: Attribute %d length %u", 458 id, attr_len); 459 if (attr_len > end - pos) { 460 wpa_printf(MSG_DEBUG, "P2P: Attribute underflow " 461 "(len=%u left=%d)", 462 attr_len, (int) (end - pos)); 463 wpa_hexdump(MSG_MSGDUMP, "P2P: Data", pos, end - pos); 464 return -1; 465 } 466 if (p2p_parse_attribute(id, pos, attr_len, msg)) 467 return -1; 468 pos += attr_len; 469 } 470 471 return 0; 472 } 473 474 475 static int p2p_parse_wps_ie(const struct wpabuf *buf, struct p2p_message *msg) 476 { 477 struct wps_parse_attr attr; 478 int i; 479 480 wpa_printf(MSG_DEBUG, "P2P: Parsing WPS IE"); 481 if (wps_parse_msg(buf, &attr)) 482 return -1; 483 if (attr.dev_name && attr.dev_name_len < sizeof(msg->device_name) && 484 !msg->device_name[0]) 485 os_memcpy(msg->device_name, attr.dev_name, attr.dev_name_len); 486 if (attr.config_methods) { 487 msg->wps_config_methods = 488 WPA_GET_BE16(attr.config_methods); 489 wpa_printf(MSG_DEBUG, "P2P: Config Methods (WPS): 0x%x", 490 msg->wps_config_methods); 491 } 492 if (attr.dev_password_id) { 493 msg->dev_password_id = WPA_GET_BE16(attr.dev_password_id); 494 wpa_printf(MSG_DEBUG, "P2P: Device Password ID: %d", 495 msg->dev_password_id); 496 msg->dev_password_id_present = 1; 497 } 498 if (attr.primary_dev_type) { 499 char devtype[WPS_DEV_TYPE_BUFSIZE]; 500 msg->wps_pri_dev_type = attr.primary_dev_type; 501 wpa_printf(MSG_DEBUG, "P2P: Primary Device Type (WPS): %s", 502 wps_dev_type_bin2str(msg->wps_pri_dev_type, devtype, 503 sizeof(devtype))); 504 } 505 if (attr.sec_dev_type_list) { 506 msg->wps_sec_dev_type_list = attr.sec_dev_type_list; 507 msg->wps_sec_dev_type_list_len = attr.sec_dev_type_list_len; 508 } 509 510 for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 511 msg->wps_vendor_ext[i] = attr.vendor_ext[i]; 512 msg->wps_vendor_ext_len[i] = attr.vendor_ext_len[i]; 513 } 514 515 msg->manufacturer = attr.manufacturer; 516 msg->manufacturer_len = attr.manufacturer_len; 517 msg->model_name = attr.model_name; 518 msg->model_name_len = attr.model_name_len; 519 msg->model_number = attr.model_number; 520 msg->model_number_len = attr.model_number_len; 521 msg->serial_number = attr.serial_number; 522 msg->serial_number_len = attr.serial_number_len; 523 524 msg->oob_dev_password = attr.oob_dev_password; 525 msg->oob_dev_password_len = attr.oob_dev_password_len; 526 527 return 0; 528 } 529 530 531 /** 532 * p2p_parse_ies - Parse P2P message IEs (both WPS and P2P IE) 533 * @data: IEs from the message 534 * @len: Length of data buffer in octets 535 * @msg: Buffer for returning parsed attributes 536 * Returns: 0 on success, -1 on failure 537 * 538 * Note: Caller is responsible for clearing the msg data structure before 539 * calling this function. 540 * 541 * Note: Caller must free temporary memory allocations by calling 542 * p2p_parse_free() when the parsed data is not needed anymore. 543 */ 544 int p2p_parse_ies(const u8 *data, size_t len, struct p2p_message *msg) 545 { 546 struct ieee802_11_elems elems; 547 548 if (ieee802_11_parse_elems(data, len, &elems, 0) == ParseFailed) 549 return -1; 550 551 if (elems.ds_params) 552 msg->ds_params = elems.ds_params; 553 if (elems.ssid) 554 msg->ssid = elems.ssid - 2; 555 556 msg->wps_attributes = ieee802_11_vendor_ie_concat(data, len, 557 WPS_DEV_OUI_WFA); 558 if (msg->wps_attributes && 559 p2p_parse_wps_ie(msg->wps_attributes, msg)) { 560 p2p_parse_free(msg); 561 return -1; 562 } 563 564 msg->p2p_attributes = ieee802_11_vendor_ie_concat(data, len, 565 P2P_IE_VENDOR_TYPE); 566 if (msg->p2p_attributes && 567 p2p_parse_p2p_ie(msg->p2p_attributes, msg)) { 568 wpa_printf(MSG_DEBUG, "P2P: Failed to parse P2P IE data"); 569 if (msg->p2p_attributes) 570 wpa_hexdump_buf(MSG_MSGDUMP, "P2P: P2P IE data", 571 msg->p2p_attributes); 572 p2p_parse_free(msg); 573 return -1; 574 } 575 576 #ifdef CONFIG_WIFI_DISPLAY 577 if (elems.wfd) { 578 msg->wfd_subelems = ieee802_11_vendor_ie_concat( 579 data, len, WFD_IE_VENDOR_TYPE); 580 } 581 #endif /* CONFIG_WIFI_DISPLAY */ 582 583 msg->pref_freq_list = elems.pref_freq_list; 584 msg->pref_freq_list_len = elems.pref_freq_list_len; 585 586 return 0; 587 } 588 589 590 /** 591 * p2p_parse - Parse a P2P Action frame contents 592 * @data: Action frame payload after Category and Code fields 593 * @len: Length of data buffer in octets 594 * @msg: Buffer for returning parsed attributes 595 * Returns: 0 on success, -1 on failure 596 * 597 * Note: Caller must free temporary memory allocations by calling 598 * p2p_parse_free() when the parsed data is not needed anymore. 599 */ 600 int p2p_parse(const u8 *data, size_t len, struct p2p_message *msg) 601 { 602 os_memset(msg, 0, sizeof(*msg)); 603 wpa_printf(MSG_DEBUG, "P2P: Parsing the received message"); 604 if (len < 1) { 605 wpa_printf(MSG_DEBUG, "P2P: No Dialog Token in the message"); 606 return -1; 607 } 608 msg->dialog_token = data[0]; 609 wpa_printf(MSG_DEBUG, "P2P: * Dialog Token: %d", msg->dialog_token); 610 611 return p2p_parse_ies(data + 1, len - 1, msg); 612 } 613 614 615 int p2p_parse_ies_separate(const u8 *wsc, size_t wsc_len, const u8 *p2p, 616 size_t p2p_len, struct p2p_message *msg) 617 { 618 os_memset(msg, 0, sizeof(*msg)); 619 620 msg->wps_attributes = wpabuf_alloc_copy(wsc, wsc_len); 621 if (msg->wps_attributes && 622 p2p_parse_wps_ie(msg->wps_attributes, msg)) { 623 p2p_parse_free(msg); 624 return -1; 625 } 626 627 msg->p2p_attributes = wpabuf_alloc_copy(p2p, p2p_len); 628 if (msg->p2p_attributes && 629 p2p_parse_p2p_ie(msg->p2p_attributes, msg)) { 630 wpa_printf(MSG_DEBUG, "P2P: Failed to parse P2P IE data"); 631 if (msg->p2p_attributes) 632 wpa_hexdump_buf(MSG_MSGDUMP, "P2P: P2P IE data", 633 msg->p2p_attributes); 634 p2p_parse_free(msg); 635 return -1; 636 } 637 638 return 0; 639 } 640 641 642 /** 643 * p2p_parse_free - Free temporary data from P2P parsing 644 * @msg: Parsed attributes 645 */ 646 void p2p_parse_free(struct p2p_message *msg) 647 { 648 wpabuf_free(msg->p2p_attributes); 649 msg->p2p_attributes = NULL; 650 wpabuf_free(msg->wps_attributes); 651 msg->wps_attributes = NULL; 652 #ifdef CONFIG_WIFI_DISPLAY 653 wpabuf_free(msg->wfd_subelems); 654 msg->wfd_subelems = NULL; 655 #endif /* CONFIG_WIFI_DISPLAY */ 656 } 657 658 659 int p2p_group_info_parse(const u8 *gi, size_t gi_len, 660 struct p2p_group_info *info) 661 { 662 const u8 *g, *gend; 663 664 os_memset(info, 0, sizeof(*info)); 665 if (gi == NULL) 666 return 0; 667 668 g = gi; 669 gend = gi + gi_len; 670 while (g < gend) { 671 struct p2p_client_info *cli; 672 const u8 *cend; 673 u16 count; 674 u8 len; 675 676 cli = &info->client[info->num_clients]; 677 len = *g++; 678 if (len > gend - g || len < 2 * ETH_ALEN + 1 + 2 + 8 + 1) 679 return -1; /* invalid data */ 680 cend = g + len; 681 /* g at start of P2P Client Info Descriptor */ 682 cli->p2p_device_addr = g; 683 g += ETH_ALEN; 684 cli->p2p_interface_addr = g; 685 g += ETH_ALEN; 686 cli->dev_capab = *g++; 687 688 cli->config_methods = WPA_GET_BE16(g); 689 g += 2; 690 cli->pri_dev_type = g; 691 g += 8; 692 693 /* g at Number of Secondary Device Types */ 694 len = *g++; 695 if (8 * len > cend - g) 696 return -1; /* invalid data */ 697 cli->num_sec_dev_types = len; 698 cli->sec_dev_types = g; 699 g += 8 * len; 700 701 /* g at Device Name in WPS TLV format */ 702 if (cend - g < 2 + 2) 703 return -1; /* invalid data */ 704 if (WPA_GET_BE16(g) != ATTR_DEV_NAME) 705 return -1; /* invalid Device Name TLV */ 706 g += 2; 707 count = WPA_GET_BE16(g); 708 g += 2; 709 if (count > cend - g) 710 return -1; /* invalid Device Name TLV */ 711 if (count >= WPS_DEV_NAME_MAX_LEN) 712 count = WPS_DEV_NAME_MAX_LEN; 713 cli->dev_name = (const char *) g; 714 cli->dev_name_len = count; 715 716 g = cend; 717 718 info->num_clients++; 719 if (info->num_clients == P2P_MAX_GROUP_ENTRIES) 720 return -1; 721 } 722 723 return 0; 724 } 725 726 727 static int p2p_group_info_text(const u8 *gi, size_t gi_len, char *buf, 728 char *end) 729 { 730 char *pos = buf; 731 int ret; 732 struct p2p_group_info info; 733 unsigned int i; 734 735 if (p2p_group_info_parse(gi, gi_len, &info) < 0) 736 return 0; 737 738 for (i = 0; i < info.num_clients; i++) { 739 struct p2p_client_info *cli; 740 char name[WPS_DEV_NAME_MAX_LEN + 1]; 741 char devtype[WPS_DEV_TYPE_BUFSIZE]; 742 u8 s; 743 int count; 744 745 cli = &info.client[i]; 746 ret = os_snprintf(pos, end - pos, "p2p_group_client: " 747 "dev=" MACSTR " iface=" MACSTR, 748 MAC2STR(cli->p2p_device_addr), 749 MAC2STR(cli->p2p_interface_addr)); 750 if (os_snprintf_error(end - pos, ret)) 751 return pos - buf; 752 pos += ret; 753 754 ret = os_snprintf(pos, end - pos, 755 " dev_capab=0x%x config_methods=0x%x " 756 "dev_type=%s", 757 cli->dev_capab, cli->config_methods, 758 wps_dev_type_bin2str(cli->pri_dev_type, 759 devtype, 760 sizeof(devtype))); 761 if (os_snprintf_error(end - pos, ret)) 762 return pos - buf; 763 pos += ret; 764 765 for (s = 0; s < cli->num_sec_dev_types; s++) { 766 ret = os_snprintf(pos, end - pos, " dev_type=%s", 767 wps_dev_type_bin2str( 768 &cli->sec_dev_types[s * 8], 769 devtype, sizeof(devtype))); 770 if (os_snprintf_error(end - pos, ret)) 771 return pos - buf; 772 pos += ret; 773 } 774 775 os_memcpy(name, cli->dev_name, cli->dev_name_len); 776 name[cli->dev_name_len] = '\0'; 777 count = (int) cli->dev_name_len - 1; 778 while (count >= 0) { 779 if (is_ctrl_char(name[count])) 780 name[count] = '_'; 781 count--; 782 } 783 784 ret = os_snprintf(pos, end - pos, " dev_name='%s'\n", name); 785 if (os_snprintf_error(end - pos, ret)) 786 return pos - buf; 787 pos += ret; 788 } 789 790 return pos - buf; 791 } 792 793 794 /** 795 * p2p_attr_text - Build text format description of P2P IE attributes 796 * @data: P2P IE contents 797 * @buf: Buffer for returning text 798 * @end: Pointer to the end of the buf area 799 * Returns: Number of octets written to the buffer or -1 on faikure 800 * 801 * This function can be used to parse P2P IE contents into text format 802 * field=value lines. 803 */ 804 int p2p_attr_text(struct wpabuf *data, char *buf, char *end) 805 { 806 struct p2p_message msg; 807 char *pos = buf; 808 int ret; 809 810 os_memset(&msg, 0, sizeof(msg)); 811 if (p2p_parse_p2p_ie(data, &msg)) 812 return -1; 813 814 if (msg.capability) { 815 ret = os_snprintf(pos, end - pos, 816 "p2p_dev_capab=0x%x\n" 817 "p2p_group_capab=0x%x\n", 818 msg.capability[0], msg.capability[1]); 819 if (os_snprintf_error(end - pos, ret)) 820 return pos - buf; 821 pos += ret; 822 } 823 824 if (msg.pri_dev_type) { 825 char devtype[WPS_DEV_TYPE_BUFSIZE]; 826 ret = os_snprintf(pos, end - pos, 827 "p2p_primary_device_type=%s\n", 828 wps_dev_type_bin2str(msg.pri_dev_type, 829 devtype, 830 sizeof(devtype))); 831 if (os_snprintf_error(end - pos, ret)) 832 return pos - buf; 833 pos += ret; 834 } 835 836 ret = os_snprintf(pos, end - pos, "p2p_device_name=%s\n", 837 msg.device_name); 838 if (os_snprintf_error(end - pos, ret)) 839 return pos - buf; 840 pos += ret; 841 842 if (msg.p2p_device_addr) { 843 ret = os_snprintf(pos, end - pos, "p2p_device_addr=" MACSTR 844 "\n", 845 MAC2STR(msg.p2p_device_addr)); 846 if (os_snprintf_error(end - pos, ret)) 847 return pos - buf; 848 pos += ret; 849 } 850 851 ret = os_snprintf(pos, end - pos, "p2p_config_methods=0x%x\n", 852 msg.config_methods); 853 if (os_snprintf_error(end - pos, ret)) 854 return pos - buf; 855 pos += ret; 856 857 ret = p2p_group_info_text(msg.group_info, msg.group_info_len, 858 pos, end); 859 if (ret < 0) 860 return pos - buf; 861 pos += ret; 862 863 return pos - buf; 864 } 865 866 867 int p2p_get_cross_connect_disallowed(const struct wpabuf *p2p_ie) 868 { 869 struct p2p_message msg; 870 871 os_memset(&msg, 0, sizeof(msg)); 872 if (p2p_parse_p2p_ie(p2p_ie, &msg)) 873 return 0; 874 875 if (!msg.manageability) 876 return 0; 877 878 return !(msg.manageability[0] & P2P_MAN_CROSS_CONNECTION_PERMITTED); 879 } 880 881 882 u8 p2p_get_group_capab(const struct wpabuf *p2p_ie) 883 { 884 struct p2p_message msg; 885 886 os_memset(&msg, 0, sizeof(msg)); 887 if (p2p_parse_p2p_ie(p2p_ie, &msg)) 888 return 0; 889 890 if (!msg.capability) 891 return 0; 892 893 return msg.capability[1]; 894 } 895 896 897 const u8 * p2p_get_go_dev_addr(const struct wpabuf *p2p_ie) 898 { 899 struct p2p_message msg; 900 901 os_memset(&msg, 0, sizeof(msg)); 902 if (p2p_parse_p2p_ie(p2p_ie, &msg)) 903 return NULL; 904 905 if (msg.p2p_device_addr) 906 return msg.p2p_device_addr; 907 if (msg.device_id) 908 return msg.device_id; 909 910 return NULL; 911 } 912