2 * IEEE 802.11 Common routines
3 * Copyright (c) 2002-2015, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
13 #include "wpa_common.h"
14 #include "drivers/driver.h"
15 #include "qca-vendor.h"
16 #include "ieee802_11_defs.h"
17 #include "ieee802_11_common.h"
20 static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen,
21 struct ieee802_11_elems *elems,
26 /* first 3 bytes in vendor specific information element are the IEEE
27 * OUI of the vendor. The following byte is used a vendor specific
31 wpa_printf(MSG_MSGDUMP, "short vendor specific "
32 "information element ignored (len=%lu)",
33 (unsigned long) elen);
38 oui = WPA_GET_BE24(pos);
41 /* Microsoft/Wi-Fi information elements are further typed and
45 /* Microsoft OUI (00:50:F2) with OUI Type 1:
46 * real WPA information element */
48 elems->wpa_ie_len = elen;
51 /* WMM information element */
53 wpa_printf(MSG_MSGDUMP, "short WMM "
54 "information element ignored "
56 (unsigned long) elen);
60 case WMM_OUI_SUBTYPE_INFORMATION_ELEMENT:
61 case WMM_OUI_SUBTYPE_PARAMETER_ELEMENT:
63 * Share same pointer since only one of these
64 * is used and they start with same data.
65 * Length field can be used to distinguish the
69 elems->wmm_len = elen;
71 case WMM_OUI_SUBTYPE_TSPEC_ELEMENT:
72 elems->wmm_tspec = pos;
73 elems->wmm_tspec_len = elen;
76 wpa_printf(MSG_EXCESSIVE, "unknown WMM "
77 "information element ignored "
78 "(subtype=%d len=%lu)",
79 pos[4], (unsigned long) elen);
84 /* Wi-Fi Protected Setup (WPS) IE */
86 elems->wps_ie_len = elen;
89 wpa_printf(MSG_EXCESSIVE, "Unknown Microsoft "
90 "information element ignored "
92 pos[3], (unsigned long) elen);
100 /* Wi-Fi Alliance - P2P IE */
102 elems->p2p_len = elen;
105 /* Wi-Fi Alliance - WFD IE */
107 elems->wfd_len = elen;
109 case HS20_INDICATION_OUI_TYPE:
112 elems->hs20_len = elen;
114 case HS20_OSEN_OUI_TYPE:
115 /* Hotspot 2.0 OSEN */
117 elems->osen_len = elen;
122 elems->mbo_len = elen;
124 case HS20_ROAMING_CONS_SEL_OUI_TYPE:
125 /* Hotspot 2.0 Roaming Consortium Selection */
126 elems->roaming_cons_sel = pos;
127 elems->roaming_cons_sel_len = elen;
130 wpa_printf(MSG_MSGDUMP, "Unknown WFA "
131 "information element ignored "
133 pos[3], (unsigned long) elen);
140 case VENDOR_HT_CAPAB_OUI_TYPE:
141 elems->vendor_ht_cap = pos;
142 elems->vendor_ht_cap_len = elen;
144 case VENDOR_VHT_TYPE:
146 (pos[4] == VENDOR_VHT_SUBTYPE ||
147 pos[4] == VENDOR_VHT_SUBTYPE2)) {
148 elems->vendor_vht = pos;
149 elems->vendor_vht_len = elen;
154 wpa_printf(MSG_EXCESSIVE, "Unknown Broadcom "
155 "information element ignored "
157 pos[3], (unsigned long) elen);
164 case QCA_VENDOR_ELEM_P2P_PREF_CHAN_LIST:
165 elems->pref_freq_list = pos;
166 elems->pref_freq_list_len = elen;
169 wpa_printf(MSG_EXCESSIVE,
170 "Unknown QCA information element ignored (type=%d len=%lu)",
171 pos[3], (unsigned long) elen);
177 wpa_printf(MSG_EXCESSIVE, "unknown vendor specific "
178 "information element ignored (vendor OUI "
179 "%02x:%02x:%02x len=%lu)",
180 pos[0], pos[1], pos[2], (unsigned long) elen);
188 static int ieee802_11_parse_extension(const u8 *pos, size_t elen,
189 struct ieee802_11_elems *elems,
196 wpa_printf(MSG_MSGDUMP,
197 "short information element (Ext)");
206 case WLAN_EID_EXT_ASSOC_DELAY_INFO:
209 elems->assoc_delay_info = pos;
211 case WLAN_EID_EXT_FILS_REQ_PARAMS:
214 elems->fils_req_params = pos;
215 elems->fils_req_params_len = elen;
217 case WLAN_EID_EXT_FILS_KEY_CONFIRM:
218 elems->fils_key_confirm = pos;
219 elems->fils_key_confirm_len = elen;
221 case WLAN_EID_EXT_FILS_SESSION:
222 if (elen != FILS_SESSION_LEN)
224 elems->fils_session = pos;
226 case WLAN_EID_EXT_FILS_HLP_CONTAINER:
227 if (elen < 2 * ETH_ALEN)
229 elems->fils_hlp = pos;
230 elems->fils_hlp_len = elen;
232 case WLAN_EID_EXT_FILS_IP_ADDR_ASSIGN:
235 elems->fils_ip_addr_assign = pos;
236 elems->fils_ip_addr_assign_len = elen;
238 case WLAN_EID_EXT_KEY_DELIVERY:
239 if (elen < WPA_KEY_RSC_LEN)
241 elems->key_delivery = pos;
242 elems->key_delivery_len = elen;
244 case WLAN_EID_EXT_FILS_WRAPPED_DATA:
245 elems->fils_wrapped_data = pos;
246 elems->fils_wrapped_data_len = elen;
248 case WLAN_EID_EXT_FILS_PUBLIC_KEY:
251 elems->fils_pk = pos;
252 elems->fils_pk_len = elen;
254 case WLAN_EID_EXT_FILS_NONCE:
255 if (elen != FILS_NONCE_LEN)
257 elems->fils_nonce = pos;
259 case WLAN_EID_EXT_OWE_DH_PARAM:
263 elems->owe_dh_len = elen;
265 case WLAN_EID_EXT_PASSWORD_IDENTIFIER:
266 elems->password_id = pos;
267 elems->password_id_len = elen;
271 wpa_printf(MSG_MSGDUMP,
272 "IEEE 802.11 element parsing ignored unknown element extension (ext_id=%u elen=%u)",
273 ext_id, (unsigned int) elen);
283 * ieee802_11_parse_elems - Parse information elements in management frames
284 * @start: Pointer to the start of IEs
285 * @len: Length of IE buffer in octets
286 * @elems: Data structure for parsed elements
287 * @show_errors: Whether to show parsing errors in debug log
288 * Returns: Parsing result
290 ParseRes ieee802_11_parse_elems(const u8 *start, size_t len,
291 struct ieee802_11_elems *elems,
295 const u8 *pos = start;
298 os_memset(elems, 0, sizeof(*elems));
309 wpa_printf(MSG_DEBUG, "IEEE 802.11 element "
310 "parse failed (id=%d elen=%d "
312 id, elen, (unsigned long) left);
313 wpa_hexdump(MSG_MSGDUMP, "IEs", start, len);
320 if (elen > SSID_MAX_LEN) {
321 wpa_printf(MSG_DEBUG,
322 "Ignored too long SSID element (elen=%u)",
327 elems->ssid_len = elen;
329 case WLAN_EID_SUPP_RATES:
330 elems->supp_rates = pos;
331 elems->supp_rates_len = elen;
333 case WLAN_EID_DS_PARAMS:
336 elems->ds_params = pos;
338 case WLAN_EID_CF_PARAMS:
341 case WLAN_EID_CHALLENGE:
342 elems->challenge = pos;
343 elems->challenge_len = elen;
345 case WLAN_EID_ERP_INFO:
348 elems->erp_info = pos;
350 case WLAN_EID_EXT_SUPP_RATES:
351 elems->ext_supp_rates = pos;
352 elems->ext_supp_rates_len = elen;
354 case WLAN_EID_VENDOR_SPECIFIC:
355 if (ieee802_11_parse_vendor_specific(pos, elen,
362 elems->rsn_ie_len = elen;
364 case WLAN_EID_PWR_CAPABILITY:
367 elems->power_capab = pos;
368 elems->power_capab_len = elen;
370 case WLAN_EID_SUPPORTED_CHANNELS:
371 elems->supp_channels = pos;
372 elems->supp_channels_len = elen;
374 case WLAN_EID_MOBILITY_DOMAIN:
375 if (elen < sizeof(struct rsn_mdie))
378 elems->mdie_len = elen;
380 case WLAN_EID_FAST_BSS_TRANSITION:
381 if (elen < sizeof(struct rsn_ftie))
384 elems->ftie_len = elen;
386 case WLAN_EID_TIMEOUT_INTERVAL:
389 elems->timeout_int = pos;
391 case WLAN_EID_HT_CAP:
392 if (elen < sizeof(struct ieee80211_ht_capabilities))
394 elems->ht_capabilities = pos;
396 case WLAN_EID_HT_OPERATION:
397 if (elen < sizeof(struct ieee80211_ht_operation))
399 elems->ht_operation = pos;
401 case WLAN_EID_MESH_CONFIG:
402 elems->mesh_config = pos;
403 elems->mesh_config_len = elen;
405 case WLAN_EID_MESH_ID:
406 elems->mesh_id = pos;
407 elems->mesh_id_len = elen;
409 case WLAN_EID_PEER_MGMT:
410 elems->peer_mgmt = pos;
411 elems->peer_mgmt_len = elen;
413 case WLAN_EID_VHT_CAP:
414 if (elen < sizeof(struct ieee80211_vht_capabilities))
416 elems->vht_capabilities = pos;
418 case WLAN_EID_VHT_OPERATION:
419 if (elen < sizeof(struct ieee80211_vht_operation))
421 elems->vht_operation = pos;
423 case WLAN_EID_VHT_OPERATING_MODE_NOTIFICATION:
426 elems->vht_opmode_notif = pos;
428 case WLAN_EID_LINK_ID:
431 elems->link_id = pos;
433 case WLAN_EID_INTERWORKING:
434 elems->interworking = pos;
435 elems->interworking_len = elen;
437 case WLAN_EID_QOS_MAP_SET:
440 elems->qos_map_set = pos;
441 elems->qos_map_set_len = elen;
443 case WLAN_EID_EXT_CAPAB:
444 elems->ext_capab = pos;
445 elems->ext_capab_len = elen;
447 case WLAN_EID_BSS_MAX_IDLE_PERIOD:
450 elems->bss_max_idle_period = pos;
452 case WLAN_EID_SSID_LIST:
453 elems->ssid_list = pos;
454 elems->ssid_list_len = elen;
458 elems->ampe_len = elen;
462 elems->mic_len = elen;
463 /* after mic everything is encrypted, so stop. */
466 case WLAN_EID_MULTI_BAND:
467 if (elems->mb_ies.nof_ies >= MAX_NOF_MB_IES_SUPPORTED) {
468 wpa_printf(MSG_MSGDUMP,
469 "IEEE 802.11 element parse ignored MB IE (id=%d elen=%d)",
474 elems->mb_ies.ies[elems->mb_ies.nof_ies].ie = pos;
475 elems->mb_ies.ies[elems->mb_ies.nof_ies].ie_len = elen;
476 elems->mb_ies.nof_ies++;
478 case WLAN_EID_SUPPORTED_OPERATING_CLASSES:
479 elems->supp_op_classes = pos;
480 elems->supp_op_classes_len = elen;
482 case WLAN_EID_RRM_ENABLED_CAPABILITIES:
483 elems->rrm_enabled = pos;
484 elems->rrm_enabled_len = elen;
486 case WLAN_EID_CAG_NUMBER:
487 elems->cag_number = pos;
488 elems->cag_number_len = elen;
490 case WLAN_EID_AP_CSN:
495 case WLAN_EID_FILS_INDICATION:
498 elems->fils_indic = pos;
499 elems->fils_indic_len = elen;
505 elems->dils_len = elen;
507 case WLAN_EID_FRAGMENT:
510 case WLAN_EID_EXTENSION:
511 if (ieee802_11_parse_extension(pos, elen, elems,
519 wpa_printf(MSG_MSGDUMP, "IEEE 802.11 element parse "
520 "ignored unknown element (id=%d elen=%d)",
532 return unknown ? ParseUnknown : ParseOK;
536 int ieee802_11_ie_count(const u8 *ies, size_t ies_len)
547 while (end - pos >= 2) {
548 if (2 + pos[1] > end - pos)
558 struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len,
562 const u8 *end, *pos, *ie;
568 while (end - pos > 1) {
569 if (2 + pos[1] > end - pos)
571 if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
572 WPA_GET_BE32(&pos[2]) == oui_type) {
580 return NULL; /* No specified vendor IE found */
582 buf = wpabuf_alloc(ies_len);
587 * There may be multiple vendor IEs in the message, so need to
588 * concatenate their data fields.
590 while (end - pos > 1) {
591 if (2 + pos[1] > end - pos)
593 if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
594 WPA_GET_BE32(&pos[2]) == oui_type)
595 wpabuf_put_data(buf, pos + 6, pos[1] - 4);
603 const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len)
608 * PS-Poll frames are 16 bytes. All other frames are
609 * 24 bytes or longer.
614 fc = le_to_host16(hdr->frame_control);
615 type = WLAN_FC_GET_TYPE(fc);
616 stype = WLAN_FC_GET_STYPE(fc);
619 case WLAN_FC_TYPE_DATA:
622 switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
623 case WLAN_FC_FROMDS | WLAN_FC_TODS:
631 case WLAN_FC_TYPE_CTRL:
632 if (stype != WLAN_FC_STYPE_PSPOLL)
635 case WLAN_FC_TYPE_MGMT:
643 int hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[],
644 const char *name, const char *val)
648 struct hostapd_wmm_ac_params *ac;
650 /* skip 'wme_ac_' or 'wmm_ac_' prefix */
652 if (os_strncmp(pos, "be_", 3) == 0) {
655 } else if (os_strncmp(pos, "bk_", 3) == 0) {
658 } else if (os_strncmp(pos, "vi_", 3) == 0) {
661 } else if (os_strncmp(pos, "vo_", 3) == 0) {
665 wpa_printf(MSG_ERROR, "Unknown WMM name '%s'", pos);
669 ac = &wmm_ac_params[num];
671 if (os_strcmp(pos, "aifs") == 0) {
673 if (v < 1 || v > 255) {
674 wpa_printf(MSG_ERROR, "Invalid AIFS value %d", v);
678 } else if (os_strcmp(pos, "cwmin") == 0) {
680 if (v < 0 || v > 15) {
681 wpa_printf(MSG_ERROR, "Invalid cwMin value %d", v);
685 } else if (os_strcmp(pos, "cwmax") == 0) {
687 if (v < 0 || v > 15) {
688 wpa_printf(MSG_ERROR, "Invalid cwMax value %d", v);
692 } else if (os_strcmp(pos, "txop_limit") == 0) {
694 if (v < 0 || v > 0xffff) {
695 wpa_printf(MSG_ERROR, "Invalid txop value %d", v);
699 } else if (os_strcmp(pos, "acm") == 0) {
701 if (v < 0 || v > 1) {
702 wpa_printf(MSG_ERROR, "Invalid acm value %d", v);
705 ac->admission_control_mandatory = v;
707 wpa_printf(MSG_ERROR, "Unknown wmm_ac_ field '%s'", pos);
715 enum hostapd_hw_mode ieee80211_freq_to_chan(int freq, u8 *channel)
719 return ieee80211_freq_to_channel_ext(freq, 0, VHT_CHANWIDTH_USE_HT,
725 * ieee80211_freq_to_channel_ext - Convert frequency into channel info
726 * for HT40 and VHT. DFS channels are not covered.
727 * @freq: Frequency (MHz) to convert
728 * @sec_channel: 0 = non-HT40, 1 = sec. channel above, -1 = sec. channel below
729 * @vht: VHT channel width (VHT_CHANWIDTH_*)
730 * @op_class: Buffer for returning operating class
731 * @channel: Buffer for returning channel number
732 * Returns: hw_mode on success, NUM_HOSTAPD_MODES on failure
734 enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
735 int sec_channel, int vht,
736 u8 *op_class, u8 *channel)
740 /* TODO: more operating classes */
742 if (sec_channel > 1 || sec_channel < -1)
743 return NUM_HOSTAPD_MODES;
745 if (freq >= 2412 && freq <= 2472) {
746 if ((freq - 2407) % 5)
747 return NUM_HOSTAPD_MODES;
750 return NUM_HOSTAPD_MODES;
752 /* 2.407 GHz, channels 1..13 */
753 if (sec_channel == 1)
755 else if (sec_channel == -1)
760 *channel = (freq - 2407) / 5;
762 return HOSTAPD_MODE_IEEE80211G;
766 if (sec_channel || vht)
767 return NUM_HOSTAPD_MODES;
769 *op_class = 82; /* channel 14 */
772 return HOSTAPD_MODE_IEEE80211B;
775 if (freq >= 4900 && freq < 5000) {
776 if ((freq - 4000) % 5)
777 return NUM_HOSTAPD_MODES;
778 *channel = (freq - 4000) / 5;
779 *op_class = 0; /* TODO */
780 return HOSTAPD_MODE_IEEE80211A;
784 case VHT_CHANWIDTH_80MHZ:
787 case VHT_CHANWIDTH_160MHZ:
790 case VHT_CHANWIDTH_80P80MHZ:
798 /* 5 GHz, channels 36..48 */
799 if (freq >= 5180 && freq <= 5240) {
800 if ((freq - 5000) % 5)
801 return NUM_HOSTAPD_MODES;
804 *op_class = vht_opclass;
805 else if (sec_channel == 1)
807 else if (sec_channel == -1)
812 *channel = (freq - 5000) / 5;
814 return HOSTAPD_MODE_IEEE80211A;
817 /* 5 GHz, channels 52..64 */
818 if (freq >= 5260 && freq <= 5320) {
819 if ((freq - 5000) % 5)
820 return NUM_HOSTAPD_MODES;
823 *op_class = vht_opclass;
824 else if (sec_channel == 1)
826 else if (sec_channel == -1)
831 *channel = (freq - 5000) / 5;
833 return HOSTAPD_MODE_IEEE80211A;
836 /* 5 GHz, channels 149..169 */
837 if (freq >= 5745 && freq <= 5845) {
838 if ((freq - 5000) % 5)
839 return NUM_HOSTAPD_MODES;
842 *op_class = vht_opclass;
843 else if (sec_channel == 1)
845 else if (sec_channel == -1)
847 else if (freq <= 5805)
852 *channel = (freq - 5000) / 5;
854 return HOSTAPD_MODE_IEEE80211A;
857 /* 5 GHz, channels 100..140 */
858 if (freq >= 5000 && freq <= 5700) {
859 if ((freq - 5000) % 5)
860 return NUM_HOSTAPD_MODES;
863 *op_class = vht_opclass;
864 else if (sec_channel == 1)
866 else if (sec_channel == -1)
871 *channel = (freq - 5000) / 5;
873 return HOSTAPD_MODE_IEEE80211A;
876 if (freq >= 5000 && freq < 5900) {
877 if ((freq - 5000) % 5)
878 return NUM_HOSTAPD_MODES;
879 *channel = (freq - 5000) / 5;
880 *op_class = 0; /* TODO */
881 return HOSTAPD_MODE_IEEE80211A;
884 /* 56.16 GHz, channel 1..4 */
885 if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 4) {
886 if (sec_channel || vht)
887 return NUM_HOSTAPD_MODES;
889 *channel = (freq - 56160) / 2160;
892 return HOSTAPD_MODE_IEEE80211AD;
895 return NUM_HOSTAPD_MODES;
899 static const char *const us_op_class_cc[] = {
903 static const char *const eu_op_class_cc[] = {
904 "AL", "AM", "AT", "AZ", "BA", "BE", "BG", "BY", "CH", "CY", "CZ", "DE",
905 "DK", "EE", "EL", "ES", "FI", "FR", "GE", "HR", "HU", "IE", "IS", "IT",
906 "LI", "LT", "LU", "LV", "MD", "ME", "MK", "MT", "NL", "NO", "PL", "PT",
907 "RO", "RS", "RU", "SE", "SI", "SK", "TR", "UA", "UK", NULL
910 static const char *const jp_op_class_cc[] = {
914 static const char *const cn_op_class_cc[] = {
919 static int country_match(const char *const cc[], const char *const country)
925 for (i = 0; cc[i]; i++) {
926 if (cc[i][0] == country[0] && cc[i][1] == country[1])
934 static int ieee80211_chan_to_freq_us(u8 op_class, u8 chan)
937 case 12: /* channels 1..11 */
938 case 32: /* channels 1..7; 40 MHz */
939 case 33: /* channels 5..11; 40 MHz */
940 if (chan < 1 || chan > 11)
942 return 2407 + 5 * chan;
943 case 1: /* channels 36,40,44,48 */
944 case 2: /* channels 52,56,60,64; dfs */
945 case 22: /* channels 36,44; 40 MHz */
946 case 23: /* channels 52,60; 40 MHz */
947 case 27: /* channels 40,48; 40 MHz */
948 case 28: /* channels 56,64; 40 MHz */
949 if (chan < 36 || chan > 64)
951 return 5000 + 5 * chan;
952 case 4: /* channels 100-144 */
953 case 24: /* channels 100-140; 40 MHz */
954 if (chan < 100 || chan > 144)
956 return 5000 + 5 * chan;
957 case 3: /* channels 149,153,157,161 */
958 case 25: /* channels 149,157; 40 MHz */
959 case 26: /* channels 149,157; 40 MHz */
960 case 30: /* channels 153,161; 40 MHz */
961 case 31: /* channels 153,161; 40 MHz */
962 if (chan < 149 || chan > 161)
964 return 5000 + 5 * chan;
965 case 5: /* channels 149,153,157,161,165 */
966 if (chan < 149 || chan > 165)
968 return 5000 + 5 * chan;
969 case 34: /* 60 GHz band, channels 1..3 */
970 if (chan < 1 || chan > 3)
972 return 56160 + 2160 * chan;
978 static int ieee80211_chan_to_freq_eu(u8 op_class, u8 chan)
981 case 4: /* channels 1..13 */
982 case 11: /* channels 1..9; 40 MHz */
983 case 12: /* channels 5..13; 40 MHz */
984 if (chan < 1 || chan > 13)
986 return 2407 + 5 * chan;
987 case 1: /* channels 36,40,44,48 */
988 case 2: /* channels 52,56,60,64; dfs */
989 case 5: /* channels 36,44; 40 MHz */
990 case 6: /* channels 52,60; 40 MHz */
991 case 8: /* channels 40,48; 40 MHz */
992 case 9: /* channels 56,64; 40 MHz */
993 if (chan < 36 || chan > 64)
995 return 5000 + 5 * chan;
996 case 3: /* channels 100-140 */
997 case 7: /* channels 100-132; 40 MHz */
998 case 10: /* channels 104-136; 40 MHz */
999 case 16: /* channels 100-140 */
1000 if (chan < 100 || chan > 140)
1002 return 5000 + 5 * chan;
1003 case 17: /* channels 149,153,157,161,165,169 */
1004 if (chan < 149 || chan > 169)
1006 return 5000 + 5 * chan;
1007 case 18: /* 60 GHz band, channels 1..4 */
1008 if (chan < 1 || chan > 4)
1010 return 56160 + 2160 * chan;
1016 static int ieee80211_chan_to_freq_jp(u8 op_class, u8 chan)
1019 case 30: /* channels 1..13 */
1020 case 56: /* channels 1..9; 40 MHz */
1021 case 57: /* channels 5..13; 40 MHz */
1022 if (chan < 1 || chan > 13)
1024 return 2407 + 5 * chan;
1025 case 31: /* channel 14 */
1028 return 2414 + 5 * chan;
1029 case 1: /* channels 34,38,42,46(old) or 36,40,44,48 */
1030 case 32: /* channels 52,56,60,64 */
1031 case 33: /* channels 52,56,60,64 */
1032 case 36: /* channels 36,44; 40 MHz */
1033 case 37: /* channels 52,60; 40 MHz */
1034 case 38: /* channels 52,60; 40 MHz */
1035 case 41: /* channels 40,48; 40 MHz */
1036 case 42: /* channels 56,64; 40 MHz */
1037 case 43: /* channels 56,64; 40 MHz */
1038 if (chan < 34 || chan > 64)
1040 return 5000 + 5 * chan;
1041 case 34: /* channels 100-140 */
1042 case 35: /* channels 100-140 */
1043 case 39: /* channels 100-132; 40 MHz */
1044 case 40: /* channels 100-132; 40 MHz */
1045 case 44: /* channels 104-136; 40 MHz */
1046 case 45: /* channels 104-136; 40 MHz */
1047 case 58: /* channels 100-140 */
1048 if (chan < 100 || chan > 140)
1050 return 5000 + 5 * chan;
1051 case 59: /* 60 GHz band, channels 1..4 */
1052 if (chan < 1 || chan > 3)
1054 return 56160 + 2160 * chan;
1060 static int ieee80211_chan_to_freq_cn(u8 op_class, u8 chan)
1063 case 7: /* channels 1..13 */
1064 case 8: /* channels 1..9; 40 MHz */
1065 case 9: /* channels 5..13; 40 MHz */
1066 if (chan < 1 || chan > 13)
1068 return 2407 + 5 * chan;
1069 case 1: /* channels 36,40,44,48 */
1070 case 2: /* channels 52,56,60,64; dfs */
1071 case 4: /* channels 36,44; 40 MHz */
1072 case 5: /* channels 52,60; 40 MHz */
1073 if (chan < 36 || chan > 64)
1075 return 5000 + 5 * chan;
1076 case 3: /* channels 149,153,157,161,165 */
1077 case 6: /* channels 149,157; 40 MHz */
1078 if (chan < 149 || chan > 165)
1080 return 5000 + 5 * chan;
1086 static int ieee80211_chan_to_freq_global(u8 op_class, u8 chan)
1088 /* Table E-4 in IEEE Std 802.11-2012 - Global operating classes */
1091 /* channels 1..13 */
1092 if (chan < 1 || chan > 13)
1094 return 2407 + 5 * chan;
1099 return 2414 + 5 * chan;
1100 case 83: /* channels 1..9; 40 MHz */
1101 case 84: /* channels 5..13; 40 MHz */
1102 if (chan < 1 || chan > 13)
1104 return 2407 + 5 * chan;
1105 case 115: /* channels 36,40,44,48; indoor only */
1106 case 116: /* channels 36,44; 40 MHz; indoor only */
1107 case 117: /* channels 40,48; 40 MHz; indoor only */
1108 case 118: /* channels 52,56,60,64; dfs */
1109 case 119: /* channels 52,60; 40 MHz; dfs */
1110 case 120: /* channels 56,64; 40 MHz; dfs */
1111 if (chan < 36 || chan > 64)
1113 return 5000 + 5 * chan;
1114 case 121: /* channels 100-140 */
1115 case 122: /* channels 100-142; 40 MHz */
1116 case 123: /* channels 104-136; 40 MHz */
1117 if (chan < 100 || chan > 140)
1119 return 5000 + 5 * chan;
1120 case 124: /* channels 149,153,157,161 */
1121 case 126: /* channels 149,157; 40 MHz */
1122 case 127: /* channels 153,161; 40 MHz */
1123 if (chan < 149 || chan > 161)
1125 return 5000 + 5 * chan;
1126 case 125: /* channels 149,153,157,161,165,169 */
1127 if (chan < 149 || chan > 169)
1129 return 5000 + 5 * chan;
1130 case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
1131 case 130: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
1132 if (chan < 36 || chan > 161)
1134 return 5000 + 5 * chan;
1135 case 129: /* center freqs 50, 114; 160 MHz */
1136 if (chan < 36 || chan > 128)
1138 return 5000 + 5 * chan;
1139 case 180: /* 60 GHz band, channels 1..4 */
1140 if (chan < 1 || chan > 4)
1142 return 56160 + 2160 * chan;
1148 * ieee80211_chan_to_freq - Convert channel info to frequency
1149 * @country: Country code, if known; otherwise, global operating class is used
1150 * @op_class: Operating class
1151 * @chan: Channel number
1152 * Returns: Frequency in MHz or -1 if the specified channel is unknown
1154 int ieee80211_chan_to_freq(const char *country, u8 op_class, u8 chan)
1158 if (country_match(us_op_class_cc, country)) {
1159 freq = ieee80211_chan_to_freq_us(op_class, chan);
1164 if (country_match(eu_op_class_cc, country)) {
1165 freq = ieee80211_chan_to_freq_eu(op_class, chan);
1170 if (country_match(jp_op_class_cc, country)) {
1171 freq = ieee80211_chan_to_freq_jp(op_class, chan);
1176 if (country_match(cn_op_class_cc, country)) {
1177 freq = ieee80211_chan_to_freq_cn(op_class, chan);
1182 return ieee80211_chan_to_freq_global(op_class, chan);
1186 int ieee80211_is_dfs(int freq, const struct hostapd_hw_modes *modes,
1191 if (!modes || !num_modes)
1192 return (freq >= 5260 && freq <= 5320) ||
1193 (freq >= 5500 && freq <= 5700);
1195 for (i = 0; i < num_modes; i++) {
1196 for (j = 0; j < modes[i].num_channels; j++) {
1197 if (modes[i].channels[j].freq == freq &&
1198 (modes[i].channels[j].flag & HOSTAPD_CHAN_RADAR))
1207 static int is_11b(u8 rate)
1209 return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16;
1213 int supp_rates_11b_only(struct ieee802_11_elems *elems)
1215 int num_11b = 0, num_others = 0;
1218 if (elems->supp_rates == NULL && elems->ext_supp_rates == NULL)
1221 for (i = 0; elems->supp_rates && i < elems->supp_rates_len; i++) {
1222 if (is_11b(elems->supp_rates[i]))
1228 for (i = 0; elems->ext_supp_rates && i < elems->ext_supp_rates_len;
1230 if (is_11b(elems->ext_supp_rates[i]))
1236 return num_11b > 0 && num_others == 0;
1240 const char * fc2str(u16 fc)
1242 u16 stype = WLAN_FC_GET_STYPE(fc);
1243 #define C2S(x) case x: return #x;
1245 switch (WLAN_FC_GET_TYPE(fc)) {
1246 case WLAN_FC_TYPE_MGMT:
1248 C2S(WLAN_FC_STYPE_ASSOC_REQ)
1249 C2S(WLAN_FC_STYPE_ASSOC_RESP)
1250 C2S(WLAN_FC_STYPE_REASSOC_REQ)
1251 C2S(WLAN_FC_STYPE_REASSOC_RESP)
1252 C2S(WLAN_FC_STYPE_PROBE_REQ)
1253 C2S(WLAN_FC_STYPE_PROBE_RESP)
1254 C2S(WLAN_FC_STYPE_BEACON)
1255 C2S(WLAN_FC_STYPE_ATIM)
1256 C2S(WLAN_FC_STYPE_DISASSOC)
1257 C2S(WLAN_FC_STYPE_AUTH)
1258 C2S(WLAN_FC_STYPE_DEAUTH)
1259 C2S(WLAN_FC_STYPE_ACTION)
1262 case WLAN_FC_TYPE_CTRL:
1264 C2S(WLAN_FC_STYPE_PSPOLL)
1265 C2S(WLAN_FC_STYPE_RTS)
1266 C2S(WLAN_FC_STYPE_CTS)
1267 C2S(WLAN_FC_STYPE_ACK)
1268 C2S(WLAN_FC_STYPE_CFEND)
1269 C2S(WLAN_FC_STYPE_CFENDACK)
1272 case WLAN_FC_TYPE_DATA:
1274 C2S(WLAN_FC_STYPE_DATA)
1275 C2S(WLAN_FC_STYPE_DATA_CFACK)
1276 C2S(WLAN_FC_STYPE_DATA_CFPOLL)
1277 C2S(WLAN_FC_STYPE_DATA_CFACKPOLL)
1278 C2S(WLAN_FC_STYPE_NULLFUNC)
1279 C2S(WLAN_FC_STYPE_CFACK)
1280 C2S(WLAN_FC_STYPE_CFPOLL)
1281 C2S(WLAN_FC_STYPE_CFACKPOLL)
1282 C2S(WLAN_FC_STYPE_QOS_DATA)
1283 C2S(WLAN_FC_STYPE_QOS_DATA_CFACK)
1284 C2S(WLAN_FC_STYPE_QOS_DATA_CFPOLL)
1285 C2S(WLAN_FC_STYPE_QOS_DATA_CFACKPOLL)
1286 C2S(WLAN_FC_STYPE_QOS_NULL)
1287 C2S(WLAN_FC_STYPE_QOS_CFPOLL)
1288 C2S(WLAN_FC_STYPE_QOS_CFACKPOLL)
1292 return "WLAN_FC_TYPE_UNKNOWN";
1297 int mb_ies_info_by_ies(struct mb_ies_info *info, const u8 *ies_buf,
1300 os_memset(info, 0, sizeof(*info));
1302 while (ies_buf && ies_len >= 2 &&
1303 info->nof_ies < MAX_NOF_MB_IES_SUPPORTED) {
1304 size_t len = 2 + ies_buf[1];
1306 if (len > ies_len) {
1307 wpa_hexdump(MSG_DEBUG, "Truncated IEs",
1312 if (ies_buf[0] == WLAN_EID_MULTI_BAND) {
1313 wpa_printf(MSG_DEBUG, "MB IE of %zu bytes found", len);
1314 info->ies[info->nof_ies].ie = ies_buf + 2;
1315 info->ies[info->nof_ies].ie_len = ies_buf[1];
1327 struct wpabuf * mb_ies_by_info(struct mb_ies_info *info)
1329 struct wpabuf *mb_ies = NULL;
1331 WPA_ASSERT(info != NULL);
1333 if (info->nof_ies) {
1335 size_t mb_ies_size = 0;
1337 for (i = 0; i < info->nof_ies; i++)
1338 mb_ies_size += 2 + info->ies[i].ie_len;
1340 mb_ies = wpabuf_alloc(mb_ies_size);
1342 for (i = 0; i < info->nof_ies; i++) {
1343 wpabuf_put_u8(mb_ies, WLAN_EID_MULTI_BAND);
1344 wpabuf_put_u8(mb_ies, info->ies[i].ie_len);
1345 wpabuf_put_data(mb_ies,
1347 info->ies[i].ie_len);
1356 const struct oper_class_map global_op_class[] = {
1357 { HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20, P2P_SUPP },
1358 { HOSTAPD_MODE_IEEE80211G, 82, 14, 14, 1, BW20, NO_P2P_SUPP },
1360 /* Do not enable HT40 on 2.4 GHz for P2P use for now */
1361 { HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS, NO_P2P_SUPP },
1362 { HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS, NO_P2P_SUPP },
1364 { HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20, P2P_SUPP },
1365 { HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS, P2P_SUPP },
1366 { HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS, P2P_SUPP },
1367 { HOSTAPD_MODE_IEEE80211A, 118, 52, 64, 4, BW20, NO_P2P_SUPP },
1368 { HOSTAPD_MODE_IEEE80211A, 119, 52, 60, 8, BW40PLUS, NO_P2P_SUPP },
1369 { HOSTAPD_MODE_IEEE80211A, 120, 56, 64, 8, BW40MINUS, NO_P2P_SUPP },
1370 { HOSTAPD_MODE_IEEE80211A, 121, 100, 140, 4, BW20, NO_P2P_SUPP },
1371 { HOSTAPD_MODE_IEEE80211A, 122, 100, 132, 8, BW40PLUS, NO_P2P_SUPP },
1372 { HOSTAPD_MODE_IEEE80211A, 123, 104, 136, 8, BW40MINUS, NO_P2P_SUPP },
1373 { HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20, P2P_SUPP },
1374 { HOSTAPD_MODE_IEEE80211A, 125, 149, 169, 4, BW20, P2P_SUPP },
1375 { HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8, BW40PLUS, P2P_SUPP },
1376 { HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8, BW40MINUS, P2P_SUPP },
1379 * IEEE P802.11ac/D7.0 Table E-4 actually talks about channel center
1380 * frequency index 42, 58, 106, 122, 138, 155 with channel spacing of
1381 * 80 MHz, but currently use the following definition for simplicity
1382 * (these center frequencies are not actual channels, which makes
1383 * wpas_p2p_allow_channel() fail). wpas_p2p_verify_80mhz() should take
1384 * care of removing invalid channels.
1386 { HOSTAPD_MODE_IEEE80211A, 128, 36, 161, 4, BW80, P2P_SUPP },
1387 { HOSTAPD_MODE_IEEE80211A, 129, 50, 114, 16, BW160, P2P_SUPP },
1388 { HOSTAPD_MODE_IEEE80211A, 130, 36, 161, 4, BW80P80, P2P_SUPP },
1389 { HOSTAPD_MODE_IEEE80211AD, 180, 1, 4, 1, BW2160, P2P_SUPP },
1390 { -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP }
1394 static enum phy_type ieee80211_phy_type_by_freq(int freq)
1396 enum hostapd_hw_mode hw_mode;
1399 hw_mode = ieee80211_freq_to_chan(freq, &channel);
1402 case HOSTAPD_MODE_IEEE80211A:
1403 return PHY_TYPE_OFDM;
1404 case HOSTAPD_MODE_IEEE80211B:
1405 return PHY_TYPE_HRDSSS;
1406 case HOSTAPD_MODE_IEEE80211G:
1407 return PHY_TYPE_ERP;
1408 case HOSTAPD_MODE_IEEE80211AD:
1409 return PHY_TYPE_DMG;
1411 return PHY_TYPE_UNSPECIFIED;
1416 /* ieee80211_get_phy_type - Derive the phy type by freq and bandwidth */
1417 enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht)
1420 return PHY_TYPE_VHT;
1424 return ieee80211_phy_type_by_freq(freq);
1428 size_t global_op_class_size = ARRAY_SIZE(global_op_class);
1432 * get_ie - Fetch a specified information element from IEs buffer
1433 * @ies: Information elements buffer
1434 * @len: Information elements buffer length
1435 * @eid: Information element identifier (WLAN_EID_*)
1436 * Returns: Pointer to the information element (id field) or %NULL if not found
1438 * This function returns the first matching information element in the IEs
1439 * buffer or %NULL in case the element is not found.
1441 const u8 * get_ie(const u8 *ies, size_t len, u8 eid)
1450 while (end - ies > 1) {
1451 if (2 + ies[1] > end - ies)
1465 * get_ie_ext - Fetch a specified extended information element from IEs buffer
1466 * @ies: Information elements buffer
1467 * @len: Information elements buffer length
1468 * @ext: Information element extension identifier (WLAN_EID_EXT_*)
1469 * Returns: Pointer to the information element (id field) or %NULL if not found
1471 * This function returns the first matching information element in the IEs
1472 * buffer or %NULL in case the element is not found.
1474 const u8 * get_ie_ext(const u8 *ies, size_t len, u8 ext)
1483 while (end - ies > 1) {
1484 if (2 + ies[1] > end - ies)
1487 if (ies[0] == WLAN_EID_EXTENSION && ies[1] >= 1 &&
1498 size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len)
1501 * MBO IE requires 6 bytes without the attributes: EID (1), length (1),
1502 * OUI (3), OUI type (1).
1504 if (len < 6 + attr_len) {
1505 wpa_printf(MSG_DEBUG,
1506 "MBO: Not enough room in buffer for MBO IE: buf len = %zu, attr_len = %zu",
1511 *buf++ = WLAN_EID_VENDOR_SPECIFIC;
1512 *buf++ = attr_len + 4;
1513 WPA_PUT_BE24(buf, OUI_WFA);
1515 *buf++ = MBO_OUI_TYPE;
1516 os_memcpy(buf, attr, attr_len);
1518 return 6 + attr_len;
1522 static const struct country_op_class us_op_class[] = {
1544 static const struct country_op_class eu_op_class[] = {
1561 static const struct country_op_class jp_op_class[] = {
1585 static const struct country_op_class cn_op_class[] = {
1598 global_op_class_from_country_array(u8 op_class, size_t array_size,
1599 const struct country_op_class *country_array)
1603 for (i = 0; i < array_size; i++) {
1604 if (country_array[i].country_op_class == op_class)
1605 return country_array[i].global_op_class;
1612 u8 country_to_global_op_class(const char *country, u8 op_class)
1614 const struct country_op_class *country_array;
1618 if (country_match(us_op_class_cc, country)) {
1619 country_array = us_op_class;
1620 size = ARRAY_SIZE(us_op_class);
1621 } else if (country_match(eu_op_class_cc, country)) {
1622 country_array = eu_op_class;
1623 size = ARRAY_SIZE(eu_op_class);
1624 } else if (country_match(jp_op_class_cc, country)) {
1625 country_array = jp_op_class;
1626 size = ARRAY_SIZE(jp_op_class);
1627 } else if (country_match(cn_op_class_cc, country)) {
1628 country_array = cn_op_class;
1629 size = ARRAY_SIZE(cn_op_class);
1632 * Countries that do not match any of the above countries use
1633 * global operating classes
1638 g_op_class = global_op_class_from_country_array(op_class, size,
1642 * If the given operating class did not match any of the country's
1643 * operating classes, assume that global operating class is used.
1645 return g_op_class ? g_op_class : op_class;
1649 const struct oper_class_map * get_oper_class(const char *country, u8 op_class)
1651 const struct oper_class_map *op;
1654 op_class = country_to_global_op_class(country, op_class);
1656 op = &global_op_class[0];
1657 while (op->op_class && op->op_class != op_class)
1667 int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
1670 u8 *nei_pos = nei_rep;
1674 * BSS Transition Candidate List Entries - Neighbor Report elements
1675 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
1676 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
1683 pos = os_strstr(pos, " neighbor=");
1686 if (nei_pos + 15 > nei_rep + nei_rep_len) {
1687 wpa_printf(MSG_DEBUG,
1688 "Not enough room for additional neighbor");
1693 nei_start = nei_pos;
1694 *nei_pos++ = WLAN_EID_NEIGHBOR_REPORT;
1695 nei_pos++; /* length to be filled in */
1697 if (hwaddr_aton(pos, nei_pos)) {
1698 wpa_printf(MSG_DEBUG, "Invalid BSSID");
1701 nei_pos += ETH_ALEN;
1704 wpa_printf(MSG_DEBUG, "Missing BSSID Information");
1709 val = strtol(pos, &endptr, 0);
1710 WPA_PUT_LE32(nei_pos, val);
1712 if (*endptr != ',') {
1713 wpa_printf(MSG_DEBUG, "Missing Operating Class");
1718 *nei_pos++ = atoi(pos); /* Operating Class */
1719 pos = os_strchr(pos, ',');
1721 wpa_printf(MSG_DEBUG, "Missing Channel Number");
1726 *nei_pos++ = atoi(pos); /* Channel Number */
1727 pos = os_strchr(pos, ',');
1729 wpa_printf(MSG_DEBUG, "Missing PHY Type");
1734 *nei_pos++ = atoi(pos); /* PHY Type */
1735 end = os_strchr(pos, ' ');
1736 tmp = os_strchr(pos, ',');
1737 if (tmp && (!end || tmp < end)) {
1738 /* Optional Subelements (hexdump) */
1742 end = os_strchr(pos, ' ');
1746 len = os_strlen(pos);
1747 if (nei_pos + len / 2 > nei_rep + nei_rep_len) {
1748 wpa_printf(MSG_DEBUG,
1749 "Not enough room for neighbor subelements");
1753 hexstr2bin(pos, nei_pos, len / 2) < 0) {
1754 wpa_printf(MSG_DEBUG,
1755 "Invalid neighbor subelement info");
1762 nei_start[1] = nei_pos - nei_start - 2;
1765 return nei_pos - nei_rep;