1 /* 2 * IEEE 802.11 Common routines 3 * Copyright (c) 2002-2019, Jouni Malinen <j@w1.fi> 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 "defs.h" 13 #include "wpa_common.h" 14 #include "drivers/driver.h" 15 #include "qca-vendor.h" 16 #include "ieee802_11_defs.h" 17 #include "ieee802_11_common.h" 18 19 20 static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen, 21 struct ieee802_11_elems *elems, 22 int show_errors) 23 { 24 unsigned int oui; 25 26 /* first 3 bytes in vendor specific information element are the IEEE 27 * OUI of the vendor. The following byte is used a vendor specific 28 * sub-type. */ 29 if (elen < 4) { 30 if (show_errors) { 31 wpa_printf(MSG_MSGDUMP, "short vendor specific " 32 "information element ignored (len=%lu)", 33 (unsigned long) elen); 34 } 35 return -1; 36 } 37 38 oui = WPA_GET_BE24(pos); 39 switch (oui) { 40 case OUI_MICROSOFT: 41 /* Microsoft/Wi-Fi information elements are further typed and 42 * subtyped */ 43 switch (pos[3]) { 44 case 1: 45 /* Microsoft OUI (00:50:F2) with OUI Type 1: 46 * real WPA information element */ 47 elems->wpa_ie = pos; 48 elems->wpa_ie_len = elen; 49 break; 50 case WMM_OUI_TYPE: 51 /* WMM information element */ 52 if (elen < 5) { 53 wpa_printf(MSG_MSGDUMP, "short WMM " 54 "information element ignored " 55 "(len=%lu)", 56 (unsigned long) elen); 57 return -1; 58 } 59 switch (pos[4]) { 60 case WMM_OUI_SUBTYPE_INFORMATION_ELEMENT: 61 case WMM_OUI_SUBTYPE_PARAMETER_ELEMENT: 62 /* 63 * Share same pointer since only one of these 64 * is used and they start with same data. 65 * Length field can be used to distinguish the 66 * IEs. 67 */ 68 elems->wmm = pos; 69 elems->wmm_len = elen; 70 break; 71 case WMM_OUI_SUBTYPE_TSPEC_ELEMENT: 72 elems->wmm_tspec = pos; 73 elems->wmm_tspec_len = elen; 74 break; 75 default: 76 wpa_printf(MSG_EXCESSIVE, "unknown WMM " 77 "information element ignored " 78 "(subtype=%d len=%lu)", 79 pos[4], (unsigned long) elen); 80 return -1; 81 } 82 break; 83 case 4: 84 /* Wi-Fi Protected Setup (WPS) IE */ 85 elems->wps_ie = pos; 86 elems->wps_ie_len = elen; 87 break; 88 default: 89 wpa_printf(MSG_EXCESSIVE, "Unknown Microsoft " 90 "information element ignored " 91 "(type=%d len=%lu)", 92 pos[3], (unsigned long) elen); 93 return -1; 94 } 95 break; 96 97 case OUI_WFA: 98 switch (pos[3]) { 99 case P2P_OUI_TYPE: 100 /* Wi-Fi Alliance - P2P IE */ 101 elems->p2p = pos; 102 elems->p2p_len = elen; 103 break; 104 case WFD_OUI_TYPE: 105 /* Wi-Fi Alliance - WFD IE */ 106 elems->wfd = pos; 107 elems->wfd_len = elen; 108 break; 109 case HS20_INDICATION_OUI_TYPE: 110 /* Hotspot 2.0 */ 111 elems->hs20 = pos; 112 elems->hs20_len = elen; 113 break; 114 case HS20_OSEN_OUI_TYPE: 115 /* Hotspot 2.0 OSEN */ 116 elems->osen = pos; 117 elems->osen_len = elen; 118 break; 119 case MBO_OUI_TYPE: 120 /* MBO-OCE */ 121 elems->mbo = pos; 122 elems->mbo_len = elen; 123 break; 124 case HS20_ROAMING_CONS_SEL_OUI_TYPE: 125 /* Hotspot 2.0 Roaming Consortium Selection */ 126 elems->roaming_cons_sel = pos; 127 elems->roaming_cons_sel_len = elen; 128 break; 129 case MULTI_AP_OUI_TYPE: 130 elems->multi_ap = pos; 131 elems->multi_ap_len = elen; 132 break; 133 default: 134 wpa_printf(MSG_MSGDUMP, "Unknown WFA " 135 "information element ignored " 136 "(type=%d len=%lu)", 137 pos[3], (unsigned long) elen); 138 return -1; 139 } 140 break; 141 142 case OUI_BROADCOM: 143 switch (pos[3]) { 144 case VENDOR_HT_CAPAB_OUI_TYPE: 145 elems->vendor_ht_cap = pos; 146 elems->vendor_ht_cap_len = elen; 147 break; 148 case VENDOR_VHT_TYPE: 149 if (elen > 4 && 150 (pos[4] == VENDOR_VHT_SUBTYPE || 151 pos[4] == VENDOR_VHT_SUBTYPE2)) { 152 elems->vendor_vht = pos; 153 elems->vendor_vht_len = elen; 154 } else 155 return -1; 156 break; 157 default: 158 wpa_printf(MSG_EXCESSIVE, "Unknown Broadcom " 159 "information element ignored " 160 "(type=%d len=%lu)", 161 pos[3], (unsigned long) elen); 162 return -1; 163 } 164 break; 165 166 case OUI_QCA: 167 switch (pos[3]) { 168 case QCA_VENDOR_ELEM_P2P_PREF_CHAN_LIST: 169 elems->pref_freq_list = pos; 170 elems->pref_freq_list_len = elen; 171 break; 172 default: 173 wpa_printf(MSG_EXCESSIVE, 174 "Unknown QCA information element ignored (type=%d len=%lu)", 175 pos[3], (unsigned long) elen); 176 return -1; 177 } 178 break; 179 180 default: 181 wpa_printf(MSG_EXCESSIVE, "unknown vendor specific " 182 "information element ignored (vendor OUI " 183 "%02x:%02x:%02x len=%lu)", 184 pos[0], pos[1], pos[2], (unsigned long) elen); 185 return -1; 186 } 187 188 return 0; 189 } 190 191 192 static int ieee802_11_parse_extension(const u8 *pos, size_t elen, 193 struct ieee802_11_elems *elems, 194 int show_errors) 195 { 196 u8 ext_id; 197 198 if (elen < 1) { 199 if (show_errors) { 200 wpa_printf(MSG_MSGDUMP, 201 "short information element (Ext)"); 202 } 203 return -1; 204 } 205 206 ext_id = *pos++; 207 elen--; 208 209 switch (ext_id) { 210 case WLAN_EID_EXT_ASSOC_DELAY_INFO: 211 if (elen != 1) 212 break; 213 elems->assoc_delay_info = pos; 214 break; 215 case WLAN_EID_EXT_FILS_REQ_PARAMS: 216 if (elen < 3) 217 break; 218 elems->fils_req_params = pos; 219 elems->fils_req_params_len = elen; 220 break; 221 case WLAN_EID_EXT_FILS_KEY_CONFIRM: 222 elems->fils_key_confirm = pos; 223 elems->fils_key_confirm_len = elen; 224 break; 225 case WLAN_EID_EXT_FILS_SESSION: 226 if (elen != FILS_SESSION_LEN) 227 break; 228 elems->fils_session = pos; 229 break; 230 case WLAN_EID_EXT_FILS_HLP_CONTAINER: 231 if (elen < 2 * ETH_ALEN) 232 break; 233 elems->fils_hlp = pos; 234 elems->fils_hlp_len = elen; 235 break; 236 case WLAN_EID_EXT_FILS_IP_ADDR_ASSIGN: 237 if (elen < 1) 238 break; 239 elems->fils_ip_addr_assign = pos; 240 elems->fils_ip_addr_assign_len = elen; 241 break; 242 case WLAN_EID_EXT_KEY_DELIVERY: 243 if (elen < WPA_KEY_RSC_LEN) 244 break; 245 elems->key_delivery = pos; 246 elems->key_delivery_len = elen; 247 break; 248 case WLAN_EID_EXT_FILS_WRAPPED_DATA: 249 elems->fils_wrapped_data = pos; 250 elems->fils_wrapped_data_len = elen; 251 break; 252 case WLAN_EID_EXT_FILS_PUBLIC_KEY: 253 if (elen < 1) 254 break; 255 elems->fils_pk = pos; 256 elems->fils_pk_len = elen; 257 break; 258 case WLAN_EID_EXT_FILS_NONCE: 259 if (elen != FILS_NONCE_LEN) 260 break; 261 elems->fils_nonce = pos; 262 break; 263 case WLAN_EID_EXT_OWE_DH_PARAM: 264 if (elen < 2) 265 break; 266 elems->owe_dh = pos; 267 elems->owe_dh_len = elen; 268 break; 269 case WLAN_EID_EXT_PASSWORD_IDENTIFIER: 270 elems->password_id = pos; 271 elems->password_id_len = elen; 272 break; 273 case WLAN_EID_EXT_HE_CAPABILITIES: 274 elems->he_capabilities = pos; 275 elems->he_capabilities_len = elen; 276 break; 277 case WLAN_EID_EXT_OCV_OCI: 278 elems->oci = pos; 279 elems->oci_len = elen; 280 break; 281 default: 282 if (show_errors) { 283 wpa_printf(MSG_MSGDUMP, 284 "IEEE 802.11 element parsing ignored unknown element extension (ext_id=%u elen=%u)", 285 ext_id, (unsigned int) elen); 286 } 287 return -1; 288 } 289 290 return 0; 291 } 292 293 294 /** 295 * ieee802_11_parse_elems - Parse information elements in management frames 296 * @start: Pointer to the start of IEs 297 * @len: Length of IE buffer in octets 298 * @elems: Data structure for parsed elements 299 * @show_errors: Whether to show parsing errors in debug log 300 * Returns: Parsing result 301 */ 302 ParseRes ieee802_11_parse_elems(const u8 *start, size_t len, 303 struct ieee802_11_elems *elems, 304 int show_errors) 305 { 306 const struct element *elem; 307 int unknown = 0; 308 309 os_memset(elems, 0, sizeof(*elems)); 310 311 if (!start) 312 return ParseOK; 313 314 for_each_element(elem, start, len) { 315 u8 id = elem->id, elen = elem->datalen; 316 const u8 *pos = elem->data; 317 318 switch (id) { 319 case WLAN_EID_SSID: 320 if (elen > SSID_MAX_LEN) { 321 wpa_printf(MSG_DEBUG, 322 "Ignored too long SSID element (elen=%u)", 323 elen); 324 break; 325 } 326 elems->ssid = pos; 327 elems->ssid_len = elen; 328 break; 329 case WLAN_EID_SUPP_RATES: 330 elems->supp_rates = pos; 331 elems->supp_rates_len = elen; 332 break; 333 case WLAN_EID_DS_PARAMS: 334 if (elen < 1) 335 break; 336 elems->ds_params = pos; 337 break; 338 case WLAN_EID_CF_PARAMS: 339 case WLAN_EID_TIM: 340 break; 341 case WLAN_EID_CHALLENGE: 342 elems->challenge = pos; 343 elems->challenge_len = elen; 344 break; 345 case WLAN_EID_ERP_INFO: 346 if (elen < 1) 347 break; 348 elems->erp_info = pos; 349 break; 350 case WLAN_EID_EXT_SUPP_RATES: 351 elems->ext_supp_rates = pos; 352 elems->ext_supp_rates_len = elen; 353 break; 354 case WLAN_EID_VENDOR_SPECIFIC: 355 if (ieee802_11_parse_vendor_specific(pos, elen, 356 elems, 357 show_errors)) 358 unknown++; 359 break; 360 case WLAN_EID_RSN: 361 elems->rsn_ie = pos; 362 elems->rsn_ie_len = elen; 363 break; 364 case WLAN_EID_PWR_CAPABILITY: 365 if (elen < 2) 366 break; 367 elems->power_capab = pos; 368 elems->power_capab_len = elen; 369 break; 370 case WLAN_EID_SUPPORTED_CHANNELS: 371 elems->supp_channels = pos; 372 elems->supp_channels_len = elen; 373 break; 374 case WLAN_EID_MOBILITY_DOMAIN: 375 if (elen < sizeof(struct rsn_mdie)) 376 break; 377 elems->mdie = pos; 378 elems->mdie_len = elen; 379 break; 380 case WLAN_EID_FAST_BSS_TRANSITION: 381 if (elen < sizeof(struct rsn_ftie)) 382 break; 383 elems->ftie = pos; 384 elems->ftie_len = elen; 385 break; 386 case WLAN_EID_TIMEOUT_INTERVAL: 387 if (elen != 5) 388 break; 389 elems->timeout_int = pos; 390 break; 391 case WLAN_EID_HT_CAP: 392 if (elen < sizeof(struct ieee80211_ht_capabilities)) 393 break; 394 elems->ht_capabilities = pos; 395 break; 396 case WLAN_EID_HT_OPERATION: 397 if (elen < sizeof(struct ieee80211_ht_operation)) 398 break; 399 elems->ht_operation = pos; 400 break; 401 case WLAN_EID_MESH_CONFIG: 402 elems->mesh_config = pos; 403 elems->mesh_config_len = elen; 404 break; 405 case WLAN_EID_MESH_ID: 406 elems->mesh_id = pos; 407 elems->mesh_id_len = elen; 408 break; 409 case WLAN_EID_PEER_MGMT: 410 elems->peer_mgmt = pos; 411 elems->peer_mgmt_len = elen; 412 break; 413 case WLAN_EID_VHT_CAP: 414 if (elen < sizeof(struct ieee80211_vht_capabilities)) 415 break; 416 elems->vht_capabilities = pos; 417 break; 418 case WLAN_EID_VHT_OPERATION: 419 if (elen < sizeof(struct ieee80211_vht_operation)) 420 break; 421 elems->vht_operation = pos; 422 break; 423 case WLAN_EID_VHT_OPERATING_MODE_NOTIFICATION: 424 if (elen != 1) 425 break; 426 elems->vht_opmode_notif = pos; 427 break; 428 case WLAN_EID_LINK_ID: 429 if (elen < 18) 430 break; 431 elems->link_id = pos; 432 break; 433 case WLAN_EID_INTERWORKING: 434 elems->interworking = pos; 435 elems->interworking_len = elen; 436 break; 437 case WLAN_EID_QOS_MAP_SET: 438 if (elen < 16) 439 break; 440 elems->qos_map_set = pos; 441 elems->qos_map_set_len = elen; 442 break; 443 case WLAN_EID_EXT_CAPAB: 444 elems->ext_capab = pos; 445 elems->ext_capab_len = elen; 446 break; 447 case WLAN_EID_BSS_MAX_IDLE_PERIOD: 448 if (elen < 3) 449 break; 450 elems->bss_max_idle_period = pos; 451 break; 452 case WLAN_EID_SSID_LIST: 453 elems->ssid_list = pos; 454 elems->ssid_list_len = elen; 455 break; 456 case WLAN_EID_AMPE: 457 elems->ampe = pos; 458 elems->ampe_len = elen; 459 break; 460 case WLAN_EID_MIC: 461 elems->mic = pos; 462 elems->mic_len = elen; 463 /* after mic everything is encrypted, so stop. */ 464 goto done; 465 case WLAN_EID_MULTI_BAND: 466 if (elems->mb_ies.nof_ies >= MAX_NOF_MB_IES_SUPPORTED) { 467 wpa_printf(MSG_MSGDUMP, 468 "IEEE 802.11 element parse ignored MB IE (id=%d elen=%d)", 469 id, elen); 470 break; 471 } 472 473 elems->mb_ies.ies[elems->mb_ies.nof_ies].ie = pos; 474 elems->mb_ies.ies[elems->mb_ies.nof_ies].ie_len = elen; 475 elems->mb_ies.nof_ies++; 476 break; 477 case WLAN_EID_SUPPORTED_OPERATING_CLASSES: 478 elems->supp_op_classes = pos; 479 elems->supp_op_classes_len = elen; 480 break; 481 case WLAN_EID_RRM_ENABLED_CAPABILITIES: 482 elems->rrm_enabled = pos; 483 elems->rrm_enabled_len = elen; 484 break; 485 case WLAN_EID_CAG_NUMBER: 486 elems->cag_number = pos; 487 elems->cag_number_len = elen; 488 break; 489 case WLAN_EID_AP_CSN: 490 if (elen < 1) 491 break; 492 elems->ap_csn = pos; 493 break; 494 case WLAN_EID_FILS_INDICATION: 495 if (elen < 2) 496 break; 497 elems->fils_indic = pos; 498 elems->fils_indic_len = elen; 499 break; 500 case WLAN_EID_DILS: 501 if (elen < 2) 502 break; 503 elems->dils = pos; 504 elems->dils_len = elen; 505 break; 506 case WLAN_EID_FRAGMENT: 507 /* TODO */ 508 break; 509 case WLAN_EID_EXTENSION: 510 if (ieee802_11_parse_extension(pos, elen, elems, 511 show_errors)) 512 unknown++; 513 break; 514 default: 515 unknown++; 516 if (!show_errors) 517 break; 518 wpa_printf(MSG_MSGDUMP, "IEEE 802.11 element parse " 519 "ignored unknown element (id=%d elen=%d)", 520 id, elen); 521 break; 522 } 523 } 524 525 if (!for_each_element_completed(elem, start, len)) { 526 if (show_errors) { 527 wpa_printf(MSG_DEBUG, 528 "IEEE 802.11 element parse failed @%d", 529 (int) (start + len - (const u8 *) elem)); 530 wpa_hexdump(MSG_MSGDUMP, "IEs", start, len); 531 } 532 return ParseFailed; 533 } 534 535 done: 536 return unknown ? ParseUnknown : ParseOK; 537 } 538 539 540 int ieee802_11_ie_count(const u8 *ies, size_t ies_len) 541 { 542 const struct element *elem; 543 int count = 0; 544 545 if (ies == NULL) 546 return 0; 547 548 for_each_element(elem, ies, ies_len) 549 count++; 550 551 return count; 552 } 553 554 555 struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len, 556 u32 oui_type) 557 { 558 struct wpabuf *buf; 559 const struct element *elem, *found = NULL; 560 561 for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, ies_len) { 562 if (elem->datalen >= 4 && 563 WPA_GET_BE32(elem->data) == oui_type) { 564 found = elem; 565 break; 566 } 567 } 568 569 if (!found) 570 return NULL; /* No specified vendor IE found */ 571 572 buf = wpabuf_alloc(ies_len); 573 if (buf == NULL) 574 return NULL; 575 576 /* 577 * There may be multiple vendor IEs in the message, so need to 578 * concatenate their data fields. 579 */ 580 for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, ies_len) { 581 if (elem->datalen >= 4 && WPA_GET_BE32(elem->data) == oui_type) 582 wpabuf_put_data(buf, elem->data + 4, elem->datalen - 4); 583 } 584 585 return buf; 586 } 587 588 589 const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len) 590 { 591 u16 fc, type, stype; 592 593 /* 594 * PS-Poll frames are 16 bytes. All other frames are 595 * 24 bytes or longer. 596 */ 597 if (len < 16) 598 return NULL; 599 600 fc = le_to_host16(hdr->frame_control); 601 type = WLAN_FC_GET_TYPE(fc); 602 stype = WLAN_FC_GET_STYPE(fc); 603 604 switch (type) { 605 case WLAN_FC_TYPE_DATA: 606 if (len < 24) 607 return NULL; 608 switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) { 609 case WLAN_FC_FROMDS | WLAN_FC_TODS: 610 case WLAN_FC_TODS: 611 return hdr->addr1; 612 case WLAN_FC_FROMDS: 613 return hdr->addr2; 614 default: 615 return NULL; 616 } 617 case WLAN_FC_TYPE_CTRL: 618 if (stype != WLAN_FC_STYPE_PSPOLL) 619 return NULL; 620 return hdr->addr1; 621 case WLAN_FC_TYPE_MGMT: 622 return hdr->addr3; 623 default: 624 return NULL; 625 } 626 } 627 628 629 int hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[], 630 const char *name, const char *val) 631 { 632 int num, v; 633 const char *pos; 634 struct hostapd_wmm_ac_params *ac; 635 636 /* skip 'wme_ac_' or 'wmm_ac_' prefix */ 637 pos = name + 7; 638 if (os_strncmp(pos, "be_", 3) == 0) { 639 num = 0; 640 pos += 3; 641 } else if (os_strncmp(pos, "bk_", 3) == 0) { 642 num = 1; 643 pos += 3; 644 } else if (os_strncmp(pos, "vi_", 3) == 0) { 645 num = 2; 646 pos += 3; 647 } else if (os_strncmp(pos, "vo_", 3) == 0) { 648 num = 3; 649 pos += 3; 650 } else { 651 wpa_printf(MSG_ERROR, "Unknown WMM name '%s'", pos); 652 return -1; 653 } 654 655 ac = &wmm_ac_params[num]; 656 657 if (os_strcmp(pos, "aifs") == 0) { 658 v = atoi(val); 659 if (v < 1 || v > 255) { 660 wpa_printf(MSG_ERROR, "Invalid AIFS value %d", v); 661 return -1; 662 } 663 ac->aifs = v; 664 } else if (os_strcmp(pos, "cwmin") == 0) { 665 v = atoi(val); 666 if (v < 0 || v > 15) { 667 wpa_printf(MSG_ERROR, "Invalid cwMin value %d", v); 668 return -1; 669 } 670 ac->cwmin = v; 671 } else if (os_strcmp(pos, "cwmax") == 0) { 672 v = atoi(val); 673 if (v < 0 || v > 15) { 674 wpa_printf(MSG_ERROR, "Invalid cwMax value %d", v); 675 return -1; 676 } 677 ac->cwmax = v; 678 } else if (os_strcmp(pos, "txop_limit") == 0) { 679 v = atoi(val); 680 if (v < 0 || v > 0xffff) { 681 wpa_printf(MSG_ERROR, "Invalid txop value %d", v); 682 return -1; 683 } 684 ac->txop_limit = v; 685 } else if (os_strcmp(pos, "acm") == 0) { 686 v = atoi(val); 687 if (v < 0 || v > 1) { 688 wpa_printf(MSG_ERROR, "Invalid acm value %d", v); 689 return -1; 690 } 691 ac->admission_control_mandatory = v; 692 } else { 693 wpa_printf(MSG_ERROR, "Unknown wmm_ac_ field '%s'", pos); 694 return -1; 695 } 696 697 return 0; 698 } 699 700 701 enum hostapd_hw_mode ieee80211_freq_to_chan(int freq, u8 *channel) 702 { 703 u8 op_class; 704 705 return ieee80211_freq_to_channel_ext(freq, 0, VHT_CHANWIDTH_USE_HT, 706 &op_class, channel); 707 } 708 709 710 /** 711 * ieee80211_freq_to_channel_ext - Convert frequency into channel info 712 * for HT40 and VHT. DFS channels are not covered. 713 * @freq: Frequency (MHz) to convert 714 * @sec_channel: 0 = non-HT40, 1 = sec. channel above, -1 = sec. channel below 715 * @vht: VHT channel width (VHT_CHANWIDTH_*) 716 * @op_class: Buffer for returning operating class 717 * @channel: Buffer for returning channel number 718 * Returns: hw_mode on success, NUM_HOSTAPD_MODES on failure 719 */ 720 enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq, 721 int sec_channel, int vht, 722 u8 *op_class, u8 *channel) 723 { 724 u8 vht_opclass; 725 726 /* TODO: more operating classes */ 727 728 if (sec_channel > 1 || sec_channel < -1) 729 return NUM_HOSTAPD_MODES; 730 731 if (freq >= 2412 && freq <= 2472) { 732 if ((freq - 2407) % 5) 733 return NUM_HOSTAPD_MODES; 734 735 if (vht) 736 return NUM_HOSTAPD_MODES; 737 738 /* 2.407 GHz, channels 1..13 */ 739 if (sec_channel == 1) 740 *op_class = 83; 741 else if (sec_channel == -1) 742 *op_class = 84; 743 else 744 *op_class = 81; 745 746 *channel = (freq - 2407) / 5; 747 748 return HOSTAPD_MODE_IEEE80211G; 749 } 750 751 if (freq == 2484) { 752 if (sec_channel || vht) 753 return NUM_HOSTAPD_MODES; 754 755 *op_class = 82; /* channel 14 */ 756 *channel = 14; 757 758 return HOSTAPD_MODE_IEEE80211B; 759 } 760 761 if (freq >= 4900 && freq < 5000) { 762 if ((freq - 4000) % 5) 763 return NUM_HOSTAPD_MODES; 764 *channel = (freq - 4000) / 5; 765 *op_class = 0; /* TODO */ 766 return HOSTAPD_MODE_IEEE80211A; 767 } 768 769 switch (vht) { 770 case VHT_CHANWIDTH_80MHZ: 771 vht_opclass = 128; 772 break; 773 case VHT_CHANWIDTH_160MHZ: 774 vht_opclass = 129; 775 break; 776 case VHT_CHANWIDTH_80P80MHZ: 777 vht_opclass = 130; 778 break; 779 default: 780 vht_opclass = 0; 781 break; 782 } 783 784 /* 5 GHz, channels 36..48 */ 785 if (freq >= 5180 && freq <= 5240) { 786 if ((freq - 5000) % 5) 787 return NUM_HOSTAPD_MODES; 788 789 if (vht_opclass) 790 *op_class = vht_opclass; 791 else if (sec_channel == 1) 792 *op_class = 116; 793 else if (sec_channel == -1) 794 *op_class = 117; 795 else 796 *op_class = 115; 797 798 *channel = (freq - 5000) / 5; 799 800 return HOSTAPD_MODE_IEEE80211A; 801 } 802 803 /* 5 GHz, channels 52..64 */ 804 if (freq >= 5260 && freq <= 5320) { 805 if ((freq - 5000) % 5) 806 return NUM_HOSTAPD_MODES; 807 808 if (vht_opclass) 809 *op_class = vht_opclass; 810 else if (sec_channel == 1) 811 *op_class = 119; 812 else if (sec_channel == -1) 813 *op_class = 120; 814 else 815 *op_class = 118; 816 817 *channel = (freq - 5000) / 5; 818 819 return HOSTAPD_MODE_IEEE80211A; 820 } 821 822 /* 5 GHz, channels 149..169 */ 823 if (freq >= 5745 && freq <= 5845) { 824 if ((freq - 5000) % 5) 825 return NUM_HOSTAPD_MODES; 826 827 if (vht_opclass) 828 *op_class = vht_opclass; 829 else if (sec_channel == 1) 830 *op_class = 126; 831 else if (sec_channel == -1) 832 *op_class = 127; 833 else if (freq <= 5805) 834 *op_class = 124; 835 else 836 *op_class = 125; 837 838 *channel = (freq - 5000) / 5; 839 840 return HOSTAPD_MODE_IEEE80211A; 841 } 842 843 /* 5 GHz, channels 100..140 */ 844 if (freq >= 5000 && freq <= 5700) { 845 if ((freq - 5000) % 5) 846 return NUM_HOSTAPD_MODES; 847 848 if (vht_opclass) 849 *op_class = vht_opclass; 850 else if (sec_channel == 1) 851 *op_class = 122; 852 else if (sec_channel == -1) 853 *op_class = 123; 854 else 855 *op_class = 121; 856 857 *channel = (freq - 5000) / 5; 858 859 return HOSTAPD_MODE_IEEE80211A; 860 } 861 862 if (freq >= 5000 && freq < 5900) { 863 if ((freq - 5000) % 5) 864 return NUM_HOSTAPD_MODES; 865 *channel = (freq - 5000) / 5; 866 *op_class = 0; /* TODO */ 867 return HOSTAPD_MODE_IEEE80211A; 868 } 869 870 /* 56.16 GHz, channel 1..4 */ 871 if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 4) { 872 if (sec_channel || vht) 873 return NUM_HOSTAPD_MODES; 874 875 *channel = (freq - 56160) / 2160; 876 *op_class = 180; 877 878 return HOSTAPD_MODE_IEEE80211AD; 879 } 880 881 return NUM_HOSTAPD_MODES; 882 } 883 884 885 int ieee80211_chaninfo_to_channel(unsigned int freq, enum chan_width chanwidth, 886 int sec_channel, u8 *op_class, u8 *channel) 887 { 888 int vht = CHAN_WIDTH_UNKNOWN; 889 890 switch (chanwidth) { 891 case CHAN_WIDTH_UNKNOWN: 892 case CHAN_WIDTH_20_NOHT: 893 case CHAN_WIDTH_20: 894 case CHAN_WIDTH_40: 895 vht = VHT_CHANWIDTH_USE_HT; 896 break; 897 case CHAN_WIDTH_80: 898 vht = VHT_CHANWIDTH_80MHZ; 899 break; 900 case CHAN_WIDTH_80P80: 901 vht = VHT_CHANWIDTH_80P80MHZ; 902 break; 903 case CHAN_WIDTH_160: 904 vht = VHT_CHANWIDTH_160MHZ; 905 break; 906 } 907 908 if (ieee80211_freq_to_channel_ext(freq, sec_channel, vht, op_class, 909 channel) == NUM_HOSTAPD_MODES) { 910 wpa_printf(MSG_WARNING, 911 "Cannot determine operating class and channel (freq=%u chanwidth=%d sec_channel=%d)", 912 freq, chanwidth, sec_channel); 913 return -1; 914 } 915 916 return 0; 917 } 918 919 920 static const char *const us_op_class_cc[] = { 921 "US", "CA", NULL 922 }; 923 924 static const char *const eu_op_class_cc[] = { 925 "AL", "AM", "AT", "AZ", "BA", "BE", "BG", "BY", "CH", "CY", "CZ", "DE", 926 "DK", "EE", "EL", "ES", "FI", "FR", "GE", "HR", "HU", "IE", "IS", "IT", 927 "LI", "LT", "LU", "LV", "MD", "ME", "MK", "MT", "NL", "NO", "PL", "PT", 928 "RO", "RS", "RU", "SE", "SI", "SK", "TR", "UA", "UK", NULL 929 }; 930 931 static const char *const jp_op_class_cc[] = { 932 "JP", NULL 933 }; 934 935 static const char *const cn_op_class_cc[] = { 936 "CN", NULL 937 }; 938 939 940 static int country_match(const char *const cc[], const char *const country) 941 { 942 int i; 943 944 if (country == NULL) 945 return 0; 946 for (i = 0; cc[i]; i++) { 947 if (cc[i][0] == country[0] && cc[i][1] == country[1]) 948 return 1; 949 } 950 951 return 0; 952 } 953 954 955 static int ieee80211_chan_to_freq_us(u8 op_class, u8 chan) 956 { 957 switch (op_class) { 958 case 12: /* channels 1..11 */ 959 case 32: /* channels 1..7; 40 MHz */ 960 case 33: /* channels 5..11; 40 MHz */ 961 if (chan < 1 || chan > 11) 962 return -1; 963 return 2407 + 5 * chan; 964 case 1: /* channels 36,40,44,48 */ 965 case 2: /* channels 52,56,60,64; dfs */ 966 case 22: /* channels 36,44; 40 MHz */ 967 case 23: /* channels 52,60; 40 MHz */ 968 case 27: /* channels 40,48; 40 MHz */ 969 case 28: /* channels 56,64; 40 MHz */ 970 if (chan < 36 || chan > 64) 971 return -1; 972 return 5000 + 5 * chan; 973 case 4: /* channels 100-144 */ 974 case 24: /* channels 100-140; 40 MHz */ 975 if (chan < 100 || chan > 144) 976 return -1; 977 return 5000 + 5 * chan; 978 case 3: /* channels 149,153,157,161 */ 979 case 25: /* channels 149,157; 40 MHz */ 980 case 26: /* channels 149,157; 40 MHz */ 981 case 30: /* channels 153,161; 40 MHz */ 982 case 31: /* channels 153,161; 40 MHz */ 983 if (chan < 149 || chan > 161) 984 return -1; 985 return 5000 + 5 * chan; 986 case 5: /* channels 149,153,157,161,165 */ 987 if (chan < 149 || chan > 165) 988 return -1; 989 return 5000 + 5 * chan; 990 case 34: /* 60 GHz band, channels 1..3 */ 991 if (chan < 1 || chan > 3) 992 return -1; 993 return 56160 + 2160 * chan; 994 } 995 return -1; 996 } 997 998 999 static int ieee80211_chan_to_freq_eu(u8 op_class, u8 chan) 1000 { 1001 switch (op_class) { 1002 case 4: /* channels 1..13 */ 1003 case 11: /* channels 1..9; 40 MHz */ 1004 case 12: /* channels 5..13; 40 MHz */ 1005 if (chan < 1 || chan > 13) 1006 return -1; 1007 return 2407 + 5 * chan; 1008 case 1: /* channels 36,40,44,48 */ 1009 case 2: /* channels 52,56,60,64; dfs */ 1010 case 5: /* channels 36,44; 40 MHz */ 1011 case 6: /* channels 52,60; 40 MHz */ 1012 case 8: /* channels 40,48; 40 MHz */ 1013 case 9: /* channels 56,64; 40 MHz */ 1014 if (chan < 36 || chan > 64) 1015 return -1; 1016 return 5000 + 5 * chan; 1017 case 3: /* channels 100-140 */ 1018 case 7: /* channels 100-132; 40 MHz */ 1019 case 10: /* channels 104-136; 40 MHz */ 1020 case 16: /* channels 100-140 */ 1021 if (chan < 100 || chan > 140) 1022 return -1; 1023 return 5000 + 5 * chan; 1024 case 17: /* channels 149,153,157,161,165,169 */ 1025 if (chan < 149 || chan > 169) 1026 return -1; 1027 return 5000 + 5 * chan; 1028 case 18: /* 60 GHz band, channels 1..4 */ 1029 if (chan < 1 || chan > 4) 1030 return -1; 1031 return 56160 + 2160 * chan; 1032 } 1033 return -1; 1034 } 1035 1036 1037 static int ieee80211_chan_to_freq_jp(u8 op_class, u8 chan) 1038 { 1039 switch (op_class) { 1040 case 30: /* channels 1..13 */ 1041 case 56: /* channels 1..9; 40 MHz */ 1042 case 57: /* channels 5..13; 40 MHz */ 1043 if (chan < 1 || chan > 13) 1044 return -1; 1045 return 2407 + 5 * chan; 1046 case 31: /* channel 14 */ 1047 if (chan != 14) 1048 return -1; 1049 return 2414 + 5 * chan; 1050 case 1: /* channels 34,38,42,46(old) or 36,40,44,48 */ 1051 case 32: /* channels 52,56,60,64 */ 1052 case 33: /* channels 52,56,60,64 */ 1053 case 36: /* channels 36,44; 40 MHz */ 1054 case 37: /* channels 52,60; 40 MHz */ 1055 case 38: /* channels 52,60; 40 MHz */ 1056 case 41: /* channels 40,48; 40 MHz */ 1057 case 42: /* channels 56,64; 40 MHz */ 1058 case 43: /* channels 56,64; 40 MHz */ 1059 if (chan < 34 || chan > 64) 1060 return -1; 1061 return 5000 + 5 * chan; 1062 case 34: /* channels 100-140 */ 1063 case 35: /* channels 100-140 */ 1064 case 39: /* channels 100-132; 40 MHz */ 1065 case 40: /* channels 100-132; 40 MHz */ 1066 case 44: /* channels 104-136; 40 MHz */ 1067 case 45: /* channels 104-136; 40 MHz */ 1068 case 58: /* channels 100-140 */ 1069 if (chan < 100 || chan > 140) 1070 return -1; 1071 return 5000 + 5 * chan; 1072 case 59: /* 60 GHz band, channels 1..4 */ 1073 if (chan < 1 || chan > 3) 1074 return -1; 1075 return 56160 + 2160 * chan; 1076 } 1077 return -1; 1078 } 1079 1080 1081 static int ieee80211_chan_to_freq_cn(u8 op_class, u8 chan) 1082 { 1083 switch (op_class) { 1084 case 7: /* channels 1..13 */ 1085 case 8: /* channels 1..9; 40 MHz */ 1086 case 9: /* channels 5..13; 40 MHz */ 1087 if (chan < 1 || chan > 13) 1088 return -1; 1089 return 2407 + 5 * chan; 1090 case 1: /* channels 36,40,44,48 */ 1091 case 2: /* channels 52,56,60,64; dfs */ 1092 case 4: /* channels 36,44; 40 MHz */ 1093 case 5: /* channels 52,60; 40 MHz */ 1094 if (chan < 36 || chan > 64) 1095 return -1; 1096 return 5000 + 5 * chan; 1097 case 3: /* channels 149,153,157,161,165 */ 1098 case 6: /* channels 149,157; 40 MHz */ 1099 if (chan < 149 || chan > 165) 1100 return -1; 1101 return 5000 + 5 * chan; 1102 } 1103 return -1; 1104 } 1105 1106 1107 static int ieee80211_chan_to_freq_global(u8 op_class, u8 chan) 1108 { 1109 /* Table E-4 in IEEE Std 802.11-2012 - Global operating classes */ 1110 switch (op_class) { 1111 case 81: 1112 /* channels 1..13 */ 1113 if (chan < 1 || chan > 13) 1114 return -1; 1115 return 2407 + 5 * chan; 1116 case 82: 1117 /* channel 14 */ 1118 if (chan != 14) 1119 return -1; 1120 return 2414 + 5 * chan; 1121 case 83: /* channels 1..9; 40 MHz */ 1122 case 84: /* channels 5..13; 40 MHz */ 1123 if (chan < 1 || chan > 13) 1124 return -1; 1125 return 2407 + 5 * chan; 1126 case 115: /* channels 36,40,44,48; indoor only */ 1127 case 116: /* channels 36,44; 40 MHz; indoor only */ 1128 case 117: /* channels 40,48; 40 MHz; indoor only */ 1129 case 118: /* channels 52,56,60,64; dfs */ 1130 case 119: /* channels 52,60; 40 MHz; dfs */ 1131 case 120: /* channels 56,64; 40 MHz; dfs */ 1132 if (chan < 36 || chan > 64) 1133 return -1; 1134 return 5000 + 5 * chan; 1135 case 121: /* channels 100-140 */ 1136 case 122: /* channels 100-142; 40 MHz */ 1137 case 123: /* channels 104-136; 40 MHz */ 1138 if (chan < 100 || chan > 140) 1139 return -1; 1140 return 5000 + 5 * chan; 1141 case 124: /* channels 149,153,157,161 */ 1142 case 126: /* channels 149,157; 40 MHz */ 1143 case 127: /* channels 153,161; 40 MHz */ 1144 if (chan < 149 || chan > 161) 1145 return -1; 1146 return 5000 + 5 * chan; 1147 case 125: /* channels 149,153,157,161,165,169 */ 1148 if (chan < 149 || chan > 169) 1149 return -1; 1150 return 5000 + 5 * chan; 1151 case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */ 1152 case 130: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */ 1153 if (chan < 36 || chan > 161) 1154 return -1; 1155 return 5000 + 5 * chan; 1156 case 129: /* center freqs 50, 114; 160 MHz */ 1157 if (chan < 36 || chan > 128) 1158 return -1; 1159 return 5000 + 5 * chan; 1160 case 180: /* 60 GHz band, channels 1..4 */ 1161 if (chan < 1 || chan > 4) 1162 return -1; 1163 return 56160 + 2160 * chan; 1164 } 1165 return -1; 1166 } 1167 1168 /** 1169 * ieee80211_chan_to_freq - Convert channel info to frequency 1170 * @country: Country code, if known; otherwise, global operating class is used 1171 * @op_class: Operating class 1172 * @chan: Channel number 1173 * Returns: Frequency in MHz or -1 if the specified channel is unknown 1174 */ 1175 int ieee80211_chan_to_freq(const char *country, u8 op_class, u8 chan) 1176 { 1177 int freq; 1178 1179 if (country_match(us_op_class_cc, country)) { 1180 freq = ieee80211_chan_to_freq_us(op_class, chan); 1181 if (freq > 0) 1182 return freq; 1183 } 1184 1185 if (country_match(eu_op_class_cc, country)) { 1186 freq = ieee80211_chan_to_freq_eu(op_class, chan); 1187 if (freq > 0) 1188 return freq; 1189 } 1190 1191 if (country_match(jp_op_class_cc, country)) { 1192 freq = ieee80211_chan_to_freq_jp(op_class, chan); 1193 if (freq > 0) 1194 return freq; 1195 } 1196 1197 if (country_match(cn_op_class_cc, country)) { 1198 freq = ieee80211_chan_to_freq_cn(op_class, chan); 1199 if (freq > 0) 1200 return freq; 1201 } 1202 1203 return ieee80211_chan_to_freq_global(op_class, chan); 1204 } 1205 1206 1207 int ieee80211_is_dfs(int freq, const struct hostapd_hw_modes *modes, 1208 u16 num_modes) 1209 { 1210 int i, j; 1211 1212 if (!modes || !num_modes) 1213 return (freq >= 5260 && freq <= 5320) || 1214 (freq >= 5500 && freq <= 5700); 1215 1216 for (i = 0; i < num_modes; i++) { 1217 for (j = 0; j < modes[i].num_channels; j++) { 1218 if (modes[i].channels[j].freq == freq && 1219 (modes[i].channels[j].flag & HOSTAPD_CHAN_RADAR)) 1220 return 1; 1221 } 1222 } 1223 1224 return 0; 1225 } 1226 1227 1228 static int is_11b(u8 rate) 1229 { 1230 return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16; 1231 } 1232 1233 1234 int supp_rates_11b_only(struct ieee802_11_elems *elems) 1235 { 1236 int num_11b = 0, num_others = 0; 1237 int i; 1238 1239 if (elems->supp_rates == NULL && elems->ext_supp_rates == NULL) 1240 return 0; 1241 1242 for (i = 0; elems->supp_rates && i < elems->supp_rates_len; i++) { 1243 if (is_11b(elems->supp_rates[i])) 1244 num_11b++; 1245 else 1246 num_others++; 1247 } 1248 1249 for (i = 0; elems->ext_supp_rates && i < elems->ext_supp_rates_len; 1250 i++) { 1251 if (is_11b(elems->ext_supp_rates[i])) 1252 num_11b++; 1253 else 1254 num_others++; 1255 } 1256 1257 return num_11b > 0 && num_others == 0; 1258 } 1259 1260 1261 const char * fc2str(u16 fc) 1262 { 1263 u16 stype = WLAN_FC_GET_STYPE(fc); 1264 #define C2S(x) case x: return #x; 1265 1266 switch (WLAN_FC_GET_TYPE(fc)) { 1267 case WLAN_FC_TYPE_MGMT: 1268 switch (stype) { 1269 C2S(WLAN_FC_STYPE_ASSOC_REQ) 1270 C2S(WLAN_FC_STYPE_ASSOC_RESP) 1271 C2S(WLAN_FC_STYPE_REASSOC_REQ) 1272 C2S(WLAN_FC_STYPE_REASSOC_RESP) 1273 C2S(WLAN_FC_STYPE_PROBE_REQ) 1274 C2S(WLAN_FC_STYPE_PROBE_RESP) 1275 C2S(WLAN_FC_STYPE_BEACON) 1276 C2S(WLAN_FC_STYPE_ATIM) 1277 C2S(WLAN_FC_STYPE_DISASSOC) 1278 C2S(WLAN_FC_STYPE_AUTH) 1279 C2S(WLAN_FC_STYPE_DEAUTH) 1280 C2S(WLAN_FC_STYPE_ACTION) 1281 } 1282 break; 1283 case WLAN_FC_TYPE_CTRL: 1284 switch (stype) { 1285 C2S(WLAN_FC_STYPE_PSPOLL) 1286 C2S(WLAN_FC_STYPE_RTS) 1287 C2S(WLAN_FC_STYPE_CTS) 1288 C2S(WLAN_FC_STYPE_ACK) 1289 C2S(WLAN_FC_STYPE_CFEND) 1290 C2S(WLAN_FC_STYPE_CFENDACK) 1291 } 1292 break; 1293 case WLAN_FC_TYPE_DATA: 1294 switch (stype) { 1295 C2S(WLAN_FC_STYPE_DATA) 1296 C2S(WLAN_FC_STYPE_DATA_CFACK) 1297 C2S(WLAN_FC_STYPE_DATA_CFPOLL) 1298 C2S(WLAN_FC_STYPE_DATA_CFACKPOLL) 1299 C2S(WLAN_FC_STYPE_NULLFUNC) 1300 C2S(WLAN_FC_STYPE_CFACK) 1301 C2S(WLAN_FC_STYPE_CFPOLL) 1302 C2S(WLAN_FC_STYPE_CFACKPOLL) 1303 C2S(WLAN_FC_STYPE_QOS_DATA) 1304 C2S(WLAN_FC_STYPE_QOS_DATA_CFACK) 1305 C2S(WLAN_FC_STYPE_QOS_DATA_CFPOLL) 1306 C2S(WLAN_FC_STYPE_QOS_DATA_CFACKPOLL) 1307 C2S(WLAN_FC_STYPE_QOS_NULL) 1308 C2S(WLAN_FC_STYPE_QOS_CFPOLL) 1309 C2S(WLAN_FC_STYPE_QOS_CFACKPOLL) 1310 } 1311 break; 1312 } 1313 return "WLAN_FC_TYPE_UNKNOWN"; 1314 #undef C2S 1315 } 1316 1317 1318 int mb_ies_info_by_ies(struct mb_ies_info *info, const u8 *ies_buf, 1319 size_t ies_len) 1320 { 1321 const struct element *elem; 1322 1323 os_memset(info, 0, sizeof(*info)); 1324 1325 if (!ies_buf) 1326 return 0; 1327 1328 for_each_element_id(elem, WLAN_EID_MULTI_BAND, ies_buf, ies_len) { 1329 if (info->nof_ies >= MAX_NOF_MB_IES_SUPPORTED) 1330 return 0; 1331 1332 wpa_printf(MSG_DEBUG, "MB IE of %u bytes found", 1333 elem->datalen + 2); 1334 info->ies[info->nof_ies].ie = elem->data; 1335 info->ies[info->nof_ies].ie_len = elem->datalen; 1336 info->nof_ies++; 1337 } 1338 1339 if (!for_each_element_completed(elem, ies_buf, ies_len)) { 1340 wpa_hexdump(MSG_DEBUG, "Truncated IEs", ies_buf, ies_len); 1341 return -1; 1342 } 1343 1344 return 0; 1345 } 1346 1347 1348 struct wpabuf * mb_ies_by_info(struct mb_ies_info *info) 1349 { 1350 struct wpabuf *mb_ies = NULL; 1351 1352 WPA_ASSERT(info != NULL); 1353 1354 if (info->nof_ies) { 1355 u8 i; 1356 size_t mb_ies_size = 0; 1357 1358 for (i = 0; i < info->nof_ies; i++) 1359 mb_ies_size += 2 + info->ies[i].ie_len; 1360 1361 mb_ies = wpabuf_alloc(mb_ies_size); 1362 if (mb_ies) { 1363 for (i = 0; i < info->nof_ies; i++) { 1364 wpabuf_put_u8(mb_ies, WLAN_EID_MULTI_BAND); 1365 wpabuf_put_u8(mb_ies, info->ies[i].ie_len); 1366 wpabuf_put_data(mb_ies, 1367 info->ies[i].ie, 1368 info->ies[i].ie_len); 1369 } 1370 } 1371 } 1372 1373 return mb_ies; 1374 } 1375 1376 1377 const struct oper_class_map global_op_class[] = { 1378 { HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20, P2P_SUPP }, 1379 { HOSTAPD_MODE_IEEE80211G, 82, 14, 14, 1, BW20, NO_P2P_SUPP }, 1380 1381 /* Do not enable HT40 on 2.4 GHz for P2P use for now */ 1382 { HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS, NO_P2P_SUPP }, 1383 { HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS, NO_P2P_SUPP }, 1384 1385 { HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20, P2P_SUPP }, 1386 { HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS, P2P_SUPP }, 1387 { HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS, P2P_SUPP }, 1388 { HOSTAPD_MODE_IEEE80211A, 118, 52, 64, 4, BW20, NO_P2P_SUPP }, 1389 { HOSTAPD_MODE_IEEE80211A, 119, 52, 60, 8, BW40PLUS, NO_P2P_SUPP }, 1390 { HOSTAPD_MODE_IEEE80211A, 120, 56, 64, 8, BW40MINUS, NO_P2P_SUPP }, 1391 { HOSTAPD_MODE_IEEE80211A, 121, 100, 140, 4, BW20, NO_P2P_SUPP }, 1392 { HOSTAPD_MODE_IEEE80211A, 122, 100, 132, 8, BW40PLUS, NO_P2P_SUPP }, 1393 { HOSTAPD_MODE_IEEE80211A, 123, 104, 136, 8, BW40MINUS, NO_P2P_SUPP }, 1394 { HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20, P2P_SUPP }, 1395 { HOSTAPD_MODE_IEEE80211A, 125, 149, 169, 4, BW20, P2P_SUPP }, 1396 { HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8, BW40PLUS, P2P_SUPP }, 1397 { HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8, BW40MINUS, P2P_SUPP }, 1398 1399 /* 1400 * IEEE P802.11ac/D7.0 Table E-4 actually talks about channel center 1401 * frequency index 42, 58, 106, 122, 138, 155 with channel spacing of 1402 * 80 MHz, but currently use the following definition for simplicity 1403 * (these center frequencies are not actual channels, which makes 1404 * wpas_p2p_allow_channel() fail). wpas_p2p_verify_80mhz() should take 1405 * care of removing invalid channels. 1406 */ 1407 { HOSTAPD_MODE_IEEE80211A, 128, 36, 161, 4, BW80, P2P_SUPP }, 1408 { HOSTAPD_MODE_IEEE80211A, 129, 50, 114, 16, BW160, P2P_SUPP }, 1409 { HOSTAPD_MODE_IEEE80211A, 130, 36, 161, 4, BW80P80, P2P_SUPP }, 1410 { HOSTAPD_MODE_IEEE80211AD, 180, 1, 4, 1, BW2160, P2P_SUPP }, 1411 { -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP } 1412 }; 1413 1414 1415 static enum phy_type ieee80211_phy_type_by_freq(int freq) 1416 { 1417 enum hostapd_hw_mode hw_mode; 1418 u8 channel; 1419 1420 hw_mode = ieee80211_freq_to_chan(freq, &channel); 1421 1422 switch (hw_mode) { 1423 case HOSTAPD_MODE_IEEE80211A: 1424 return PHY_TYPE_OFDM; 1425 case HOSTAPD_MODE_IEEE80211B: 1426 return PHY_TYPE_HRDSSS; 1427 case HOSTAPD_MODE_IEEE80211G: 1428 return PHY_TYPE_ERP; 1429 case HOSTAPD_MODE_IEEE80211AD: 1430 return PHY_TYPE_DMG; 1431 default: 1432 return PHY_TYPE_UNSPECIFIED; 1433 }; 1434 } 1435 1436 1437 /* ieee80211_get_phy_type - Derive the phy type by freq and bandwidth */ 1438 enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht) 1439 { 1440 if (vht) 1441 return PHY_TYPE_VHT; 1442 if (ht) 1443 return PHY_TYPE_HT; 1444 1445 return ieee80211_phy_type_by_freq(freq); 1446 } 1447 1448 1449 size_t global_op_class_size = ARRAY_SIZE(global_op_class); 1450 1451 1452 /** 1453 * get_ie - Fetch a specified information element from IEs buffer 1454 * @ies: Information elements buffer 1455 * @len: Information elements buffer length 1456 * @eid: Information element identifier (WLAN_EID_*) 1457 * Returns: Pointer to the information element (id field) or %NULL if not found 1458 * 1459 * This function returns the first matching information element in the IEs 1460 * buffer or %NULL in case the element is not found. 1461 */ 1462 const u8 * get_ie(const u8 *ies, size_t len, u8 eid) 1463 { 1464 const struct element *elem; 1465 1466 if (!ies) 1467 return NULL; 1468 1469 for_each_element_id(elem, eid, ies, len) 1470 return &elem->id; 1471 1472 return NULL; 1473 } 1474 1475 1476 /** 1477 * get_ie_ext - Fetch a specified extended information element from IEs buffer 1478 * @ies: Information elements buffer 1479 * @len: Information elements buffer length 1480 * @ext: Information element extension identifier (WLAN_EID_EXT_*) 1481 * Returns: Pointer to the information element (id field) or %NULL if not found 1482 * 1483 * This function returns the first matching information element in the IEs 1484 * buffer or %NULL in case the element is not found. 1485 */ 1486 const u8 * get_ie_ext(const u8 *ies, size_t len, u8 ext) 1487 { 1488 const struct element *elem; 1489 1490 if (!ies) 1491 return NULL; 1492 1493 for_each_element_extid(elem, ext, ies, len) 1494 return &elem->id; 1495 1496 return NULL; 1497 } 1498 1499 1500 const u8 * get_vendor_ie(const u8 *ies, size_t len, u32 vendor_type) 1501 { 1502 const struct element *elem; 1503 1504 for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, len) { 1505 if (elem->datalen >= 4 && 1506 vendor_type == WPA_GET_BE32(elem->data)) 1507 return &elem->id; 1508 } 1509 1510 return NULL; 1511 } 1512 1513 1514 size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len) 1515 { 1516 /* 1517 * MBO IE requires 6 bytes without the attributes: EID (1), length (1), 1518 * OUI (3), OUI type (1). 1519 */ 1520 if (len < 6 + attr_len) { 1521 wpa_printf(MSG_DEBUG, 1522 "MBO: Not enough room in buffer for MBO IE: buf len = %zu, attr_len = %zu", 1523 len, attr_len); 1524 return 0; 1525 } 1526 1527 *buf++ = WLAN_EID_VENDOR_SPECIFIC; 1528 *buf++ = attr_len + 4; 1529 WPA_PUT_BE24(buf, OUI_WFA); 1530 buf += 3; 1531 *buf++ = MBO_OUI_TYPE; 1532 os_memcpy(buf, attr, attr_len); 1533 1534 return 6 + attr_len; 1535 } 1536 1537 1538 size_t add_multi_ap_ie(u8 *buf, size_t len, u8 value) 1539 { 1540 u8 *pos = buf; 1541 1542 if (len < 9) 1543 return 0; 1544 1545 *pos++ = WLAN_EID_VENDOR_SPECIFIC; 1546 *pos++ = 7; /* len */ 1547 WPA_PUT_BE24(pos, OUI_WFA); 1548 pos += 3; 1549 *pos++ = MULTI_AP_OUI_TYPE; 1550 *pos++ = MULTI_AP_SUB_ELEM_TYPE; 1551 *pos++ = 1; /* len */ 1552 *pos++ = value; 1553 1554 return pos - buf; 1555 } 1556 1557 1558 static const struct country_op_class us_op_class[] = { 1559 { 1, 115 }, 1560 { 2, 118 }, 1561 { 3, 124 }, 1562 { 4, 121 }, 1563 { 5, 125 }, 1564 { 12, 81 }, 1565 { 22, 116 }, 1566 { 23, 119 }, 1567 { 24, 122 }, 1568 { 25, 126 }, 1569 { 26, 126 }, 1570 { 27, 117 }, 1571 { 28, 120 }, 1572 { 29, 123 }, 1573 { 30, 127 }, 1574 { 31, 127 }, 1575 { 32, 83 }, 1576 { 33, 84 }, 1577 { 34, 180 }, 1578 }; 1579 1580 static const struct country_op_class eu_op_class[] = { 1581 { 1, 115 }, 1582 { 2, 118 }, 1583 { 3, 121 }, 1584 { 4, 81 }, 1585 { 5, 116 }, 1586 { 6, 119 }, 1587 { 7, 122 }, 1588 { 8, 117 }, 1589 { 9, 120 }, 1590 { 10, 123 }, 1591 { 11, 83 }, 1592 { 12, 84 }, 1593 { 17, 125 }, 1594 { 18, 180 }, 1595 }; 1596 1597 static const struct country_op_class jp_op_class[] = { 1598 { 1, 115 }, 1599 { 30, 81 }, 1600 { 31, 82 }, 1601 { 32, 118 }, 1602 { 33, 118 }, 1603 { 34, 121 }, 1604 { 35, 121 }, 1605 { 36, 116 }, 1606 { 37, 119 }, 1607 { 38, 119 }, 1608 { 39, 122 }, 1609 { 40, 122 }, 1610 { 41, 117 }, 1611 { 42, 120 }, 1612 { 43, 120 }, 1613 { 44, 123 }, 1614 { 45, 123 }, 1615 { 56, 83 }, 1616 { 57, 84 }, 1617 { 58, 121 }, 1618 { 59, 180 }, 1619 }; 1620 1621 static const struct country_op_class cn_op_class[] = { 1622 { 1, 115 }, 1623 { 2, 118 }, 1624 { 3, 125 }, 1625 { 4, 116 }, 1626 { 5, 119 }, 1627 { 6, 126 }, 1628 { 7, 81 }, 1629 { 8, 83 }, 1630 { 9, 84 }, 1631 }; 1632 1633 static u8 1634 global_op_class_from_country_array(u8 op_class, size_t array_size, 1635 const struct country_op_class *country_array) 1636 { 1637 size_t i; 1638 1639 for (i = 0; i < array_size; i++) { 1640 if (country_array[i].country_op_class == op_class) 1641 return country_array[i].global_op_class; 1642 } 1643 1644 return 0; 1645 } 1646 1647 1648 u8 country_to_global_op_class(const char *country, u8 op_class) 1649 { 1650 const struct country_op_class *country_array; 1651 size_t size; 1652 u8 g_op_class; 1653 1654 if (country_match(us_op_class_cc, country)) { 1655 country_array = us_op_class; 1656 size = ARRAY_SIZE(us_op_class); 1657 } else if (country_match(eu_op_class_cc, country)) { 1658 country_array = eu_op_class; 1659 size = ARRAY_SIZE(eu_op_class); 1660 } else if (country_match(jp_op_class_cc, country)) { 1661 country_array = jp_op_class; 1662 size = ARRAY_SIZE(jp_op_class); 1663 } else if (country_match(cn_op_class_cc, country)) { 1664 country_array = cn_op_class; 1665 size = ARRAY_SIZE(cn_op_class); 1666 } else { 1667 /* 1668 * Countries that do not match any of the above countries use 1669 * global operating classes 1670 */ 1671 return op_class; 1672 } 1673 1674 g_op_class = global_op_class_from_country_array(op_class, size, 1675 country_array); 1676 1677 /* 1678 * If the given operating class did not match any of the country's 1679 * operating classes, assume that global operating class is used. 1680 */ 1681 return g_op_class ? g_op_class : op_class; 1682 } 1683 1684 1685 const struct oper_class_map * get_oper_class(const char *country, u8 op_class) 1686 { 1687 const struct oper_class_map *op; 1688 1689 if (country) 1690 op_class = country_to_global_op_class(country, op_class); 1691 1692 op = &global_op_class[0]; 1693 while (op->op_class && op->op_class != op_class) 1694 op++; 1695 1696 if (!op->op_class) 1697 return NULL; 1698 1699 return op; 1700 } 1701 1702 1703 int oper_class_bw_to_int(const struct oper_class_map *map) 1704 { 1705 switch (map->bw) { 1706 case BW20: 1707 return 20; 1708 case BW40PLUS: 1709 case BW40MINUS: 1710 return 40; 1711 case BW80: 1712 return 80; 1713 case BW80P80: 1714 case BW160: 1715 return 160; 1716 case BW2160: 1717 return 2160; 1718 default: 1719 return 0; 1720 } 1721 } 1722 1723 1724 int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep, 1725 size_t nei_rep_len) 1726 { 1727 u8 *nei_pos = nei_rep; 1728 const char *end; 1729 1730 /* 1731 * BSS Transition Candidate List Entries - Neighbor Report elements 1732 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>, 1733 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>] 1734 */ 1735 while (pos) { 1736 u8 *nei_start; 1737 long int val; 1738 char *endptr, *tmp; 1739 1740 pos = os_strstr(pos, " neighbor="); 1741 if (!pos) 1742 break; 1743 if (nei_pos + 15 > nei_rep + nei_rep_len) { 1744 wpa_printf(MSG_DEBUG, 1745 "Not enough room for additional neighbor"); 1746 return -1; 1747 } 1748 pos += 10; 1749 1750 nei_start = nei_pos; 1751 *nei_pos++ = WLAN_EID_NEIGHBOR_REPORT; 1752 nei_pos++; /* length to be filled in */ 1753 1754 if (hwaddr_aton(pos, nei_pos)) { 1755 wpa_printf(MSG_DEBUG, "Invalid BSSID"); 1756 return -1; 1757 } 1758 nei_pos += ETH_ALEN; 1759 pos += 17; 1760 if (*pos != ',') { 1761 wpa_printf(MSG_DEBUG, "Missing BSSID Information"); 1762 return -1; 1763 } 1764 pos++; 1765 1766 val = strtol(pos, &endptr, 0); 1767 WPA_PUT_LE32(nei_pos, val); 1768 nei_pos += 4; 1769 if (*endptr != ',') { 1770 wpa_printf(MSG_DEBUG, "Missing Operating Class"); 1771 return -1; 1772 } 1773 pos = endptr + 1; 1774 1775 *nei_pos++ = atoi(pos); /* Operating Class */ 1776 pos = os_strchr(pos, ','); 1777 if (pos == NULL) { 1778 wpa_printf(MSG_DEBUG, "Missing Channel Number"); 1779 return -1; 1780 } 1781 pos++; 1782 1783 *nei_pos++ = atoi(pos); /* Channel Number */ 1784 pos = os_strchr(pos, ','); 1785 if (pos == NULL) { 1786 wpa_printf(MSG_DEBUG, "Missing PHY Type"); 1787 return -1; 1788 } 1789 pos++; 1790 1791 *nei_pos++ = atoi(pos); /* PHY Type */ 1792 end = os_strchr(pos, ' '); 1793 tmp = os_strchr(pos, ','); 1794 if (tmp && (!end || tmp < end)) { 1795 /* Optional Subelements (hexdump) */ 1796 size_t len; 1797 1798 pos = tmp + 1; 1799 end = os_strchr(pos, ' '); 1800 if (end) 1801 len = end - pos; 1802 else 1803 len = os_strlen(pos); 1804 if (nei_pos + len / 2 > nei_rep + nei_rep_len) { 1805 wpa_printf(MSG_DEBUG, 1806 "Not enough room for neighbor subelements"); 1807 return -1; 1808 } 1809 if (len & 0x01 || 1810 hexstr2bin(pos, nei_pos, len / 2) < 0) { 1811 wpa_printf(MSG_DEBUG, 1812 "Invalid neighbor subelement info"); 1813 return -1; 1814 } 1815 nei_pos += len / 2; 1816 pos = end; 1817 } 1818 1819 nei_start[1] = nei_pos - nei_start - 2; 1820 } 1821 1822 return nei_pos - nei_rep; 1823 } 1824 1825 1826 int ieee802_11_ext_capab(const u8 *ie, unsigned int capab) 1827 { 1828 if (!ie || ie[1] <= capab / 8) 1829 return 0; 1830 return !!(ie[2 + capab / 8] & BIT(capab % 8)); 1831 } 1832