1 /* 2 * IEEE 802.11 Common routines 3 * Copyright (c) 2002-2015, Jouni Malinen <j (at) 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 "qca-vendor.h" 15 #include "ieee802_11_defs.h" 16 #include "ieee802_11_common.h" 17 18 19 static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen, 20 struct ieee802_11_elems *elems, 21 int show_errors) 22 { 23 unsigned int oui; 24 25 /* first 3 bytes in vendor specific information element are the IEEE 26 * OUI of the vendor. The following byte is used a vendor specific 27 * sub-type. */ 28 if (elen < 4) { 29 if (show_errors) { 30 wpa_printf(MSG_MSGDUMP, "short vendor specific " 31 "information element ignored (len=%lu)", 32 (unsigned long) elen); 33 } 34 return -1; 35 } 36 37 oui = WPA_GET_BE24(pos); 38 switch (oui) { 39 case OUI_MICROSOFT: 40 /* Microsoft/Wi-Fi information elements are further typed and 41 * subtyped */ 42 switch (pos[3]) { 43 case 1: 44 /* Microsoft OUI (00:50:F2) with OUI Type 1: 45 * real WPA information element */ 46 elems->wpa_ie = pos; 47 elems->wpa_ie_len = elen; 48 break; 49 case WMM_OUI_TYPE: 50 /* WMM information element */ 51 if (elen < 5) { 52 wpa_printf(MSG_MSGDUMP, "short WMM " 53 "information element ignored " 54 "(len=%lu)", 55 (unsigned long) elen); 56 return -1; 57 } 58 switch (pos[4]) { 59 case WMM_OUI_SUBTYPE_INFORMATION_ELEMENT: 60 case WMM_OUI_SUBTYPE_PARAMETER_ELEMENT: 61 /* 62 * Share same pointer since only one of these 63 * is used and they start with same data. 64 * Length field can be used to distinguish the 65 * IEs. 66 */ 67 elems->wmm = pos; 68 elems->wmm_len = elen; 69 break; 70 case WMM_OUI_SUBTYPE_TSPEC_ELEMENT: 71 elems->wmm_tspec = pos; 72 elems->wmm_tspec_len = elen; 73 break; 74 default: 75 wpa_printf(MSG_EXCESSIVE, "unknown WMM " 76 "information element ignored " 77 "(subtype=%d len=%lu)", 78 pos[4], (unsigned long) elen); 79 return -1; 80 } 81 break; 82 case 4: 83 /* Wi-Fi Protected Setup (WPS) IE */ 84 elems->wps_ie = pos; 85 elems->wps_ie_len = elen; 86 break; 87 default: 88 wpa_printf(MSG_EXCESSIVE, "Unknown Microsoft " 89 "information element ignored " 90 "(type=%d len=%lu)", 91 pos[3], (unsigned long) elen); 92 return -1; 93 } 94 break; 95 96 case OUI_WFA: 97 switch (pos[3]) { 98 case P2P_OUI_TYPE: 99 /* Wi-Fi Alliance - P2P IE */ 100 elems->p2p = pos; 101 elems->p2p_len = elen; 102 break; 103 case WFD_OUI_TYPE: 104 /* Wi-Fi Alliance - WFD IE */ 105 elems->wfd = pos; 106 elems->wfd_len = elen; 107 break; 108 case HS20_INDICATION_OUI_TYPE: 109 /* Hotspot 2.0 */ 110 elems->hs20 = pos; 111 elems->hs20_len = elen; 112 break; 113 case HS20_OSEN_OUI_TYPE: 114 /* Hotspot 2.0 OSEN */ 115 elems->osen = pos; 116 elems->osen_len = elen; 117 break; 118 case MBO_OUI_TYPE: 119 /* MBO-OCE */ 120 elems->mbo = pos; 121 elems->mbo_len = elen; 122 break; 123 default: 124 wpa_printf(MSG_MSGDUMP, "Unknown WFA " 125 "information element ignored " 126 "(type=%d len=%lu)", 127 pos[3], (unsigned long) elen); 128 return -1; 129 } 130 break; 131 132 case OUI_BROADCOM: 133 switch (pos[3]) { 134 case VENDOR_HT_CAPAB_OUI_TYPE: 135 elems->vendor_ht_cap = pos; 136 elems->vendor_ht_cap_len = elen; 137 break; 138 case VENDOR_VHT_TYPE: 139 if (elen > 4 && 140 (pos[4] == VENDOR_VHT_SUBTYPE || 141 pos[4] == VENDOR_VHT_SUBTYPE2)) { 142 elems->vendor_vht = pos; 143 elems->vendor_vht_len = elen; 144 } else 145 return -1; 146 break; 147 default: 148 wpa_printf(MSG_EXCESSIVE, "Unknown Broadcom " 149 "information element ignored " 150 "(type=%d len=%lu)", 151 pos[3], (unsigned long) elen); 152 return -1; 153 } 154 break; 155 156 case OUI_QCA: 157 switch (pos[3]) { 158 case QCA_VENDOR_ELEM_P2P_PREF_CHAN_LIST: 159 elems->pref_freq_list = pos; 160 elems->pref_freq_list_len = elen; 161 break; 162 default: 163 wpa_printf(MSG_EXCESSIVE, 164 "Unknown QCA information element ignored (type=%d len=%lu)", 165 pos[3], (unsigned long) elen); 166 return -1; 167 } 168 break; 169 170 default: 171 wpa_printf(MSG_EXCESSIVE, "unknown vendor specific " 172 "information element ignored (vendor OUI " 173 "%02x:%02x:%02x len=%lu)", 174 pos[0], pos[1], pos[2], (unsigned long) elen); 175 return -1; 176 } 177 178 return 0; 179 } 180 181 182 static int ieee802_11_parse_extension(const u8 *pos, size_t elen, 183 struct ieee802_11_elems *elems, 184 int show_errors) 185 { 186 u8 ext_id; 187 188 if (elen < 1) { 189 if (show_errors) { 190 wpa_printf(MSG_MSGDUMP, 191 "short information element (Ext)"); 192 } 193 return -1; 194 } 195 196 ext_id = *pos++; 197 elen--; 198 199 switch (ext_id) { 200 case WLAN_EID_EXT_ASSOC_DELAY_INFO: 201 if (elen != 1) 202 break; 203 elems->assoc_delay_info = pos; 204 break; 205 case WLAN_EID_EXT_FILS_REQ_PARAMS: 206 if (elen < 3) 207 break; 208 elems->fils_req_params = pos; 209 elems->fils_req_params_len = elen; 210 break; 211 case WLAN_EID_EXT_FILS_KEY_CONFIRM: 212 elems->fils_key_confirm = pos; 213 elems->fils_key_confirm_len = elen; 214 break; 215 case WLAN_EID_EXT_FILS_SESSION: 216 if (elen != FILS_SESSION_LEN) 217 break; 218 elems->fils_session = pos; 219 break; 220 case WLAN_EID_EXT_FILS_HLP_CONTAINER: 221 if (elen < 2 * ETH_ALEN) 222 break; 223 elems->fils_hlp = pos; 224 elems->fils_hlp_len = elen; 225 break; 226 case WLAN_EID_EXT_FILS_IP_ADDR_ASSIGN: 227 if (elen < 1) 228 break; 229 elems->fils_ip_addr_assign = pos; 230 elems->fils_ip_addr_assign_len = elen; 231 break; 232 case WLAN_EID_EXT_KEY_DELIVERY: 233 if (elen < WPA_KEY_RSC_LEN) 234 break; 235 elems->key_delivery = pos; 236 elems->key_delivery_len = elen; 237 break; 238 case WLAN_EID_EXT_FILS_WRAPPED_DATA: 239 elems->fils_wrapped_data = pos; 240 elems->fils_wrapped_data_len = elen; 241 break; 242 case WLAN_EID_EXT_FILS_PUBLIC_KEY: 243 if (elen < 1) 244 break; 245 elems->fils_pk = pos; 246 elems->fils_pk_len = elen; 247 break; 248 case WLAN_EID_EXT_FILS_NONCE: 249 if (elen != FILS_NONCE_LEN) 250 break; 251 elems->fils_nonce = pos; 252 break; 253 case WLAN_EID_EXT_OWE_DH_PARAM: 254 if (elen < 2) 255 break; 256 elems->owe_dh = pos; 257 elems->owe_dh_len = elen; 258 break; 259 default: 260 if (show_errors) { 261 wpa_printf(MSG_MSGDUMP, 262 "IEEE 802.11 element parsing ignored unknown element extension (ext_id=%u elen=%u)", 263 ext_id, (unsigned int) elen); 264 } 265 return -1; 266 } 267 268 return 0; 269 } 270 271 272 /** 273 * ieee802_11_parse_elems - Parse information elements in management frames 274 * @start: Pointer to the start of IEs 275 * @len: Length of IE buffer in octets 276 * @elems: Data structure for parsed elements 277 * @show_errors: Whether to show parsing errors in debug log 278 * Returns: Parsing result 279 */ 280 ParseRes ieee802_11_parse_elems(const u8 *start, size_t len, 281 struct ieee802_11_elems *elems, 282 int show_errors) 283 { 284 size_t left = len; 285 const u8 *pos = start; 286 int unknown = 0; 287 288 os_memset(elems, 0, sizeof(*elems)); 289 290 while (left >= 2) { 291 u8 id, elen; 292 293 id = *pos++; 294 elen = *pos++; 295 left -= 2; 296 297 if (elen > left) { 298 if (show_errors) { 299 wpa_printf(MSG_DEBUG, "IEEE 802.11 element " 300 "parse failed (id=%d elen=%d " 301 "left=%lu)", 302 id, elen, (unsigned long) left); 303 wpa_hexdump(MSG_MSGDUMP, "IEs", start, len); 304 } 305 return ParseFailed; 306 } 307 308 switch (id) { 309 case WLAN_EID_SSID: 310 if (elen > SSID_MAX_LEN) { 311 wpa_printf(MSG_DEBUG, 312 "Ignored too long SSID element (elen=%u)", 313 elen); 314 break; 315 } 316 elems->ssid = pos; 317 elems->ssid_len = elen; 318 break; 319 case WLAN_EID_SUPP_RATES: 320 elems->supp_rates = pos; 321 elems->supp_rates_len = elen; 322 break; 323 case WLAN_EID_DS_PARAMS: 324 if (elen < 1) 325 break; 326 elems->ds_params = pos; 327 break; 328 case WLAN_EID_CF_PARAMS: 329 case WLAN_EID_TIM: 330 break; 331 case WLAN_EID_CHALLENGE: 332 elems->challenge = pos; 333 elems->challenge_len = elen; 334 break; 335 case WLAN_EID_ERP_INFO: 336 if (elen < 1) 337 break; 338 elems->erp_info = pos; 339 break; 340 case WLAN_EID_EXT_SUPP_RATES: 341 elems->ext_supp_rates = pos; 342 elems->ext_supp_rates_len = elen; 343 break; 344 case WLAN_EID_VENDOR_SPECIFIC: 345 if (ieee802_11_parse_vendor_specific(pos, elen, 346 elems, 347 show_errors)) 348 unknown++; 349 break; 350 case WLAN_EID_RSN: 351 elems->rsn_ie = pos; 352 elems->rsn_ie_len = elen; 353 break; 354 case WLAN_EID_PWR_CAPABILITY: 355 break; 356 case WLAN_EID_SUPPORTED_CHANNELS: 357 elems->supp_channels = pos; 358 elems->supp_channels_len = elen; 359 break; 360 case WLAN_EID_MOBILITY_DOMAIN: 361 if (elen < sizeof(struct rsn_mdie)) 362 break; 363 elems->mdie = pos; 364 elems->mdie_len = elen; 365 break; 366 case WLAN_EID_FAST_BSS_TRANSITION: 367 if (elen < sizeof(struct rsn_ftie)) 368 break; 369 elems->ftie = pos; 370 elems->ftie_len = elen; 371 break; 372 case WLAN_EID_TIMEOUT_INTERVAL: 373 if (elen != 5) 374 break; 375 elems->timeout_int = pos; 376 break; 377 case WLAN_EID_HT_CAP: 378 if (elen < sizeof(struct ieee80211_ht_capabilities)) 379 break; 380 elems->ht_capabilities = pos; 381 break; 382 case WLAN_EID_HT_OPERATION: 383 if (elen < sizeof(struct ieee80211_ht_operation)) 384 break; 385 elems->ht_operation = pos; 386 break; 387 case WLAN_EID_MESH_CONFIG: 388 elems->mesh_config = pos; 389 elems->mesh_config_len = elen; 390 break; 391 case WLAN_EID_MESH_ID: 392 elems->mesh_id = pos; 393 elems->mesh_id_len = elen; 394 break; 395 case WLAN_EID_PEER_MGMT: 396 elems->peer_mgmt = pos; 397 elems->peer_mgmt_len = elen; 398 break; 399 case WLAN_EID_VHT_CAP: 400 if (elen < sizeof(struct ieee80211_vht_capabilities)) 401 break; 402 elems->vht_capabilities = pos; 403 break; 404 case WLAN_EID_VHT_OPERATION: 405 if (elen < sizeof(struct ieee80211_vht_operation)) 406 break; 407 elems->vht_operation = pos; 408 break; 409 case WLAN_EID_VHT_OPERATING_MODE_NOTIFICATION: 410 if (elen != 1) 411 break; 412 elems->vht_opmode_notif = pos; 413 break; 414 case WLAN_EID_LINK_ID: 415 if (elen < 18) 416 break; 417 elems->link_id = pos; 418 break; 419 case WLAN_EID_INTERWORKING: 420 elems->interworking = pos; 421 elems->interworking_len = elen; 422 break; 423 case WLAN_EID_QOS_MAP_SET: 424 if (elen < 16) 425 break; 426 elems->qos_map_set = pos; 427 elems->qos_map_set_len = elen; 428 break; 429 case WLAN_EID_EXT_CAPAB: 430 elems->ext_capab = pos; 431 elems->ext_capab_len = elen; 432 break; 433 case WLAN_EID_BSS_MAX_IDLE_PERIOD: 434 if (elen < 3) 435 break; 436 elems->bss_max_idle_period = pos; 437 break; 438 case WLAN_EID_SSID_LIST: 439 elems->ssid_list = pos; 440 elems->ssid_list_len = elen; 441 break; 442 case WLAN_EID_AMPE: 443 elems->ampe = pos; 444 elems->ampe_len = elen; 445 break; 446 case WLAN_EID_MIC: 447 elems->mic = pos; 448 elems->mic_len = elen; 449 /* after mic everything is encrypted, so stop. */ 450 left = elen; 451 break; 452 case WLAN_EID_MULTI_BAND: 453 if (elems->mb_ies.nof_ies >= MAX_NOF_MB_IES_SUPPORTED) { 454 wpa_printf(MSG_MSGDUMP, 455 "IEEE 802.11 element parse ignored MB IE (id=%d elen=%d)", 456 id, elen); 457 break; 458 } 459 460 elems->mb_ies.ies[elems->mb_ies.nof_ies].ie = pos; 461 elems->mb_ies.ies[elems->mb_ies.nof_ies].ie_len = elen; 462 elems->mb_ies.nof_ies++; 463 break; 464 case WLAN_EID_SUPPORTED_OPERATING_CLASSES: 465 elems->supp_op_classes = pos; 466 elems->supp_op_classes_len = elen; 467 break; 468 case WLAN_EID_RRM_ENABLED_CAPABILITIES: 469 elems->rrm_enabled = pos; 470 elems->rrm_enabled_len = elen; 471 break; 472 case WLAN_EID_CAG_NUMBER: 473 elems->cag_number = pos; 474 elems->cag_number_len = elen; 475 break; 476 case WLAN_EID_AP_CSN: 477 if (elen < 1) 478 break; 479 elems->ap_csn = pos; 480 break; 481 case WLAN_EID_FILS_INDICATION: 482 if (elen < 2) 483 break; 484 elems->fils_indic = pos; 485 elems->fils_indic_len = elen; 486 break; 487 case WLAN_EID_DILS: 488 if (elen < 2) 489 break; 490 elems->dils = pos; 491 elems->dils_len = elen; 492 break; 493 case WLAN_EID_FRAGMENT: 494 /* TODO */ 495 break; 496 case WLAN_EID_EXTENSION: 497 if (ieee802_11_parse_extension(pos, elen, elems, 498 show_errors)) 499 unknown++; 500 break; 501 default: 502 unknown++; 503 if (!show_errors) 504 break; 505 wpa_printf(MSG_MSGDUMP, "IEEE 802.11 element parse " 506 "ignored unknown element (id=%d elen=%d)", 507 id, elen); 508 break; 509 } 510 511 left -= elen; 512 pos += elen; 513 } 514 515 if (left) 516 return ParseFailed; 517 518 return unknown ? ParseUnknown : ParseOK; 519 } 520 521 522 int ieee802_11_ie_count(const u8 *ies, size_t ies_len) 523 { 524 int count = 0; 525 const u8 *pos, *end; 526 527 if (ies == NULL) 528 return 0; 529 530 pos = ies; 531 end = ies + ies_len; 532 533 while (end - pos >= 2) { 534 if (2 + pos[1] > end - pos) 535 break; 536 count++; 537 pos += 2 + pos[1]; 538 } 539 540 return count; 541 } 542 543 544 struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len, 545 u32 oui_type) 546 { 547 struct wpabuf *buf; 548 const u8 *end, *pos, *ie; 549 550 pos = ies; 551 end = ies + ies_len; 552 ie = NULL; 553 554 while (end - pos > 1) { 555 if (2 + pos[1] > end - pos) 556 return NULL; 557 if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && 558 WPA_GET_BE32(&pos[2]) == oui_type) { 559 ie = pos; 560 break; 561 } 562 pos += 2 + pos[1]; 563 } 564 565 if (ie == NULL) 566 return NULL; /* No specified vendor IE found */ 567 568 buf = wpabuf_alloc(ies_len); 569 if (buf == NULL) 570 return NULL; 571 572 /* 573 * There may be multiple vendor IEs in the message, so need to 574 * concatenate their data fields. 575 */ 576 while (end - pos > 1) { 577 if (2 + pos[1] > end - pos) 578 break; 579 if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && 580 WPA_GET_BE32(&pos[2]) == oui_type) 581 wpabuf_put_data(buf, pos + 6, pos[1] - 4); 582 pos += 2 + pos[1]; 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 static const char *const us_op_class_cc[] = { 886 "US", "CA", NULL 887 }; 888 889 static const char *const eu_op_class_cc[] = { 890 "AL", "AM", "AT", "AZ", "BA", "BE", "BG", "BY", "CH", "CY", "CZ", "DE", 891 "DK", "EE", "EL", "ES", "FI", "FR", "GE", "HR", "HU", "IE", "IS", "IT", 892 "LI", "LT", "LU", "LV", "MD", "ME", "MK", "MT", "NL", "NO", "PL", "PT", 893 "RO", "RS", "RU", "SE", "SI", "SK", "TR", "UA", "UK", NULL 894 }; 895 896 static const char *const jp_op_class_cc[] = { 897 "JP", NULL 898 }; 899 900 static const char *const cn_op_class_cc[] = { 901 "CN", NULL 902 }; 903 904 905 static int country_match(const char *const cc[], const char *const country) 906 { 907 int i; 908 909 if (country == NULL) 910 return 0; 911 for (i = 0; cc[i]; i++) { 912 if (cc[i][0] == country[0] && cc[i][1] == country[1]) 913 return 1; 914 } 915 916 return 0; 917 } 918 919 920 static int ieee80211_chan_to_freq_us(u8 op_class, u8 chan) 921 { 922 switch (op_class) { 923 case 12: /* channels 1..11 */ 924 case 32: /* channels 1..7; 40 MHz */ 925 case 33: /* channels 5..11; 40 MHz */ 926 if (chan < 1 || chan > 11) 927 return -1; 928 return 2407 + 5 * chan; 929 case 1: /* channels 36,40,44,48 */ 930 case 2: /* channels 52,56,60,64; dfs */ 931 case 22: /* channels 36,44; 40 MHz */ 932 case 23: /* channels 52,60; 40 MHz */ 933 case 27: /* channels 40,48; 40 MHz */ 934 case 28: /* channels 56,64; 40 MHz */ 935 if (chan < 36 || chan > 64) 936 return -1; 937 return 5000 + 5 * chan; 938 case 4: /* channels 100-144 */ 939 case 24: /* channels 100-140; 40 MHz */ 940 if (chan < 100 || chan > 144) 941 return -1; 942 return 5000 + 5 * chan; 943 case 3: /* channels 149,153,157,161 */ 944 case 25: /* channels 149,157; 40 MHz */ 945 case 26: /* channels 149,157; 40 MHz */ 946 case 30: /* channels 153,161; 40 MHz */ 947 case 31: /* channels 153,161; 40 MHz */ 948 if (chan < 149 || chan > 161) 949 return -1; 950 return 5000 + 5 * chan; 951 case 5: /* channels 149,153,157,161,165 */ 952 if (chan < 149 || chan > 165) 953 return -1; 954 return 5000 + 5 * chan; 955 case 34: /* 60 GHz band, channels 1..3 */ 956 if (chan < 1 || chan > 3) 957 return -1; 958 return 56160 + 2160 * chan; 959 } 960 return -1; 961 } 962 963 964 static int ieee80211_chan_to_freq_eu(u8 op_class, u8 chan) 965 { 966 switch (op_class) { 967 case 4: /* channels 1..13 */ 968 case 11: /* channels 1..9; 40 MHz */ 969 case 12: /* channels 5..13; 40 MHz */ 970 if (chan < 1 || chan > 13) 971 return -1; 972 return 2407 + 5 * chan; 973 case 1: /* channels 36,40,44,48 */ 974 case 2: /* channels 52,56,60,64; dfs */ 975 case 5: /* channels 36,44; 40 MHz */ 976 case 6: /* channels 52,60; 40 MHz */ 977 case 8: /* channels 40,48; 40 MHz */ 978 case 9: /* channels 56,64; 40 MHz */ 979 if (chan < 36 || chan > 64) 980 return -1; 981 return 5000 + 5 * chan; 982 case 3: /* channels 100-140 */ 983 case 7: /* channels 100-132; 40 MHz */ 984 case 10: /* channels 104-136; 40 MHz */ 985 case 16: /* channels 100-140 */ 986 if (chan < 100 || chan > 140) 987 return -1; 988 return 5000 + 5 * chan; 989 case 17: /* channels 149,153,157,161,165,169 */ 990 if (chan < 149 || chan > 169) 991 return -1; 992 return 5000 + 5 * chan; 993 case 18: /* 60 GHz band, channels 1..4 */ 994 if (chan < 1 || chan > 4) 995 return -1; 996 return 56160 + 2160 * chan; 997 } 998 return -1; 999 } 1000 1001 1002 static int ieee80211_chan_to_freq_jp(u8 op_class, u8 chan) 1003 { 1004 switch (op_class) { 1005 case 30: /* channels 1..13 */ 1006 case 56: /* channels 1..9; 40 MHz */ 1007 case 57: /* channels 5..13; 40 MHz */ 1008 if (chan < 1 || chan > 13) 1009 return -1; 1010 return 2407 + 5 * chan; 1011 case 31: /* channel 14 */ 1012 if (chan != 14) 1013 return -1; 1014 return 2414 + 5 * chan; 1015 case 1: /* channels 34,38,42,46(old) or 36,40,44,48 */ 1016 case 32: /* channels 52,56,60,64 */ 1017 case 33: /* channels 52,56,60,64 */ 1018 case 36: /* channels 36,44; 40 MHz */ 1019 case 37: /* channels 52,60; 40 MHz */ 1020 case 38: /* channels 52,60; 40 MHz */ 1021 case 41: /* channels 40,48; 40 MHz */ 1022 case 42: /* channels 56,64; 40 MHz */ 1023 case 43: /* channels 56,64; 40 MHz */ 1024 if (chan < 34 || chan > 64) 1025 return -1; 1026 return 5000 + 5 * chan; 1027 case 34: /* channels 100-140 */ 1028 case 35: /* channels 100-140 */ 1029 case 39: /* channels 100-132; 40 MHz */ 1030 case 40: /* channels 100-132; 40 MHz */ 1031 case 44: /* channels 104-136; 40 MHz */ 1032 case 45: /* channels 104-136; 40 MHz */ 1033 case 58: /* channels 100-140 */ 1034 if (chan < 100 || chan > 140) 1035 return -1; 1036 return 5000 + 5 * chan; 1037 case 59: /* 60 GHz band, channels 1..4 */ 1038 if (chan < 1 || chan > 3) 1039 return -1; 1040 return 56160 + 2160 * chan; 1041 } 1042 return -1; 1043 } 1044 1045 1046 static int ieee80211_chan_to_freq_cn(u8 op_class, u8 chan) 1047 { 1048 switch (op_class) { 1049 case 7: /* channels 1..13 */ 1050 case 8: /* channels 1..9; 40 MHz */ 1051 case 9: /* channels 5..13; 40 MHz */ 1052 if (chan < 1 || chan > 13) 1053 return -1; 1054 return 2407 + 5 * chan; 1055 case 1: /* channels 36,40,44,48 */ 1056 case 2: /* channels 52,56,60,64; dfs */ 1057 case 4: /* channels 36,44; 40 MHz */ 1058 case 5: /* channels 52,60; 40 MHz */ 1059 if (chan < 36 || chan > 64) 1060 return -1; 1061 return 5000 + 5 * chan; 1062 case 3: /* channels 149,153,157,161,165 */ 1063 case 6: /* channels 149,157; 40 MHz */ 1064 if (chan < 149 || chan > 165) 1065 return -1; 1066 return 5000 + 5 * chan; 1067 } 1068 return -1; 1069 } 1070 1071 1072 static int ieee80211_chan_to_freq_global(u8 op_class, u8 chan) 1073 { 1074 /* Table E-4 in IEEE Std 802.11-2012 - Global operating classes */ 1075 switch (op_class) { 1076 case 81: 1077 /* channels 1..13 */ 1078 if (chan < 1 || chan > 13) 1079 return -1; 1080 return 2407 + 5 * chan; 1081 case 82: 1082 /* channel 14 */ 1083 if (chan != 14) 1084 return -1; 1085 return 2414 + 5 * chan; 1086 case 83: /* channels 1..9; 40 MHz */ 1087 case 84: /* channels 5..13; 40 MHz */ 1088 if (chan < 1 || chan > 13) 1089 return -1; 1090 return 2407 + 5 * chan; 1091 case 115: /* channels 36,40,44,48; indoor only */ 1092 case 116: /* channels 36,44; 40 MHz; indoor only */ 1093 case 117: /* channels 40,48; 40 MHz; indoor only */ 1094 case 118: /* channels 52,56,60,64; dfs */ 1095 case 119: /* channels 52,60; 40 MHz; dfs */ 1096 case 120: /* channels 56,64; 40 MHz; dfs */ 1097 if (chan < 36 || chan > 64) 1098 return -1; 1099 return 5000 + 5 * chan; 1100 case 121: /* channels 100-140 */ 1101 case 122: /* channels 100-142; 40 MHz */ 1102 case 123: /* channels 104-136; 40 MHz */ 1103 if (chan < 100 || chan > 140) 1104 return -1; 1105 return 5000 + 5 * chan; 1106 case 124: /* channels 149,153,157,161 */ 1107 case 126: /* channels 149,157; 40 MHz */ 1108 case 127: /* channels 153,161; 40 MHz */ 1109 if (chan < 149 || chan > 161) 1110 return -1; 1111 return 5000 + 5 * chan; 1112 case 125: /* channels 149,153,157,161,165,169 */ 1113 if (chan < 149 || chan > 169) 1114 return -1; 1115 return 5000 + 5 * chan; 1116 case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */ 1117 case 130: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */ 1118 if (chan < 36 || chan > 161) 1119 return -1; 1120 return 5000 + 5 * chan; 1121 case 129: /* center freqs 50, 114; 160 MHz */ 1122 if (chan < 36 || chan > 128) 1123 return -1; 1124 return 5000 + 5 * chan; 1125 case 180: /* 60 GHz band, channels 1..4 */ 1126 if (chan < 1 || chan > 4) 1127 return -1; 1128 return 56160 + 2160 * chan; 1129 } 1130 return -1; 1131 } 1132 1133 /** 1134 * ieee80211_chan_to_freq - Convert channel info to frequency 1135 * @country: Country code, if known; otherwise, global operating class is used 1136 * @op_class: Operating class 1137 * @chan: Channel number 1138 * Returns: Frequency in MHz or -1 if the specified channel is unknown 1139 */ 1140 int ieee80211_chan_to_freq(const char *country, u8 op_class, u8 chan) 1141 { 1142 int freq; 1143 1144 if (country_match(us_op_class_cc, country)) { 1145 freq = ieee80211_chan_to_freq_us(op_class, chan); 1146 if (freq > 0) 1147 return freq; 1148 } 1149 1150 if (country_match(eu_op_class_cc, country)) { 1151 freq = ieee80211_chan_to_freq_eu(op_class, chan); 1152 if (freq > 0) 1153 return freq; 1154 } 1155 1156 if (country_match(jp_op_class_cc, country)) { 1157 freq = ieee80211_chan_to_freq_jp(op_class, chan); 1158 if (freq > 0) 1159 return freq; 1160 } 1161 1162 if (country_match(cn_op_class_cc, country)) { 1163 freq = ieee80211_chan_to_freq_cn(op_class, chan); 1164 if (freq > 0) 1165 return freq; 1166 } 1167 1168 return ieee80211_chan_to_freq_global(op_class, chan); 1169 } 1170 1171 1172 int ieee80211_is_dfs(int freq) 1173 { 1174 /* TODO: this could be more accurate to better cover all domains */ 1175 return (freq >= 5260 && freq <= 5320) || (freq >= 5500 && freq <= 5700); 1176 } 1177 1178 1179 static int is_11b(u8 rate) 1180 { 1181 return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16; 1182 } 1183 1184 1185 int supp_rates_11b_only(struct ieee802_11_elems *elems) 1186 { 1187 int num_11b = 0, num_others = 0; 1188 int i; 1189 1190 if (elems->supp_rates == NULL && elems->ext_supp_rates == NULL) 1191 return 0; 1192 1193 for (i = 0; elems->supp_rates && i < elems->supp_rates_len; i++) { 1194 if (is_11b(elems->supp_rates[i])) 1195 num_11b++; 1196 else 1197 num_others++; 1198 } 1199 1200 for (i = 0; elems->ext_supp_rates && i < elems->ext_supp_rates_len; 1201 i++) { 1202 if (is_11b(elems->ext_supp_rates[i])) 1203 num_11b++; 1204 else 1205 num_others++; 1206 } 1207 1208 return num_11b > 0 && num_others == 0; 1209 } 1210 1211 1212 const char * fc2str(u16 fc) 1213 { 1214 u16 stype = WLAN_FC_GET_STYPE(fc); 1215 #define C2S(x) case x: return #x; 1216 1217 switch (WLAN_FC_GET_TYPE(fc)) { 1218 case WLAN_FC_TYPE_MGMT: 1219 switch (stype) { 1220 C2S(WLAN_FC_STYPE_ASSOC_REQ) 1221 C2S(WLAN_FC_STYPE_ASSOC_RESP) 1222 C2S(WLAN_FC_STYPE_REASSOC_REQ) 1223 C2S(WLAN_FC_STYPE_REASSOC_RESP) 1224 C2S(WLAN_FC_STYPE_PROBE_REQ) 1225 C2S(WLAN_FC_STYPE_PROBE_RESP) 1226 C2S(WLAN_FC_STYPE_BEACON) 1227 C2S(WLAN_FC_STYPE_ATIM) 1228 C2S(WLAN_FC_STYPE_DISASSOC) 1229 C2S(WLAN_FC_STYPE_AUTH) 1230 C2S(WLAN_FC_STYPE_DEAUTH) 1231 C2S(WLAN_FC_STYPE_ACTION) 1232 } 1233 break; 1234 case WLAN_FC_TYPE_CTRL: 1235 switch (stype) { 1236 C2S(WLAN_FC_STYPE_PSPOLL) 1237 C2S(WLAN_FC_STYPE_RTS) 1238 C2S(WLAN_FC_STYPE_CTS) 1239 C2S(WLAN_FC_STYPE_ACK) 1240 C2S(WLAN_FC_STYPE_CFEND) 1241 C2S(WLAN_FC_STYPE_CFENDACK) 1242 } 1243 break; 1244 case WLAN_FC_TYPE_DATA: 1245 switch (stype) { 1246 C2S(WLAN_FC_STYPE_DATA) 1247 C2S(WLAN_FC_STYPE_DATA_CFACK) 1248 C2S(WLAN_FC_STYPE_DATA_CFPOLL) 1249 C2S(WLAN_FC_STYPE_DATA_CFACKPOLL) 1250 C2S(WLAN_FC_STYPE_NULLFUNC) 1251 C2S(WLAN_FC_STYPE_CFACK) 1252 C2S(WLAN_FC_STYPE_CFPOLL) 1253 C2S(WLAN_FC_STYPE_CFACKPOLL) 1254 C2S(WLAN_FC_STYPE_QOS_DATA) 1255 C2S(WLAN_FC_STYPE_QOS_DATA_CFACK) 1256 C2S(WLAN_FC_STYPE_QOS_DATA_CFPOLL) 1257 C2S(WLAN_FC_STYPE_QOS_DATA_CFACKPOLL) 1258 C2S(WLAN_FC_STYPE_QOS_NULL) 1259 C2S(WLAN_FC_STYPE_QOS_CFPOLL) 1260 C2S(WLAN_FC_STYPE_QOS_CFACKPOLL) 1261 } 1262 break; 1263 } 1264 return "WLAN_FC_TYPE_UNKNOWN"; 1265 #undef C2S 1266 } 1267 1268 1269 int mb_ies_info_by_ies(struct mb_ies_info *info, const u8 *ies_buf, 1270 size_t ies_len) 1271 { 1272 os_memset(info, 0, sizeof(*info)); 1273 1274 while (ies_buf && ies_len >= 2 && 1275 info->nof_ies < MAX_NOF_MB_IES_SUPPORTED) { 1276 size_t len = 2 + ies_buf[1]; 1277 1278 if (len > ies_len) { 1279 wpa_hexdump(MSG_DEBUG, "Truncated IEs", 1280 ies_buf, ies_len); 1281 return -1; 1282 } 1283 1284 if (ies_buf[0] == WLAN_EID_MULTI_BAND) { 1285 wpa_printf(MSG_DEBUG, "MB IE of %zu bytes found", len); 1286 info->ies[info->nof_ies].ie = ies_buf + 2; 1287 info->ies[info->nof_ies].ie_len = ies_buf[1]; 1288 info->nof_ies++; 1289 } 1290 1291 ies_len -= len; 1292 ies_buf += len; 1293 } 1294 1295 return 0; 1296 } 1297 1298 1299 struct wpabuf * mb_ies_by_info(struct mb_ies_info *info) 1300 { 1301 struct wpabuf *mb_ies = NULL; 1302 1303 WPA_ASSERT(info != NULL); 1304 1305 if (info->nof_ies) { 1306 u8 i; 1307 size_t mb_ies_size = 0; 1308 1309 for (i = 0; i < info->nof_ies; i++) 1310 mb_ies_size += 2 + info->ies[i].ie_len; 1311 1312 mb_ies = wpabuf_alloc(mb_ies_size); 1313 if (mb_ies) { 1314 for (i = 0; i < info->nof_ies; i++) { 1315 wpabuf_put_u8(mb_ies, WLAN_EID_MULTI_BAND); 1316 wpabuf_put_u8(mb_ies, info->ies[i].ie_len); 1317 wpabuf_put_data(mb_ies, 1318 info->ies[i].ie, 1319 info->ies[i].ie_len); 1320 } 1321 } 1322 } 1323 1324 return mb_ies; 1325 } 1326 1327 1328 const struct oper_class_map global_op_class[] = { 1329 { HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20, P2P_SUPP }, 1330 { HOSTAPD_MODE_IEEE80211G, 82, 14, 14, 1, BW20, NO_P2P_SUPP }, 1331 1332 /* Do not enable HT40 on 2.4 GHz for P2P use for now */ 1333 { HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS, NO_P2P_SUPP }, 1334 { HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS, NO_P2P_SUPP }, 1335 1336 { HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20, P2P_SUPP }, 1337 { HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS, P2P_SUPP }, 1338 { HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS, P2P_SUPP }, 1339 { HOSTAPD_MODE_IEEE80211A, 118, 52, 64, 4, BW20, NO_P2P_SUPP }, 1340 { HOSTAPD_MODE_IEEE80211A, 119, 52, 60, 8, BW40PLUS, NO_P2P_SUPP }, 1341 { HOSTAPD_MODE_IEEE80211A, 120, 56, 64, 8, BW40MINUS, NO_P2P_SUPP }, 1342 { HOSTAPD_MODE_IEEE80211A, 121, 100, 140, 4, BW20, NO_P2P_SUPP }, 1343 { HOSTAPD_MODE_IEEE80211A, 122, 100, 132, 8, BW40PLUS, NO_P2P_SUPP }, 1344 { HOSTAPD_MODE_IEEE80211A, 123, 104, 136, 8, BW40MINUS, NO_P2P_SUPP }, 1345 { HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20, P2P_SUPP }, 1346 { HOSTAPD_MODE_IEEE80211A, 125, 149, 169, 4, BW20, P2P_SUPP }, 1347 { HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8, BW40PLUS, P2P_SUPP }, 1348 { HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8, BW40MINUS, P2P_SUPP }, 1349 1350 /* 1351 * IEEE P802.11ac/D7.0 Table E-4 actually talks about channel center 1352 * frequency index 42, 58, 106, 122, 138, 155 with channel spacing of 1353 * 80 MHz, but currently use the following definition for simplicity 1354 * (these center frequencies are not actual channels, which makes 1355 * wpas_p2p_allow_channel() fail). wpas_p2p_verify_80mhz() should take 1356 * care of removing invalid channels. 1357 */ 1358 { HOSTAPD_MODE_IEEE80211A, 128, 36, 161, 4, BW80, P2P_SUPP }, 1359 { HOSTAPD_MODE_IEEE80211A, 129, 50, 114, 16, BW160, P2P_SUPP }, 1360 { HOSTAPD_MODE_IEEE80211A, 130, 36, 161, 4, BW80P80, P2P_SUPP }, 1361 { HOSTAPD_MODE_IEEE80211AD, 180, 1, 4, 1, BW2160, P2P_SUPP }, 1362 { -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP } 1363 }; 1364 1365 1366 static enum phy_type ieee80211_phy_type_by_freq(int freq) 1367 { 1368 enum hostapd_hw_mode hw_mode; 1369 u8 channel; 1370 1371 hw_mode = ieee80211_freq_to_chan(freq, &channel); 1372 1373 switch (hw_mode) { 1374 case HOSTAPD_MODE_IEEE80211A: 1375 return PHY_TYPE_OFDM; 1376 case HOSTAPD_MODE_IEEE80211B: 1377 return PHY_TYPE_HRDSSS; 1378 case HOSTAPD_MODE_IEEE80211G: 1379 return PHY_TYPE_ERP; 1380 case HOSTAPD_MODE_IEEE80211AD: 1381 return PHY_TYPE_DMG; 1382 default: 1383 return PHY_TYPE_UNSPECIFIED; 1384 }; 1385 } 1386 1387 1388 /* ieee80211_get_phy_type - Derive the phy type by freq and bandwidth */ 1389 enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht) 1390 { 1391 if (vht) 1392 return PHY_TYPE_VHT; 1393 if (ht) 1394 return PHY_TYPE_HT; 1395 1396 return ieee80211_phy_type_by_freq(freq); 1397 } 1398 1399 1400 size_t global_op_class_size = ARRAY_SIZE(global_op_class); 1401 1402 1403 /** 1404 * get_ie - Fetch a specified information element from IEs buffer 1405 * @ies: Information elements buffer 1406 * @len: Information elements buffer length 1407 * @eid: Information element identifier (WLAN_EID_*) 1408 * Returns: Pointer to the information element (id field) or %NULL if not found 1409 * 1410 * This function returns the first matching information element in the IEs 1411 * buffer or %NULL in case the element is not found. 1412 */ 1413 const u8 * get_ie(const u8 *ies, size_t len, u8 eid) 1414 { 1415 const u8 *end; 1416 1417 if (!ies) 1418 return NULL; 1419 1420 end = ies + len; 1421 1422 while (end - ies > 1) { 1423 if (2 + ies[1] > end - ies) 1424 break; 1425 1426 if (ies[0] == eid) 1427 return ies; 1428 1429 ies += 2 + ies[1]; 1430 } 1431 1432 return NULL; 1433 } 1434 1435 1436 /** 1437 * get_ie_ext - Fetch a specified extended information element from IEs buffer 1438 * @ies: Information elements buffer 1439 * @len: Information elements buffer length 1440 * @ext: Information element extension identifier (WLAN_EID_EXT_*) 1441 * Returns: Pointer to the information element (id field) or %NULL if not found 1442 * 1443 * This function returns the first matching information element in the IEs 1444 * buffer or %NULL in case the element is not found. 1445 */ 1446 const u8 * get_ie_ext(const u8 *ies, size_t len, u8 ext) 1447 { 1448 const u8 *end; 1449 1450 if (!ies) 1451 return NULL; 1452 1453 end = ies + len; 1454 1455 while (end - ies > 1) { 1456 if (2 + ies[1] > end - ies) 1457 break; 1458 1459 if (ies[0] == WLAN_EID_EXTENSION && ies[1] >= 1 && 1460 ies[2] == ext) 1461 return ies; 1462 1463 ies += 2 + ies[1]; 1464 } 1465 1466 return NULL; 1467 } 1468 1469 1470 size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len) 1471 { 1472 /* 1473 * MBO IE requires 6 bytes without the attributes: EID (1), length (1), 1474 * OUI (3), OUI type (1). 1475 */ 1476 if (len < 6 + attr_len) { 1477 wpa_printf(MSG_DEBUG, 1478 "MBO: Not enough room in buffer for MBO IE: buf len = %zu, attr_len = %zu", 1479 len, attr_len); 1480 return 0; 1481 } 1482 1483 *buf++ = WLAN_EID_VENDOR_SPECIFIC; 1484 *buf++ = attr_len + 4; 1485 WPA_PUT_BE24(buf, OUI_WFA); 1486 buf += 3; 1487 *buf++ = MBO_OUI_TYPE; 1488 os_memcpy(buf, attr, attr_len); 1489 1490 return 6 + attr_len; 1491 } 1492 1493 1494 static const struct country_op_class us_op_class[] = { 1495 { 1, 115 }, 1496 { 2, 118 }, 1497 { 3, 124 }, 1498 { 4, 121 }, 1499 { 5, 125 }, 1500 { 12, 81 }, 1501 { 22, 116 }, 1502 { 23, 119 }, 1503 { 24, 122 }, 1504 { 25, 126 }, 1505 { 26, 126 }, 1506 { 27, 117 }, 1507 { 28, 120 }, 1508 { 29, 123 }, 1509 { 30, 127 }, 1510 { 31, 127 }, 1511 { 32, 83 }, 1512 { 33, 84 }, 1513 { 34, 180 }, 1514 }; 1515 1516 static const struct country_op_class eu_op_class[] = { 1517 { 1, 115 }, 1518 { 2, 118 }, 1519 { 3, 121 }, 1520 { 4, 81 }, 1521 { 5, 116 }, 1522 { 6, 119 }, 1523 { 7, 122 }, 1524 { 8, 117 }, 1525 { 9, 120 }, 1526 { 10, 123 }, 1527 { 11, 83 }, 1528 { 12, 84 }, 1529 { 17, 125 }, 1530 { 18, 180 }, 1531 }; 1532 1533 static const struct country_op_class jp_op_class[] = { 1534 { 1, 115 }, 1535 { 30, 81 }, 1536 { 31, 82 }, 1537 { 32, 118 }, 1538 { 33, 118 }, 1539 { 34, 121 }, 1540 { 35, 121 }, 1541 { 36, 116 }, 1542 { 37, 119 }, 1543 { 38, 119 }, 1544 { 39, 122 }, 1545 { 40, 122 }, 1546 { 41, 117 }, 1547 { 42, 120 }, 1548 { 43, 120 }, 1549 { 44, 123 }, 1550 { 45, 123 }, 1551 { 56, 83 }, 1552 { 57, 84 }, 1553 { 58, 121 }, 1554 { 59, 180 }, 1555 }; 1556 1557 static const struct country_op_class cn_op_class[] = { 1558 { 1, 115 }, 1559 { 2, 118 }, 1560 { 3, 125 }, 1561 { 4, 116 }, 1562 { 5, 119 }, 1563 { 6, 126 }, 1564 { 7, 81 }, 1565 { 8, 83 }, 1566 { 9, 84 }, 1567 }; 1568 1569 static u8 1570 global_op_class_from_country_array(u8 op_class, size_t array_size, 1571 const struct country_op_class *country_array) 1572 { 1573 size_t i; 1574 1575 for (i = 0; i < array_size; i++) { 1576 if (country_array[i].country_op_class == op_class) 1577 return country_array[i].global_op_class; 1578 } 1579 1580 return 0; 1581 } 1582 1583 1584 u8 country_to_global_op_class(const char *country, u8 op_class) 1585 { 1586 const struct country_op_class *country_array; 1587 size_t size; 1588 u8 g_op_class; 1589 1590 if (country_match(us_op_class_cc, country)) { 1591 country_array = us_op_class; 1592 size = ARRAY_SIZE(us_op_class); 1593 } else if (country_match(eu_op_class_cc, country)) { 1594 country_array = eu_op_class; 1595 size = ARRAY_SIZE(eu_op_class); 1596 } else if (country_match(jp_op_class_cc, country)) { 1597 country_array = jp_op_class; 1598 size = ARRAY_SIZE(jp_op_class); 1599 } else if (country_match(cn_op_class_cc, country)) { 1600 country_array = cn_op_class; 1601 size = ARRAY_SIZE(cn_op_class); 1602 } else { 1603 /* 1604 * Countries that do not match any of the above countries use 1605 * global operating classes 1606 */ 1607 return op_class; 1608 } 1609 1610 g_op_class = global_op_class_from_country_array(op_class, size, 1611 country_array); 1612 1613 /* 1614 * If the given operating class did not match any of the country's 1615 * operating classes, assume that global operating class is used. 1616 */ 1617 return g_op_class ? g_op_class : op_class; 1618 } 1619 1620 1621 const struct oper_class_map * get_oper_class(const char *country, u8 op_class) 1622 { 1623 const struct oper_class_map *op; 1624 1625 if (country) 1626 op_class = country_to_global_op_class(country, op_class); 1627 1628 op = &global_op_class[0]; 1629 while (op->op_class && op->op_class != op_class) 1630 op++; 1631 1632 if (!op->op_class) 1633 return NULL; 1634 1635 return op; 1636 } 1637 1638 1639 int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep, 1640 size_t nei_rep_len) 1641 { 1642 u8 *nei_pos = nei_rep; 1643 const char *end; 1644 1645 /* 1646 * BSS Transition Candidate List Entries - Neighbor Report elements 1647 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>, 1648 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>] 1649 */ 1650 while (pos) { 1651 u8 *nei_start; 1652 long int val; 1653 char *endptr, *tmp; 1654 1655 pos = os_strstr(pos, " neighbor="); 1656 if (!pos) 1657 break; 1658 if (nei_pos + 15 > nei_rep + nei_rep_len) { 1659 wpa_printf(MSG_DEBUG, 1660 "Not enough room for additional neighbor"); 1661 return -1; 1662 } 1663 pos += 10; 1664 1665 nei_start = nei_pos; 1666 *nei_pos++ = WLAN_EID_NEIGHBOR_REPORT; 1667 nei_pos++; /* length to be filled in */ 1668 1669 if (hwaddr_aton(pos, nei_pos)) { 1670 wpa_printf(MSG_DEBUG, "Invalid BSSID"); 1671 return -1; 1672 } 1673 nei_pos += ETH_ALEN; 1674 pos += 17; 1675 if (*pos != ',') { 1676 wpa_printf(MSG_DEBUG, "Missing BSSID Information"); 1677 return -1; 1678 } 1679 pos++; 1680 1681 val = strtol(pos, &endptr, 0); 1682 WPA_PUT_LE32(nei_pos, val); 1683 nei_pos += 4; 1684 if (*endptr != ',') { 1685 wpa_printf(MSG_DEBUG, "Missing Operating Class"); 1686 return -1; 1687 } 1688 pos = endptr + 1; 1689 1690 *nei_pos++ = atoi(pos); /* Operating Class */ 1691 pos = os_strchr(pos, ','); 1692 if (pos == NULL) { 1693 wpa_printf(MSG_DEBUG, "Missing Channel Number"); 1694 return -1; 1695 } 1696 pos++; 1697 1698 *nei_pos++ = atoi(pos); /* Channel Number */ 1699 pos = os_strchr(pos, ','); 1700 if (pos == NULL) { 1701 wpa_printf(MSG_DEBUG, "Missing PHY Type"); 1702 return -1; 1703 } 1704 pos++; 1705 1706 *nei_pos++ = atoi(pos); /* PHY Type */ 1707 end = os_strchr(pos, ' '); 1708 tmp = os_strchr(pos, ','); 1709 if (tmp && (!end || tmp < end)) { 1710 /* Optional Subelements (hexdump) */ 1711 size_t len; 1712 1713 pos = tmp + 1; 1714 end = os_strchr(pos, ' '); 1715 if (end) 1716 len = end - pos; 1717 else 1718 len = os_strlen(pos); 1719 if (nei_pos + len / 2 > nei_rep + nei_rep_len) { 1720 wpa_printf(MSG_DEBUG, 1721 "Not enough room for neighbor subelements"); 1722 return -1; 1723 } 1724 if (len & 0x01 || 1725 hexstr2bin(pos, nei_pos, len / 2) < 0) { 1726 wpa_printf(MSG_DEBUG, 1727 "Invalid neighbor subelement info"); 1728 return -1; 1729 } 1730 nei_pos += len / 2; 1731 pos = end; 1732 } 1733 1734 nei_start[1] = nei_pos - nei_start - 2; 1735 } 1736 1737 return nei_pos - nei_rep; 1738 } 1739