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