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 p2p_copy_filter_devname(char * dst,size_t dst_len,const void * src,size_t src_len)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 p2p_parse_attribute(u8 id,const u8 * data,u16 len,struct p2p_message * msg)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 case P2P_ATTR_CAPABILITY_EXTENSION: 421 if (len < 2) { 422 wpa_printf(MSG_DEBUG, "P2P: Too short PCEA (length %d)", 423 len); 424 return -1; 425 } 426 msg->pcea_info = data; 427 msg->pcea_info_len = len; 428 wpa_printf(MSG_DEBUG, "P2P: * PCEA (length=%u)", len); 429 break; 430 case P2P_ATTR_PAIRING_AND_BOOTSTRAPPING: 431 if (len < 1) { 432 wpa_printf(MSG_DEBUG, "P2P: Too short PBMA (length %d)", 433 len); 434 return -1; 435 } 436 msg->pbma_info = data; 437 msg->pbma_info_len = len; 438 wpa_printf(MSG_DEBUG, "P2P: * PBMA (length=%u)", len); 439 break; 440 case P2P_ATTR_ACTION_FRAME_WRAPPER: 441 if (len < 2) { 442 wpa_printf(MSG_DEBUG, 443 "P2P: Too short Action Frame Wrapper attribute (length %d)", 444 len); 445 return -1; 446 } 447 msg->action_frame_wrapper = data; 448 msg->action_frame_wrapper_len = len; 449 wpa_printf(MSG_DEBUG, "P2P: * Action frame wrapper (length=%u)", 450 len); 451 break; 452 case P2P_ATTR_DEVICE_IDENTITY_RESOLUTION: 453 if (len < 1) { 454 wpa_printf(MSG_DEBUG, "P2P: Too short DIRA (length %d)", 455 len); 456 return -1; 457 } 458 msg->dira = data; 459 msg->dira_len = len; 460 wpa_printf(MSG_DEBUG, "P2P: * DIRA (length=%u)", len); 461 break; 462 case P2P_ATTR_WLAN_AP_INFORMATION: 463 /* One or more AP Info fields (each being 12 octets) is required 464 * to be included. */ 465 if (len < 12) { 466 wpa_printf(MSG_DEBUG, 467 "P2P: Too short WLAN AP info (length %d)", 468 len); 469 return -1; 470 } 471 msg->wlan_ap_info = data; 472 msg->wlan_ap_info_len = len; 473 break; 474 default: 475 wpa_printf(MSG_DEBUG, "P2P: Skipped unknown attribute %d " 476 "(length %d)", id, len); 477 break; 478 } 479 480 return 0; 481 } 482 483 484 /** 485 * p2p_parse_p2p_ie - Parse P2P IE 486 * @buf: Concatenated P2P IE(s) payload 487 * @msg: Buffer for returning parsed attributes 488 * Returns: 0 on success, -1 on failure 489 * 490 * Note: Caller is responsible for clearing the msg data structure before 491 * calling this function. 492 */ p2p_parse_p2p_ie(const struct wpabuf * buf,struct p2p_message * msg)493 int p2p_parse_p2p_ie(const struct wpabuf *buf, struct p2p_message *msg) 494 { 495 const u8 *pos = wpabuf_head_u8(buf); 496 const u8 *end = pos + wpabuf_len(buf); 497 498 wpa_printf(MSG_DEBUG, "P2P: Parsing P2P IE"); 499 500 while (pos < end) { 501 u16 attr_len; 502 u8 id; 503 504 if (end - pos < 3) { 505 wpa_printf(MSG_DEBUG, "P2P: Invalid P2P attribute"); 506 return -1; 507 } 508 id = *pos++; 509 attr_len = WPA_GET_LE16(pos); 510 pos += 2; 511 wpa_printf(MSG_DEBUG, "P2P: Attribute %d length %u", 512 id, attr_len); 513 if (attr_len > end - pos) { 514 wpa_printf(MSG_DEBUG, "P2P: Attribute underflow " 515 "(len=%u left=%d)", 516 attr_len, (int) (end - pos)); 517 wpa_hexdump(MSG_MSGDUMP, "P2P: Data", pos, end - pos); 518 return -1; 519 } 520 if (p2p_parse_attribute(id, pos, attr_len, msg)) 521 return -1; 522 pos += attr_len; 523 } 524 525 return 0; 526 } 527 528 p2p_parse_wps_ie(const struct wpabuf * buf,struct p2p_message * msg)529 static int p2p_parse_wps_ie(const struct wpabuf *buf, struct p2p_message *msg) 530 { 531 struct wps_parse_attr attr; 532 int i; 533 534 wpa_printf(MSG_DEBUG, "P2P: Parsing WPS IE"); 535 if (wps_parse_msg(buf, &attr)) 536 return -1; 537 if (attr.dev_name && attr.dev_name_len < sizeof(msg->device_name) && 538 !msg->device_name[0]) 539 os_memcpy(msg->device_name, attr.dev_name, attr.dev_name_len); 540 if (attr.config_methods) { 541 msg->wps_config_methods = 542 WPA_GET_BE16(attr.config_methods); 543 wpa_printf(MSG_DEBUG, "P2P: Config Methods (WPS): 0x%x", 544 msg->wps_config_methods); 545 } 546 if (attr.dev_password_id) { 547 msg->dev_password_id = WPA_GET_BE16(attr.dev_password_id); 548 wpa_printf(MSG_DEBUG, "P2P: Device Password ID: %d", 549 msg->dev_password_id); 550 msg->dev_password_id_present = 1; 551 } 552 if (attr.primary_dev_type) { 553 char devtype[WPS_DEV_TYPE_BUFSIZE]; 554 msg->wps_pri_dev_type = attr.primary_dev_type; 555 wpa_printf(MSG_DEBUG, "P2P: Primary Device Type (WPS): %s", 556 wps_dev_type_bin2str(msg->wps_pri_dev_type, devtype, 557 sizeof(devtype))); 558 } 559 if (attr.sec_dev_type_list) { 560 msg->wps_sec_dev_type_list = attr.sec_dev_type_list; 561 msg->wps_sec_dev_type_list_len = attr.sec_dev_type_list_len; 562 } 563 564 for (i = 0; i < P2P_MAX_WPS_VENDOR_EXT; i++) { 565 msg->wps_vendor_ext[i] = attr.vendor_ext[i]; 566 msg->wps_vendor_ext_len[i] = attr.vendor_ext_len[i]; 567 } 568 569 msg->manufacturer = attr.manufacturer; 570 msg->manufacturer_len = attr.manufacturer_len; 571 msg->model_name = attr.model_name; 572 msg->model_name_len = attr.model_name_len; 573 msg->model_number = attr.model_number; 574 msg->model_number_len = attr.model_number_len; 575 msg->serial_number = attr.serial_number; 576 msg->serial_number_len = attr.serial_number_len; 577 578 msg->oob_dev_password = attr.oob_dev_password; 579 msg->oob_dev_password_len = attr.oob_dev_password_len; 580 581 return 0; 582 } 583 584 585 /** 586 * p2p_parse_ies - Parse P2P message IEs (both WPS and P2P IE) 587 * @data: IEs from the message 588 * @len: Length of data buffer in octets 589 * @msg: Buffer for returning parsed attributes 590 * Returns: 0 on success, -1 on failure 591 * 592 * Note: Caller is responsible for clearing the msg data structure before 593 * calling this function. 594 * 595 * Note: Caller must free temporary memory allocations by calling 596 * p2p_parse_free() when the parsed data is not needed anymore. 597 */ p2p_parse_ies(const u8 * data,size_t len,struct p2p_message * msg)598 int p2p_parse_ies(const u8 *data, size_t len, struct p2p_message *msg) 599 { 600 struct ieee802_11_elems elems; 601 602 if (ieee802_11_parse_elems(data, len, &elems, 0) == ParseFailed) 603 return -1; 604 605 if (elems.ds_params) 606 msg->ds_params = elems.ds_params; 607 if (elems.ssid) 608 msg->ssid = elems.ssid - 2; 609 610 msg->wps_attributes = ieee802_11_vendor_ie_concat(data, len, 611 WPS_DEV_OUI_WFA); 612 if (msg->wps_attributes && 613 p2p_parse_wps_ie(msg->wps_attributes, msg)) { 614 p2p_parse_free(msg); 615 return -1; 616 } 617 618 msg->p2p_attributes = ieee802_11_vendor_ie_concat(data, len, 619 P2P_IE_VENDOR_TYPE); 620 if (msg->p2p_attributes && 621 p2p_parse_p2p_ie(msg->p2p_attributes, msg)) { 622 wpa_printf(MSG_DEBUG, "P2P: Failed to parse P2P IE data"); 623 if (msg->p2p_attributes) 624 wpa_hexdump_buf(MSG_MSGDUMP, "P2P: P2P IE data", 625 msg->p2p_attributes); 626 p2p_parse_free(msg); 627 return -1; 628 } 629 630 msg->p2p2_attributes = ieee802_11_vendor_ie_concat(data, len, 631 P2P2_IE_VENDOR_TYPE); 632 if (msg->p2p2_attributes && 633 p2p_parse_p2p_ie(msg->p2p2_attributes, msg)) { 634 wpa_printf(MSG_DEBUG, "P2P: Failed to parse P2P2 IE data"); 635 if (msg->p2p2_attributes) 636 wpa_hexdump_buf(MSG_MSGDUMP, "P2P: P2P2 IE data", 637 msg->p2p2_attributes); 638 p2p_parse_free(msg); 639 return -1; 640 } 641 642 #ifdef CONFIG_WIFI_DISPLAY 643 if (elems.wfd) { 644 msg->wfd_subelems = ieee802_11_vendor_ie_concat( 645 data, len, WFD_IE_VENDOR_TYPE); 646 } 647 #endif /* CONFIG_WIFI_DISPLAY */ 648 649 msg->pref_freq_list = elems.pref_freq_list; 650 msg->pref_freq_list_len = elems.pref_freq_list_len; 651 652 return 0; 653 } 654 655 656 /** 657 * p2p_parse - Parse a P2P Action frame contents 658 * @data: Action frame payload after Category and Code fields 659 * @len: Length of data buffer in octets 660 * @msg: Buffer for returning parsed attributes 661 * Returns: 0 on success, -1 on failure 662 * 663 * Note: Caller must free temporary memory allocations by calling 664 * p2p_parse_free() when the parsed data is not needed anymore. 665 */ p2p_parse(const u8 * data,size_t len,struct p2p_message * msg)666 int p2p_parse(const u8 *data, size_t len, struct p2p_message *msg) 667 { 668 os_memset(msg, 0, sizeof(*msg)); 669 wpa_printf(MSG_DEBUG, "P2P: Parsing the received message"); 670 if (len < 1) { 671 wpa_printf(MSG_DEBUG, "P2P: No Dialog Token in the message"); 672 return -1; 673 } 674 msg->dialog_token = data[0]; 675 wpa_printf(MSG_DEBUG, "P2P: * Dialog Token: %d", msg->dialog_token); 676 677 return p2p_parse_ies(data + 1, len - 1, msg); 678 } 679 680 p2p_parse_ies_separate(const u8 * wsc,size_t wsc_len,const u8 * p2p,size_t p2p_len,struct p2p_message * msg)681 int p2p_parse_ies_separate(const u8 *wsc, size_t wsc_len, const u8 *p2p, 682 size_t p2p_len, struct p2p_message *msg) 683 { 684 os_memset(msg, 0, sizeof(*msg)); 685 686 msg->wps_attributes = wpabuf_alloc_copy(wsc, wsc_len); 687 if (msg->wps_attributes && 688 p2p_parse_wps_ie(msg->wps_attributes, msg)) { 689 p2p_parse_free(msg); 690 return -1; 691 } 692 693 msg->p2p_attributes = wpabuf_alloc_copy(p2p, p2p_len); 694 if (msg->p2p_attributes && 695 p2p_parse_p2p_ie(msg->p2p_attributes, msg)) { 696 wpa_printf(MSG_DEBUG, "P2P: Failed to parse P2P IE data"); 697 if (msg->p2p_attributes) 698 wpa_hexdump_buf(MSG_MSGDUMP, "P2P: P2P IE data", 699 msg->p2p_attributes); 700 p2p_parse_free(msg); 701 return -1; 702 } 703 704 return 0; 705 } 706 707 708 /** 709 * p2p_parse_free - Free temporary data from P2P parsing 710 * @msg: Parsed attributes 711 */ p2p_parse_free(struct p2p_message * msg)712 void p2p_parse_free(struct p2p_message *msg) 713 { 714 wpabuf_free(msg->p2p_attributes); 715 msg->p2p_attributes = NULL; 716 wpabuf_free(msg->p2p2_attributes); 717 msg->p2p2_attributes = NULL; 718 wpabuf_free(msg->wps_attributes); 719 msg->wps_attributes = NULL; 720 #ifdef CONFIG_WIFI_DISPLAY 721 wpabuf_free(msg->wfd_subelems); 722 msg->wfd_subelems = NULL; 723 #endif /* CONFIG_WIFI_DISPLAY */ 724 } 725 726 p2p_group_info_parse(const u8 * gi,size_t gi_len,struct p2p_group_info * info)727 int p2p_group_info_parse(const u8 *gi, size_t gi_len, 728 struct p2p_group_info *info) 729 { 730 const u8 *g, *gend; 731 732 os_memset(info, 0, sizeof(*info)); 733 if (gi == NULL) 734 return 0; 735 736 g = gi; 737 gend = gi + gi_len; 738 while (g < gend) { 739 struct p2p_client_info *cli; 740 const u8 *cend; 741 u16 count; 742 u8 len; 743 744 cli = &info->client[info->num_clients]; 745 len = *g++; 746 if (len > gend - g || len < 2 * ETH_ALEN + 1 + 2 + 8 + 1) 747 return -1; /* invalid data */ 748 cend = g + len; 749 /* g at start of P2P Client Info Descriptor */ 750 cli->p2p_device_addr = g; 751 g += ETH_ALEN; 752 cli->p2p_interface_addr = g; 753 g += ETH_ALEN; 754 cli->dev_capab = *g++; 755 756 cli->config_methods = WPA_GET_BE16(g); 757 g += 2; 758 cli->pri_dev_type = g; 759 g += 8; 760 761 /* g at Number of Secondary Device Types */ 762 len = *g++; 763 if (8 * len > cend - g) 764 return -1; /* invalid data */ 765 cli->num_sec_dev_types = len; 766 cli->sec_dev_types = g; 767 g += 8 * len; 768 769 /* g at Device Name in WPS TLV format */ 770 if (cend - g < 2 + 2) 771 return -1; /* invalid data */ 772 if (WPA_GET_BE16(g) != ATTR_DEV_NAME) 773 return -1; /* invalid Device Name TLV */ 774 g += 2; 775 count = WPA_GET_BE16(g); 776 g += 2; 777 if (count > cend - g) 778 return -1; /* invalid Device Name TLV */ 779 if (count >= WPS_DEV_NAME_MAX_LEN) 780 count = WPS_DEV_NAME_MAX_LEN; 781 cli->dev_name = (const char *) g; 782 cli->dev_name_len = count; 783 784 g = cend; 785 786 info->num_clients++; 787 if (info->num_clients == P2P_MAX_GROUP_ENTRIES) 788 return -1; 789 } 790 791 return 0; 792 } 793 794 p2p_group_info_text(const u8 * gi,size_t gi_len,char * buf,char * end)795 static int p2p_group_info_text(const u8 *gi, size_t gi_len, char *buf, 796 char *end) 797 { 798 char *pos = buf; 799 int ret; 800 struct p2p_group_info info; 801 unsigned int i; 802 803 if (p2p_group_info_parse(gi, gi_len, &info) < 0) 804 return 0; 805 806 for (i = 0; i < info.num_clients; i++) { 807 struct p2p_client_info *cli; 808 char name[WPS_DEV_NAME_MAX_LEN + 1]; 809 char devtype[WPS_DEV_TYPE_BUFSIZE]; 810 u8 s; 811 int count; 812 813 cli = &info.client[i]; 814 ret = os_snprintf(pos, end - pos, "p2p_group_client: " 815 "dev=" MACSTR " iface=" MACSTR, 816 MAC2STR(cli->p2p_device_addr), 817 MAC2STR(cli->p2p_interface_addr)); 818 if (os_snprintf_error(end - pos, ret)) 819 return pos - buf; 820 pos += ret; 821 822 ret = os_snprintf(pos, end - pos, 823 " dev_capab=0x%x config_methods=0x%x " 824 "dev_type=%s", 825 cli->dev_capab, cli->config_methods, 826 wps_dev_type_bin2str(cli->pri_dev_type, 827 devtype, 828 sizeof(devtype))); 829 if (os_snprintf_error(end - pos, ret)) 830 return pos - buf; 831 pos += ret; 832 833 for (s = 0; s < cli->num_sec_dev_types; s++) { 834 ret = os_snprintf(pos, end - pos, " dev_type=%s", 835 wps_dev_type_bin2str( 836 &cli->sec_dev_types[s * 8], 837 devtype, sizeof(devtype))); 838 if (os_snprintf_error(end - pos, ret)) 839 return pos - buf; 840 pos += ret; 841 } 842 843 os_memcpy(name, cli->dev_name, cli->dev_name_len); 844 name[cli->dev_name_len] = '\0'; 845 count = (int) cli->dev_name_len - 1; 846 while (count >= 0) { 847 if (is_ctrl_char(name[count])) 848 name[count] = '_'; 849 count--; 850 } 851 852 ret = os_snprintf(pos, end - pos, " dev_name='%s'\n", name); 853 if (os_snprintf_error(end - pos, ret)) 854 return pos - buf; 855 pos += ret; 856 } 857 858 return pos - buf; 859 } 860 861 862 /** 863 * p2p_attr_text - Build text format description of P2P IE attributes 864 * @data: P2P IE contents 865 * @buf: Buffer for returning text 866 * @end: Pointer to the end of the buf area 867 * Returns: Number of octets written to the buffer or -1 on faikure 868 * 869 * This function can be used to parse P2P IE contents into text format 870 * field=value lines. 871 */ p2p_attr_text(struct wpabuf * data,char * buf,char * end)872 int p2p_attr_text(struct wpabuf *data, char *buf, char *end) 873 { 874 struct p2p_message msg; 875 char *pos = buf; 876 int ret; 877 878 os_memset(&msg, 0, sizeof(msg)); 879 if (p2p_parse_p2p_ie(data, &msg)) 880 return -1; 881 882 if (msg.capability) { 883 ret = os_snprintf(pos, end - pos, 884 "p2p_dev_capab=0x%x\n" 885 "p2p_group_capab=0x%x\n", 886 msg.capability[0], msg.capability[1]); 887 if (os_snprintf_error(end - pos, ret)) 888 return pos - buf; 889 pos += ret; 890 } 891 892 if (msg.pri_dev_type) { 893 char devtype[WPS_DEV_TYPE_BUFSIZE]; 894 ret = os_snprintf(pos, end - pos, 895 "p2p_primary_device_type=%s\n", 896 wps_dev_type_bin2str(msg.pri_dev_type, 897 devtype, 898 sizeof(devtype))); 899 if (os_snprintf_error(end - pos, ret)) 900 return pos - buf; 901 pos += ret; 902 } 903 904 ret = os_snprintf(pos, end - pos, "p2p_device_name=%s\n", 905 msg.device_name); 906 if (os_snprintf_error(end - pos, ret)) 907 return pos - buf; 908 pos += ret; 909 910 if (msg.p2p_device_addr) { 911 ret = os_snprintf(pos, end - pos, "p2p_device_addr=" MACSTR 912 "\n", 913 MAC2STR(msg.p2p_device_addr)); 914 if (os_snprintf_error(end - pos, ret)) 915 return pos - buf; 916 pos += ret; 917 } 918 919 ret = os_snprintf(pos, end - pos, "p2p_config_methods=0x%x\n", 920 msg.config_methods); 921 if (os_snprintf_error(end - pos, ret)) 922 return pos - buf; 923 pos += ret; 924 925 ret = p2p_group_info_text(msg.group_info, msg.group_info_len, 926 pos, end); 927 if (ret < 0) 928 return pos - buf; 929 pos += ret; 930 931 return pos - buf; 932 } 933 934 p2p_get_cross_connect_disallowed(const struct wpabuf * p2p_ie)935 int p2p_get_cross_connect_disallowed(const struct wpabuf *p2p_ie) 936 { 937 struct p2p_message msg; 938 939 os_memset(&msg, 0, sizeof(msg)); 940 if (p2p_parse_p2p_ie(p2p_ie, &msg)) 941 return 0; 942 943 if (!msg.manageability) 944 return 0; 945 946 return !(msg.manageability[0] & P2P_MAN_CROSS_CONNECTION_PERMITTED); 947 } 948 949 p2p_get_group_capab(const struct wpabuf * p2p_ie)950 u8 p2p_get_group_capab(const struct wpabuf *p2p_ie) 951 { 952 struct p2p_message msg; 953 954 os_memset(&msg, 0, sizeof(msg)); 955 if (p2p_parse_p2p_ie(p2p_ie, &msg)) 956 return 0; 957 958 if (!msg.capability) 959 return 0; 960 961 return msg.capability[1]; 962 } 963 964 p2p_get_go_dev_addr(const struct wpabuf * p2p_ie)965 const u8 * p2p_get_go_dev_addr(const struct wpabuf *p2p_ie) 966 { 967 struct p2p_message msg; 968 969 os_memset(&msg, 0, sizeof(msg)); 970 if (p2p_parse_p2p_ie(p2p_ie, &msg)) 971 return NULL; 972 973 if (msg.p2p_device_addr) 974 return msg.p2p_device_addr; 975 if (msg.device_id) 976 return msg.device_id; 977 978 return NULL; 979 } 980