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