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 "qca-vendor.h" 15#include "ieee802_11_defs.h" 16#include "ieee802_11_common.h" 17 18 19static 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/** 183 * ieee802_11_parse_elems - Parse information elements in management frames 184 * @start: Pointer to the start of IEs 185 * @len: Length of IE buffer in octets 186 * @elems: Data structure for parsed elements 187 * @show_errors: Whether to show parsing errors in debug log 188 * Returns: Parsing result 189 */ 190ParseRes ieee802_11_parse_elems(const u8 *start, size_t len, 191 struct ieee802_11_elems *elems, 192 int show_errors) 193{ 194 size_t left = len; 195 const u8 *pos = start; 196 int unknown = 0; 197 198 os_memset(elems, 0, sizeof(*elems)); 199 200 while (left >= 2) { 201 u8 id, elen; 202 203 id = *pos++; 204 elen = *pos++; 205 left -= 2; 206 207 if (elen > left) { 208 if (show_errors) { 209 wpa_printf(MSG_DEBUG, "IEEE 802.11 element " 210 "parse failed (id=%d elen=%d " 211 "left=%lu)", 212 id, elen, (unsigned long) left); 213 wpa_hexdump(MSG_MSGDUMP, "IEs", start, len); 214 } 215 return ParseFailed; 216 } 217 218 switch (id) { 219 case WLAN_EID_SSID: 220 if (elen > SSID_MAX_LEN) { 221 wpa_printf(MSG_DEBUG, 222 "Ignored too long SSID element (elen=%u)", 223 elen); 224 break; 225 } 226 elems->ssid = pos; 227 elems->ssid_len = elen; 228 break; 229 case WLAN_EID_SUPP_RATES: 230 elems->supp_rates = pos; 231 elems->supp_rates_len = elen; 232 break; 233 case WLAN_EID_DS_PARAMS: 234 if (elen < 1) 235 break; 236 elems->ds_params = pos; 237 break; 238 case WLAN_EID_CF_PARAMS: 239 case WLAN_EID_TIM: 240 break; 241 case WLAN_EID_CHALLENGE: 242 elems->challenge = pos; 243 elems->challenge_len = elen; 244 break; 245 case WLAN_EID_ERP_INFO: 246 if (elen < 1) 247 break; 248 elems->erp_info = pos; 249 break; 250 case WLAN_EID_EXT_SUPP_RATES: 251 elems->ext_supp_rates = pos; 252 elems->ext_supp_rates_len = elen; 253 break; 254 case WLAN_EID_VENDOR_SPECIFIC: 255 if (ieee802_11_parse_vendor_specific(pos, elen, 256 elems, 257 show_errors)) 258 unknown++; 259 break; 260 case WLAN_EID_RSN: 261 elems->rsn_ie = pos; 262 elems->rsn_ie_len = elen; 263 break; 264 case WLAN_EID_PWR_CAPABILITY: 265 break; 266 case WLAN_EID_SUPPORTED_CHANNELS: 267 elems->supp_channels = pos; 268 elems->supp_channels_len = elen; 269 break; 270 case WLAN_EID_MOBILITY_DOMAIN: 271 if (elen < sizeof(struct rsn_mdie)) 272 break; 273 elems->mdie = pos; 274 elems->mdie_len = elen; 275 break; 276 case WLAN_EID_FAST_BSS_TRANSITION: 277 if (elen < sizeof(struct rsn_ftie)) 278 break; 279 elems->ftie = pos; 280 elems->ftie_len = elen; 281 break; 282 case WLAN_EID_TIMEOUT_INTERVAL: 283 if (elen != 5) 284 break; 285 elems->timeout_int = pos; 286 break; 287 case WLAN_EID_HT_CAP: 288 if (elen < sizeof(struct ieee80211_ht_capabilities)) 289 break; 290 elems->ht_capabilities = pos; 291 break; 292 case WLAN_EID_HT_OPERATION: 293 if (elen < sizeof(struct ieee80211_ht_operation)) 294 break; 295 elems->ht_operation = pos; 296 break; 297 case WLAN_EID_MESH_CONFIG: 298 elems->mesh_config = pos; 299 elems->mesh_config_len = elen; 300 break; 301 case WLAN_EID_MESH_ID: 302 elems->mesh_id = pos; 303 elems->mesh_id_len = elen; 304 break; 305 case WLAN_EID_PEER_MGMT: 306 elems->peer_mgmt = pos; 307 elems->peer_mgmt_len = elen; 308 break; 309 case WLAN_EID_VHT_CAP: 310 if (elen < sizeof(struct ieee80211_vht_capabilities)) 311 break; 312 elems->vht_capabilities = pos; 313 break; 314 case WLAN_EID_VHT_OPERATION: 315 if (elen < sizeof(struct ieee80211_vht_operation)) 316 break; 317 elems->vht_operation = pos; 318 break; 319 case WLAN_EID_VHT_OPERATING_MODE_NOTIFICATION: 320 if (elen != 1) 321 break; 322 elems->vht_opmode_notif = pos; 323 break; 324 case WLAN_EID_LINK_ID: 325 if (elen < 18) 326 break; 327 elems->link_id = pos; 328 break; 329 case WLAN_EID_INTERWORKING: 330 elems->interworking = pos; 331 elems->interworking_len = elen; 332 break; 333 case WLAN_EID_QOS_MAP_SET: 334 if (elen < 16) 335 break; 336 elems->qos_map_set = pos; 337 elems->qos_map_set_len = elen; 338 break; 339 case WLAN_EID_EXT_CAPAB: 340 elems->ext_capab = pos; 341 elems->ext_capab_len = elen; 342 break; 343 case WLAN_EID_BSS_MAX_IDLE_PERIOD: 344 if (elen < 3) 345 break; 346 elems->bss_max_idle_period = pos; 347 break; 348 case WLAN_EID_SSID_LIST: 349 elems->ssid_list = pos; 350 elems->ssid_list_len = elen; 351 break; 352 case WLAN_EID_AMPE: 353 elems->ampe = pos; 354 elems->ampe_len = elen; 355 break; 356 case WLAN_EID_MIC: 357 elems->mic = pos; 358 elems->mic_len = elen; 359 /* after mic everything is encrypted, so stop. */ 360 left = elen; 361 break; 362 case WLAN_EID_MULTI_BAND: 363 if (elems->mb_ies.nof_ies >= MAX_NOF_MB_IES_SUPPORTED) { 364 wpa_printf(MSG_MSGDUMP, 365 "IEEE 802.11 element parse ignored MB IE (id=%d elen=%d)", 366 id, elen); 367 break; 368 } 369 370 elems->mb_ies.ies[elems->mb_ies.nof_ies].ie = pos; 371 elems->mb_ies.ies[elems->mb_ies.nof_ies].ie_len = elen; 372 elems->mb_ies.nof_ies++; 373 break; 374 case WLAN_EID_SUPPORTED_OPERATING_CLASSES: 375 elems->supp_op_classes = pos; 376 elems->supp_op_classes_len = elen; 377 break; 378 default: 379 unknown++; 380 if (!show_errors) 381 break; 382 wpa_printf(MSG_MSGDUMP, "IEEE 802.11 element parse " 383 "ignored unknown element (id=%d elen=%d)", 384 id, elen); 385 break; 386 } 387 388 left -= elen; 389 pos += elen; 390 } 391 392 if (left) 393 return ParseFailed; 394 395 return unknown ? ParseUnknown : ParseOK; 396} 397 398 399int ieee802_11_ie_count(const u8 *ies, size_t ies_len) 400{ 401 int count = 0; 402 const u8 *pos, *end; 403 404 if (ies == NULL) 405 return 0; 406 407 pos = ies; 408 end = ies + ies_len; 409 410 while (end - pos >= 2) { 411 if (2 + pos[1] > end - pos) 412 break; 413 count++; 414 pos += 2 + pos[1]; 415 } 416 417 return count; 418} 419 420 421struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len, 422 u32 oui_type) 423{ 424 struct wpabuf *buf; 425 const u8 *end, *pos, *ie; 426 427 pos = ies; 428 end = ies + ies_len; 429 ie = NULL; 430 431 while (end - pos > 1) { 432 if (2 + pos[1] > end - pos) 433 return NULL; 434 if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && 435 WPA_GET_BE32(&pos[2]) == oui_type) { 436 ie = pos; 437 break; 438 } 439 pos += 2 + pos[1]; 440 } 441 442 if (ie == NULL) 443 return NULL; /* No specified vendor IE found */ 444 445 buf = wpabuf_alloc(ies_len); 446 if (buf == NULL) 447 return NULL; 448 449 /* 450 * There may be multiple vendor IEs in the message, so need to 451 * concatenate their data fields. 452 */ 453 while (end - pos > 1) { 454 if (2 + pos[1] > end - pos) 455 break; 456 if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && 457 WPA_GET_BE32(&pos[2]) == oui_type) 458 wpabuf_put_data(buf, pos + 6, pos[1] - 4); 459 pos += 2 + pos[1]; 460 } 461 462 return buf; 463} 464 465 466const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len) 467{ 468 u16 fc, type, stype; 469 470 /* 471 * PS-Poll frames are 16 bytes. All other frames are 472 * 24 bytes or longer. 473 */ 474 if (len < 16) 475 return NULL; 476 477 fc = le_to_host16(hdr->frame_control); 478 type = WLAN_FC_GET_TYPE(fc); 479 stype = WLAN_FC_GET_STYPE(fc); 480 481 switch (type) { 482 case WLAN_FC_TYPE_DATA: 483 if (len < 24) 484 return NULL; 485 switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) { 486 case WLAN_FC_FROMDS | WLAN_FC_TODS: 487 case WLAN_FC_TODS: 488 return hdr->addr1; 489 case WLAN_FC_FROMDS: 490 return hdr->addr2; 491 default: 492 return NULL; 493 } 494 case WLAN_FC_TYPE_CTRL: 495 if (stype != WLAN_FC_STYPE_PSPOLL) 496 return NULL; 497 return hdr->addr1; 498 case WLAN_FC_TYPE_MGMT: 499 return hdr->addr3; 500 default: 501 return NULL; 502 } 503} 504 505 506int hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[], 507 const char *name, const char *val) 508{ 509 int num, v; 510 const char *pos; 511 struct hostapd_wmm_ac_params *ac; 512 513 /* skip 'wme_ac_' or 'wmm_ac_' prefix */ 514 pos = name + 7; 515 if (os_strncmp(pos, "be_", 3) == 0) { 516 num = 0; 517 pos += 3; 518 } else if (os_strncmp(pos, "bk_", 3) == 0) { 519 num = 1; 520 pos += 3; 521 } else if (os_strncmp(pos, "vi_", 3) == 0) { 522 num = 2; 523 pos += 3; 524 } else if (os_strncmp(pos, "vo_", 3) == 0) { 525 num = 3; 526 pos += 3; 527 } else { 528 wpa_printf(MSG_ERROR, "Unknown WMM name '%s'", pos); 529 return -1; 530 } 531 532 ac = &wmm_ac_params[num]; 533 534 if (os_strcmp(pos, "aifs") == 0) { 535 v = atoi(val); 536 if (v < 1 || v > 255) { 537 wpa_printf(MSG_ERROR, "Invalid AIFS value %d", v); 538 return -1; 539 } 540 ac->aifs = v; 541 } else if (os_strcmp(pos, "cwmin") == 0) { 542 v = atoi(val); 543 if (v < 0 || v > 15) { 544 wpa_printf(MSG_ERROR, "Invalid cwMin value %d", v); 545 return -1; 546 } 547 ac->cwmin = v; 548 } else if (os_strcmp(pos, "cwmax") == 0) { 549 v = atoi(val); 550 if (v < 0 || v > 15) { 551 wpa_printf(MSG_ERROR, "Invalid cwMax value %d", v); 552 return -1; 553 } 554 ac->cwmax = v; 555 } else if (os_strcmp(pos, "txop_limit") == 0) { 556 v = atoi(val); 557 if (v < 0 || v > 0xffff) { 558 wpa_printf(MSG_ERROR, "Invalid txop value %d", v); 559 return -1; 560 } 561 ac->txop_limit = v; 562 } else if (os_strcmp(pos, "acm") == 0) { 563 v = atoi(val); 564 if (v < 0 || v > 1) { 565 wpa_printf(MSG_ERROR, "Invalid acm value %d", v); 566 return -1; 567 } 568 ac->admission_control_mandatory = v; 569 } else { 570 wpa_printf(MSG_ERROR, "Unknown wmm_ac_ field '%s'", pos); 571 return -1; 572 } 573 574 return 0; 575} 576 577 578enum hostapd_hw_mode ieee80211_freq_to_chan(int freq, u8 *channel) 579{ 580 u8 op_class; 581 582 return ieee80211_freq_to_channel_ext(freq, 0, VHT_CHANWIDTH_USE_HT, 583 &op_class, channel); 584} 585 586 587/** 588 * ieee80211_freq_to_channel_ext - Convert frequency into channel info 589 * for HT40 and VHT. DFS channels are not covered. 590 * @freq: Frequency (MHz) to convert 591 * @sec_channel: 0 = non-HT40, 1 = sec. channel above, -1 = sec. channel below 592 * @vht: VHT channel width (VHT_CHANWIDTH_*) 593 * @op_class: Buffer for returning operating class 594 * @channel: Buffer for returning channel number 595 * Returns: hw_mode on success, NUM_HOSTAPD_MODES on failure 596 */ 597enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq, 598 int sec_channel, int vht, 599 u8 *op_class, u8 *channel) 600{ 601 u8 vht_opclass; 602 603 /* TODO: more operating classes */ 604 605 if (sec_channel > 1 || sec_channel < -1) 606 return NUM_HOSTAPD_MODES; 607 608 if (freq >= 2412 && freq <= 2472) { 609 if ((freq - 2407) % 5) 610 return NUM_HOSTAPD_MODES; 611 612 if (vht) 613 return NUM_HOSTAPD_MODES; 614 615 /* 2.407 GHz, channels 1..13 */ 616 if (sec_channel == 1) 617 *op_class = 83; 618 else if (sec_channel == -1) 619 *op_class = 84; 620 else 621 *op_class = 81; 622 623 *channel = (freq - 2407) / 5; 624 625 return HOSTAPD_MODE_IEEE80211G; 626 } 627 628 if (freq == 2484) { 629 if (sec_channel || vht) 630 return NUM_HOSTAPD_MODES; 631 632 *op_class = 82; /* channel 14 */ 633 *channel = 14; 634 635 return HOSTAPD_MODE_IEEE80211B; 636 } 637 638 if (freq >= 4900 && freq < 5000) { 639 if ((freq - 4000) % 5) 640 return NUM_HOSTAPD_MODES; 641 *channel = (freq - 4000) / 5; 642 *op_class = 0; /* TODO */ 643 return HOSTAPD_MODE_IEEE80211A; 644 } 645 646 switch (vht) { 647 case VHT_CHANWIDTH_80MHZ: 648 vht_opclass = 128; 649 break; 650 case VHT_CHANWIDTH_160MHZ: 651 vht_opclass = 129; 652 break; 653 case VHT_CHANWIDTH_80P80MHZ: 654 vht_opclass = 130; 655 break; 656 default: 657 vht_opclass = 0; 658 break; 659 } 660 661 /* 5 GHz, channels 36..48 */ 662 if (freq >= 5180 && freq <= 5240) { 663 if ((freq - 5000) % 5) 664 return NUM_HOSTAPD_MODES; 665 666 if (vht_opclass) 667 *op_class = vht_opclass; 668 else if (sec_channel == 1) 669 *op_class = 116; 670 else if (sec_channel == -1) 671 *op_class = 117; 672 else 673 *op_class = 115; 674 675 *channel = (freq - 5000) / 5; 676 677 return HOSTAPD_MODE_IEEE80211A; 678 } 679 680 /* 5 GHz, channels 149..169 */ 681 if (freq >= 5745 && freq <= 5845) { 682 if ((freq - 5000) % 5) 683 return NUM_HOSTAPD_MODES; 684 685 if (vht_opclass) 686 *op_class = vht_opclass; 687 else if (sec_channel == 1) 688 *op_class = 126; 689 else if (sec_channel == -1) 690 *op_class = 127; 691 else if (freq <= 5805) 692 *op_class = 124; 693 else 694 *op_class = 125; 695 696 *channel = (freq - 5000) / 5; 697 698 return HOSTAPD_MODE_IEEE80211A; 699 } 700 701 /* 5 GHz, channels 100..140 */ 702 if (freq >= 5000 && freq <= 5700) { 703 if ((freq - 5000) % 5) 704 return NUM_HOSTAPD_MODES; 705 706 if (vht_opclass) 707 *op_class = vht_opclass; 708 else if (sec_channel == 1) 709 *op_class = 122; 710 else if (sec_channel == -1) 711 *op_class = 123; 712 else 713 *op_class = 121; 714 715 *channel = (freq - 5000) / 5; 716 717 return HOSTAPD_MODE_IEEE80211A; 718 } 719 720 if (freq >= 5000 && freq < 5900) { 721 if ((freq - 5000) % 5) 722 return NUM_HOSTAPD_MODES; 723 *channel = (freq - 5000) / 5; 724 *op_class = 0; /* TODO */ 725 return HOSTAPD_MODE_IEEE80211A; 726 } 727 728 /* 56.16 GHz, channel 1..4 */ 729 if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 4) { 730 if (sec_channel || vht) 731 return NUM_HOSTAPD_MODES; 732 733 *channel = (freq - 56160) / 2160; 734 *op_class = 180; 735 736 return HOSTAPD_MODE_IEEE80211AD; 737 } 738 739 return NUM_HOSTAPD_MODES; 740} 741 742 743static const char *const us_op_class_cc[] = { 744 "US", "CA", NULL 745}; 746 747static const char *const eu_op_class_cc[] = { 748 "AL", "AM", "AT", "AZ", "BA", "BE", "BG", "BY", "CH", "CY", "CZ", "DE", 749 "DK", "EE", "EL", "ES", "FI", "FR", "GE", "HR", "HU", "IE", "IS", "IT", 750 "LI", "LT", "LU", "LV", "MD", "ME", "MK", "MT", "NL", "NO", "PL", "PT", 751 "RO", "RS", "RU", "SE", "SI", "SK", "TR", "UA", "UK", NULL 752}; 753 754static const char *const jp_op_class_cc[] = { 755 "JP", NULL 756}; 757 758static const char *const cn_op_class_cc[] = { 759 "CN", NULL 760}; 761 762 763static int country_match(const char *const cc[], const char *const country) 764{ 765 int i; 766 767 if (country == NULL) 768 return 0; 769 for (i = 0; cc[i]; i++) { 770 if (cc[i][0] == country[0] && cc[i][1] == country[1]) 771 return 1; 772 } 773 774 return 0; 775} 776 777 778static int ieee80211_chan_to_freq_us(u8 op_class, u8 chan) 779{ 780 switch (op_class) { 781 case 12: /* channels 1..11 */ 782 case 32: /* channels 1..7; 40 MHz */ 783 case 33: /* channels 5..11; 40 MHz */ 784 if (chan < 1 || chan > 11) 785 return -1; 786 return 2407 + 5 * chan; 787 case 1: /* channels 36,40,44,48 */ 788 case 2: /* channels 52,56,60,64; dfs */ 789 case 22: /* channels 36,44; 40 MHz */ 790 case 23: /* channels 52,60; 40 MHz */ 791 case 27: /* channels 40,48; 40 MHz */ 792 case 28: /* channels 56,64; 40 MHz */ 793 if (chan < 36 || chan > 64) 794 return -1; 795 return 5000 + 5 * chan; 796 case 4: /* channels 100-144 */ 797 case 24: /* channels 100-140; 40 MHz */ 798 if (chan < 100 || chan > 144) 799 return -1; 800 return 5000 + 5 * chan; 801 case 3: /* channels 149,153,157,161 */ 802 case 25: /* channels 149,157; 40 MHz */ 803 case 26: /* channels 149,157; 40 MHz */ 804 case 30: /* channels 153,161; 40 MHz */ 805 case 31: /* channels 153,161; 40 MHz */ 806 if (chan < 149 || chan > 161) 807 return -1; 808 return 5000 + 5 * chan; 809 case 5: /* channels 149,153,157,161,165 */ 810 if (chan < 149 || chan > 165) 811 return -1; 812 return 5000 + 5 * chan; 813 case 34: /* 60 GHz band, channels 1..3 */ 814 if (chan < 1 || chan > 3) 815 return -1; 816 return 56160 + 2160 * chan; 817 } 818 return -1; 819} 820 821 822static int ieee80211_chan_to_freq_eu(u8 op_class, u8 chan) 823{ 824 switch (op_class) { 825 case 4: /* channels 1..13 */ 826 case 11: /* channels 1..9; 40 MHz */ 827 case 12: /* channels 5..13; 40 MHz */ 828 if (chan < 1 || chan > 13) 829 return -1; 830 return 2407 + 5 * chan; 831 case 1: /* channels 36,40,44,48 */ 832 case 2: /* channels 52,56,60,64; dfs */ 833 case 5: /* channels 36,44; 40 MHz */ 834 case 6: /* channels 52,60; 40 MHz */ 835 case 8: /* channels 40,48; 40 MHz */ 836 case 9: /* channels 56,64; 40 MHz */ 837 if (chan < 36 || chan > 64) 838 return -1; 839 return 5000 + 5 * chan; 840 case 3: /* channels 100-140 */ 841 case 7: /* channels 100-132; 40 MHz */ 842 case 10: /* channels 104-136; 40 MHz */ 843 case 16: /* channels 100-140 */ 844 if (chan < 100 || chan > 140) 845 return -1; 846 return 5000 + 5 * chan; 847 case 17: /* channels 149,153,157,161,165,169 */ 848 if (chan < 149 || chan > 169) 849 return -1; 850 return 5000 + 5 * chan; 851 case 18: /* 60 GHz band, channels 1..4 */ 852 if (chan < 1 || chan > 4) 853 return -1; 854 return 56160 + 2160 * chan; 855 } 856 return -1; 857} 858 859 860static int ieee80211_chan_to_freq_jp(u8 op_class, u8 chan) 861{ 862 switch (op_class) { 863 case 30: /* channels 1..13 */ 864 case 56: /* channels 1..9; 40 MHz */ 865 case 57: /* channels 5..13; 40 MHz */ 866 if (chan < 1 || chan > 13) 867 return -1; 868 return 2407 + 5 * chan; 869 case 31: /* channel 14 */ 870 if (chan != 14) 871 return -1; 872 return 2414 + 5 * chan; 873 case 1: /* channels 34,38,42,46(old) or 36,40,44,48 */ 874 case 32: /* channels 52,56,60,64 */ 875 case 33: /* channels 52,56,60,64 */ 876 case 36: /* channels 36,44; 40 MHz */ 877 case 37: /* channels 52,60; 40 MHz */ 878 case 38: /* channels 52,60; 40 MHz */ 879 case 41: /* channels 40,48; 40 MHz */ 880 case 42: /* channels 56,64; 40 MHz */ 881 case 43: /* channels 56,64; 40 MHz */ 882 if (chan < 34 || chan > 64) 883 return -1; 884 return 5000 + 5 * chan; 885 case 34: /* channels 100-140 */ 886 case 35: /* channels 100-140 */ 887 case 39: /* channels 100-132; 40 MHz */ 888 case 40: /* channels 100-132; 40 MHz */ 889 case 44: /* channels 104-136; 40 MHz */ 890 case 45: /* channels 104-136; 40 MHz */ 891 case 58: /* channels 100-140 */ 892 if (chan < 100 || chan > 140) 893 return -1; 894 return 5000 + 5 * chan; 895 case 59: /* 60 GHz band, channels 1..4 */ 896 if (chan < 1 || chan > 3) 897 return -1; 898 return 56160 + 2160 * chan; 899 } 900 return -1; 901} 902 903 904static int ieee80211_chan_to_freq_cn(u8 op_class, u8 chan) 905{ 906 switch (op_class) { 907 case 7: /* channels 1..13 */ 908 case 8: /* channels 1..9; 40 MHz */ 909 case 9: /* channels 5..13; 40 MHz */ 910 if (chan < 1 || chan > 13) 911 return -1; 912 return 2407 + 5 * chan; 913 case 1: /* channels 36,40,44,48 */ 914 case 2: /* channels 52,56,60,64; dfs */ 915 case 4: /* channels 36,44; 40 MHz */ 916 case 5: /* channels 52,60; 40 MHz */ 917 if (chan < 36 || chan > 64) 918 return -1; 919 return 5000 + 5 * chan; 920 case 3: /* channels 149,153,157,161,165 */ 921 case 6: /* channels 149,157; 40 MHz */ 922 if (chan < 149 || chan > 165) 923 return -1; 924 return 5000 + 5 * chan; 925 } 926 return -1; 927} 928 929 930static int ieee80211_chan_to_freq_global(u8 op_class, u8 chan) 931{ 932 /* Table E-4 in IEEE Std 802.11-2012 - Global operating classes */ 933 switch (op_class) { 934 case 81: 935 /* channels 1..13 */ 936 if (chan < 1 || chan > 13) 937 return -1; 938 return 2407 + 5 * chan; 939 case 82: 940 /* channel 14 */ 941 if (chan != 14) 942 return -1; 943 return 2414 + 5 * chan; 944 case 83: /* channels 1..9; 40 MHz */ 945 case 84: /* channels 5..13; 40 MHz */ 946 if (chan < 1 || chan > 13) 947 return -1; 948 return 2407 + 5 * chan; 949 case 115: /* channels 36,40,44,48; indoor only */ 950 case 116: /* channels 36,44; 40 MHz; indoor only */ 951 case 117: /* channels 40,48; 40 MHz; indoor only */ 952 case 118: /* channels 52,56,60,64; dfs */ 953 case 119: /* channels 52,60; 40 MHz; dfs */ 954 case 120: /* channels 56,64; 40 MHz; dfs */ 955 if (chan < 36 || chan > 64) 956 return -1; 957 return 5000 + 5 * chan; 958 case 121: /* channels 100-140 */ 959 case 122: /* channels 100-142; 40 MHz */ 960 case 123: /* channels 104-136; 40 MHz */ 961 if (chan < 100 || chan > 140) 962 return -1; 963 return 5000 + 5 * chan; 964 case 124: /* channels 149,153,157,161 */ 965 case 126: /* channels 149,157; 40 MHz */ 966 case 127: /* channels 153,161; 40 MHz */ 967 if (chan < 149 || chan > 161) 968 return -1; 969 return 5000 + 5 * chan; 970 case 125: /* channels 149,153,157,161,165,169 */ 971 if (chan < 149 || chan > 169) 972 return -1; 973 return 5000 + 5 * chan; 974 case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */ 975 case 130: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */ 976 if (chan < 36 || chan > 161) 977 return -1; 978 return 5000 + 5 * chan; 979 case 129: /* center freqs 50, 114; 160 MHz */ 980 if (chan < 50 || chan > 114) 981 return -1; 982 return 5000 + 5 * chan; 983 case 180: /* 60 GHz band, channels 1..4 */ 984 if (chan < 1 || chan > 4) 985 return -1; 986 return 56160 + 2160 * chan; 987 } 988 return -1; 989} 990 991/** 992 * ieee80211_chan_to_freq - Convert channel info to frequency 993 * @country: Country code, if known; otherwise, global operating class is used 994 * @op_class: Operating class 995 * @chan: Channel number 996 * Returns: Frequency in MHz or -1 if the specified channel is unknown 997 */ 998int ieee80211_chan_to_freq(const char *country, u8 op_class, u8 chan) 999{ 1000 int freq; 1001 1002 if (country_match(us_op_class_cc, country)) { 1003 freq = ieee80211_chan_to_freq_us(op_class, chan); 1004 if (freq > 0) 1005 return freq; 1006 } 1007 1008 if (country_match(eu_op_class_cc, country)) { 1009 freq = ieee80211_chan_to_freq_eu(op_class, chan); 1010 if (freq > 0) 1011 return freq; 1012 } 1013 1014 if (country_match(jp_op_class_cc, country)) { 1015 freq = ieee80211_chan_to_freq_jp(op_class, chan); 1016 if (freq > 0) 1017 return freq; 1018 } 1019 1020 if (country_match(cn_op_class_cc, country)) { 1021 freq = ieee80211_chan_to_freq_cn(op_class, chan); 1022 if (freq > 0) 1023 return freq; 1024 } 1025 1026 return ieee80211_chan_to_freq_global(op_class, chan); 1027} 1028 1029 1030int ieee80211_is_dfs(int freq) 1031{ 1032 /* TODO: this could be more accurate to better cover all domains */ 1033 return (freq >= 5260 && freq <= 5320) || (freq >= 5500 && freq <= 5700); 1034} 1035 1036 1037static int is_11b(u8 rate) 1038{ 1039 return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16; 1040} 1041 1042 1043int supp_rates_11b_only(struct ieee802_11_elems *elems) 1044{ 1045 int num_11b = 0, num_others = 0; 1046 int i; 1047 1048 if (elems->supp_rates == NULL && elems->ext_supp_rates == NULL) 1049 return 0; 1050 1051 for (i = 0; elems->supp_rates && i < elems->supp_rates_len; i++) { 1052 if (is_11b(elems->supp_rates[i])) 1053 num_11b++; 1054 else 1055 num_others++; 1056 } 1057 1058 for (i = 0; elems->ext_supp_rates && i < elems->ext_supp_rates_len; 1059 i++) { 1060 if (is_11b(elems->ext_supp_rates[i])) 1061 num_11b++; 1062 else 1063 num_others++; 1064 } 1065 1066 return num_11b > 0 && num_others == 0; 1067} 1068 1069 1070const char * fc2str(u16 fc) 1071{ 1072 u16 stype = WLAN_FC_GET_STYPE(fc); 1073#define C2S(x) case x: return #x; 1074 1075 switch (WLAN_FC_GET_TYPE(fc)) { 1076 case WLAN_FC_TYPE_MGMT: 1077 switch (stype) { 1078 C2S(WLAN_FC_STYPE_ASSOC_REQ) 1079 C2S(WLAN_FC_STYPE_ASSOC_RESP) 1080 C2S(WLAN_FC_STYPE_REASSOC_REQ) 1081 C2S(WLAN_FC_STYPE_REASSOC_RESP) 1082 C2S(WLAN_FC_STYPE_PROBE_REQ) 1083 C2S(WLAN_FC_STYPE_PROBE_RESP) 1084 C2S(WLAN_FC_STYPE_BEACON) 1085 C2S(WLAN_FC_STYPE_ATIM) 1086 C2S(WLAN_FC_STYPE_DISASSOC) 1087 C2S(WLAN_FC_STYPE_AUTH) 1088 C2S(WLAN_FC_STYPE_DEAUTH) 1089 C2S(WLAN_FC_STYPE_ACTION) 1090 } 1091 break; 1092 case WLAN_FC_TYPE_CTRL: 1093 switch (stype) { 1094 C2S(WLAN_FC_STYPE_PSPOLL) 1095 C2S(WLAN_FC_STYPE_RTS) 1096 C2S(WLAN_FC_STYPE_CTS) 1097 C2S(WLAN_FC_STYPE_ACK) 1098 C2S(WLAN_FC_STYPE_CFEND) 1099 C2S(WLAN_FC_STYPE_CFENDACK) 1100 } 1101 break; 1102 case WLAN_FC_TYPE_DATA: 1103 switch (stype) { 1104 C2S(WLAN_FC_STYPE_DATA) 1105 C2S(WLAN_FC_STYPE_DATA_CFACK) 1106 C2S(WLAN_FC_STYPE_DATA_CFPOLL) 1107 C2S(WLAN_FC_STYPE_DATA_CFACKPOLL) 1108 C2S(WLAN_FC_STYPE_NULLFUNC) 1109 C2S(WLAN_FC_STYPE_CFACK) 1110 C2S(WLAN_FC_STYPE_CFPOLL) 1111 C2S(WLAN_FC_STYPE_CFACKPOLL) 1112 C2S(WLAN_FC_STYPE_QOS_DATA) 1113 C2S(WLAN_FC_STYPE_QOS_DATA_CFACK) 1114 C2S(WLAN_FC_STYPE_QOS_DATA_CFPOLL) 1115 C2S(WLAN_FC_STYPE_QOS_DATA_CFACKPOLL) 1116 C2S(WLAN_FC_STYPE_QOS_NULL) 1117 C2S(WLAN_FC_STYPE_QOS_CFPOLL) 1118 C2S(WLAN_FC_STYPE_QOS_CFACKPOLL) 1119 } 1120 break; 1121 } 1122 return "WLAN_FC_TYPE_UNKNOWN"; 1123#undef C2S 1124} 1125 1126 1127int mb_ies_info_by_ies(struct mb_ies_info *info, const u8 *ies_buf, 1128 size_t ies_len) 1129{ 1130 os_memset(info, 0, sizeof(*info)); 1131 1132 while (ies_buf && ies_len >= 2 && 1133 info->nof_ies < MAX_NOF_MB_IES_SUPPORTED) { 1134 size_t len = 2 + ies_buf[1]; 1135 1136 if (len > ies_len) { 1137 wpa_hexdump(MSG_DEBUG, "Truncated IEs", 1138 ies_buf, ies_len); 1139 return -1; 1140 } 1141 1142 if (ies_buf[0] == WLAN_EID_MULTI_BAND) { 1143 wpa_printf(MSG_DEBUG, "MB IE of %zu bytes found", len); 1144 info->ies[info->nof_ies].ie = ies_buf + 2; 1145 info->ies[info->nof_ies].ie_len = ies_buf[1]; 1146 info->nof_ies++; 1147 } 1148 1149 ies_len -= len; 1150 ies_buf += len; 1151 } 1152 1153 return 0; 1154} 1155 1156 1157struct wpabuf * mb_ies_by_info(struct mb_ies_info *info) 1158{ 1159 struct wpabuf *mb_ies = NULL; 1160 1161 WPA_ASSERT(info != NULL); 1162 1163 if (info->nof_ies) { 1164 u8 i; 1165 size_t mb_ies_size = 0; 1166 1167 for (i = 0; i < info->nof_ies; i++) 1168 mb_ies_size += 2 + info->ies[i].ie_len; 1169 1170 mb_ies = wpabuf_alloc(mb_ies_size); 1171 if (mb_ies) { 1172 for (i = 0; i < info->nof_ies; i++) { 1173 wpabuf_put_u8(mb_ies, WLAN_EID_MULTI_BAND); 1174 wpabuf_put_u8(mb_ies, info->ies[i].ie_len); 1175 wpabuf_put_data(mb_ies, 1176 info->ies[i].ie, 1177 info->ies[i].ie_len); 1178 } 1179 } 1180 } 1181 1182 return mb_ies; 1183} 1184 1185 1186const struct oper_class_map global_op_class[] = { 1187 { HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20, P2P_SUPP }, 1188 { HOSTAPD_MODE_IEEE80211G, 82, 14, 14, 1, BW20, NO_P2P_SUPP }, 1189 1190 /* Do not enable HT40 on 2.4 GHz for P2P use for now */ 1191 { HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS, NO_P2P_SUPP }, 1192 { HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS, NO_P2P_SUPP }, 1193 1194 { HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20, P2P_SUPP }, 1195 { HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS, P2P_SUPP }, 1196 { HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS, P2P_SUPP }, 1197 { HOSTAPD_MODE_IEEE80211A, 118, 52, 64, 4, BW20, NO_P2P_SUPP }, 1198 { HOSTAPD_MODE_IEEE80211A, 119, 52, 60, 8, BW40PLUS, NO_P2P_SUPP }, 1199 { HOSTAPD_MODE_IEEE80211A, 120, 56, 64, 8, BW40MINUS, NO_P2P_SUPP }, 1200 { HOSTAPD_MODE_IEEE80211A, 121, 100, 140, 4, BW20, NO_P2P_SUPP }, 1201 { HOSTAPD_MODE_IEEE80211A, 122, 100, 132, 8, BW40PLUS, NO_P2P_SUPP }, 1202 { HOSTAPD_MODE_IEEE80211A, 123, 104, 136, 8, BW40MINUS, NO_P2P_SUPP }, 1203 { HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20, P2P_SUPP }, 1204 { HOSTAPD_MODE_IEEE80211A, 125, 149, 169, 4, BW20, P2P_SUPP }, 1205 { HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8, BW40PLUS, P2P_SUPP }, 1206 { HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8, BW40MINUS, P2P_SUPP }, 1207 1208 /* 1209 * IEEE P802.11ac/D7.0 Table E-4 actually talks about channel center 1210 * frequency index 42, 58, 106, 122, 138, 155 with channel spacing of 1211 * 80 MHz, but currently use the following definition for simplicity 1212 * (these center frequencies are not actual channels, which makes 1213 * wpas_p2p_allow_channel() fail). wpas_p2p_verify_80mhz() should take 1214 * care of removing invalid channels. 1215 */ 1216 { HOSTAPD_MODE_IEEE80211A, 128, 36, 161, 4, BW80, P2P_SUPP }, 1217 { HOSTAPD_MODE_IEEE80211A, 129, 50, 114, 16, BW160, P2P_SUPP }, 1218 { HOSTAPD_MODE_IEEE80211A, 130, 36, 161, 4, BW80P80, P2P_SUPP }, 1219 { HOSTAPD_MODE_IEEE80211AD, 180, 1, 4, 1, BW2160, P2P_SUPP }, 1220 { -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP } 1221}; 1222 1223 1224static enum phy_type ieee80211_phy_type_by_freq(int freq) 1225{ 1226 enum hostapd_hw_mode hw_mode; 1227 u8 channel; 1228 1229 hw_mode = ieee80211_freq_to_chan(freq, &channel); 1230 1231 switch (hw_mode) { 1232 case HOSTAPD_MODE_IEEE80211A: 1233 return PHY_TYPE_OFDM; 1234 case HOSTAPD_MODE_IEEE80211B: 1235 return PHY_TYPE_HRDSSS; 1236 case HOSTAPD_MODE_IEEE80211G: 1237 return PHY_TYPE_ERP; 1238 case HOSTAPD_MODE_IEEE80211AD: 1239 return PHY_TYPE_DMG; 1240 default: 1241 return PHY_TYPE_UNSPECIFIED; 1242 }; 1243} 1244 1245 1246/* ieee80211_get_phy_type - Derive the phy type by freq and bandwidth */ 1247enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht) 1248{ 1249 if (vht) 1250 return PHY_TYPE_VHT; 1251 if (ht) 1252 return PHY_TYPE_HT; 1253 1254 return ieee80211_phy_type_by_freq(freq); 1255} 1256 1257 1258size_t global_op_class_size = ARRAY_SIZE(global_op_class); 1259 1260 1261/** 1262 * get_ie - Fetch a specified information element from IEs buffer 1263 * @ies: Information elements buffer 1264 * @len: Information elements buffer length 1265 * @eid: Information element identifier (WLAN_EID_*) 1266 * Returns: Pointer to the information element (id field) or %NULL if not found 1267 * 1268 * This function returns the first matching information element in the IEs 1269 * buffer or %NULL in case the element is not found. 1270 */ 1271const u8 * get_ie(const u8 *ies, size_t len, u8 eid) 1272{ 1273 const u8 *end; 1274 1275 if (!ies) 1276 return NULL; 1277 1278 end = ies + len; 1279 1280 while (end - ies > 1) { 1281 if (2 + ies[1] > end - ies) 1282 break; 1283 1284 if (ies[0] == eid) 1285 return ies; 1286 1287 ies += 2 + ies[1]; 1288 } 1289 1290 return NULL; 1291} 1292 1293 1294size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len) 1295{ 1296 /* 1297 * MBO IE requires 6 bytes without the attributes: EID (1), length (1), 1298 * OUI (3), OUI type (1). 1299 */ 1300 if (len < 6 + attr_len) { 1301 wpa_printf(MSG_DEBUG, 1302 "MBO: Not enough room in buffer for MBO IE: buf len = %zu, attr_len = %zu", 1303 len, attr_len); 1304 return 0; 1305 } 1306 1307 *buf++ = WLAN_EID_VENDOR_SPECIFIC; 1308 *buf++ = attr_len + 4; 1309 WPA_PUT_BE24(buf, OUI_WFA); 1310 buf += 3; 1311 *buf++ = MBO_OUI_TYPE; 1312 os_memcpy(buf, attr, attr_len); 1313 1314 return 6 + attr_len; 1315} 1316