2 * IEEE 802.11 Common routines
3 * Copyright (c) 2002-2019, 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;
129 case MULTI_AP_OUI_TYPE:
130 elems->multi_ap = pos;
131 elems->multi_ap_len = elen;
134 wpa_printf(MSG_MSGDUMP, "Unknown WFA "
135 "information element ignored "
137 pos[3], (unsigned long) elen);
144 case VENDOR_HT_CAPAB_OUI_TYPE:
145 elems->vendor_ht_cap = pos;
146 elems->vendor_ht_cap_len = elen;
148 case VENDOR_VHT_TYPE:
150 (pos[4] == VENDOR_VHT_SUBTYPE ||
151 pos[4] == VENDOR_VHT_SUBTYPE2)) {
152 elems->vendor_vht = pos;
153 elems->vendor_vht_len = elen;
158 wpa_printf(MSG_EXCESSIVE, "Unknown Broadcom "
159 "information element ignored "
161 pos[3], (unsigned long) elen);
168 case QCA_VENDOR_ELEM_P2P_PREF_CHAN_LIST:
169 elems->pref_freq_list = pos;
170 elems->pref_freq_list_len = elen;
173 wpa_printf(MSG_EXCESSIVE,
174 "Unknown QCA information element ignored (type=%d len=%lu)",
175 pos[3], (unsigned long) elen);
181 wpa_printf(MSG_EXCESSIVE, "unknown vendor specific "
182 "information element ignored (vendor OUI "
183 "%02x:%02x:%02x len=%lu)",
184 pos[0], pos[1], pos[2], (unsigned long) elen);
192 static int ieee802_11_parse_extension(const u8 *pos, size_t elen,
193 struct ieee802_11_elems *elems,
200 wpa_printf(MSG_MSGDUMP,
201 "short information element (Ext)");
210 case WLAN_EID_EXT_ASSOC_DELAY_INFO:
213 elems->assoc_delay_info = pos;
215 case WLAN_EID_EXT_FILS_REQ_PARAMS:
218 elems->fils_req_params = pos;
219 elems->fils_req_params_len = elen;
221 case WLAN_EID_EXT_FILS_KEY_CONFIRM:
222 elems->fils_key_confirm = pos;
223 elems->fils_key_confirm_len = elen;
225 case WLAN_EID_EXT_FILS_SESSION:
226 if (elen != FILS_SESSION_LEN)
228 elems->fils_session = pos;
230 case WLAN_EID_EXT_FILS_HLP_CONTAINER:
231 if (elen < 2 * ETH_ALEN)
233 elems->fils_hlp = pos;
234 elems->fils_hlp_len = elen;
236 case WLAN_EID_EXT_FILS_IP_ADDR_ASSIGN:
239 elems->fils_ip_addr_assign = pos;
240 elems->fils_ip_addr_assign_len = elen;
242 case WLAN_EID_EXT_KEY_DELIVERY:
243 if (elen < WPA_KEY_RSC_LEN)
245 elems->key_delivery = pos;
246 elems->key_delivery_len = elen;
248 case WLAN_EID_EXT_FILS_WRAPPED_DATA:
249 elems->fils_wrapped_data = pos;
250 elems->fils_wrapped_data_len = elen;
252 case WLAN_EID_EXT_FILS_PUBLIC_KEY:
255 elems->fils_pk = pos;
256 elems->fils_pk_len = elen;
258 case WLAN_EID_EXT_FILS_NONCE:
259 if (elen != FILS_NONCE_LEN)
261 elems->fils_nonce = pos;
263 case WLAN_EID_EXT_OWE_DH_PARAM:
267 elems->owe_dh_len = elen;
269 case WLAN_EID_EXT_PASSWORD_IDENTIFIER:
270 elems->password_id = pos;
271 elems->password_id_len = elen;
273 case WLAN_EID_EXT_HE_CAPABILITIES:
274 elems->he_capabilities = pos;
275 elems->he_capabilities_len = elen;
277 case WLAN_EID_EXT_OCV_OCI:
279 elems->oci_len = elen;
283 wpa_printf(MSG_MSGDUMP,
284 "IEEE 802.11 element parsing ignored unknown element extension (ext_id=%u elen=%u)",
285 ext_id, (unsigned int) elen);
295 * ieee802_11_parse_elems - Parse information elements in management frames
296 * @start: Pointer to the start of IEs
297 * @len: Length of IE buffer in octets
298 * @elems: Data structure for parsed elements
299 * @show_errors: Whether to show parsing errors in debug log
300 * Returns: Parsing result
302 ParseRes ieee802_11_parse_elems(const u8 *start, size_t len,
303 struct ieee802_11_elems *elems,
306 const struct element *elem;
309 os_memset(elems, 0, sizeof(*elems));
314 for_each_element(elem, start, len) {
315 u8 id = elem->id, elen = elem->datalen;
316 const u8 *pos = elem->data;
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. */
465 case WLAN_EID_MULTI_BAND:
466 if (elems->mb_ies.nof_ies >= MAX_NOF_MB_IES_SUPPORTED) {
467 wpa_printf(MSG_MSGDUMP,
468 "IEEE 802.11 element parse ignored MB IE (id=%d elen=%d)",
473 elems->mb_ies.ies[elems->mb_ies.nof_ies].ie = pos;
474 elems->mb_ies.ies[elems->mb_ies.nof_ies].ie_len = elen;
475 elems->mb_ies.nof_ies++;
477 case WLAN_EID_SUPPORTED_OPERATING_CLASSES:
478 elems->supp_op_classes = pos;
479 elems->supp_op_classes_len = elen;
481 case WLAN_EID_RRM_ENABLED_CAPABILITIES:
482 elems->rrm_enabled = pos;
483 elems->rrm_enabled_len = elen;
485 case WLAN_EID_CAG_NUMBER:
486 elems->cag_number = pos;
487 elems->cag_number_len = elen;
489 case WLAN_EID_AP_CSN:
494 case WLAN_EID_FILS_INDICATION:
497 elems->fils_indic = pos;
498 elems->fils_indic_len = elen;
504 elems->dils_len = elen;
506 case WLAN_EID_FRAGMENT:
509 case WLAN_EID_EXTENSION:
510 if (ieee802_11_parse_extension(pos, elen, elems,
518 wpa_printf(MSG_MSGDUMP, "IEEE 802.11 element parse "
519 "ignored unknown element (id=%d elen=%d)",
525 if (!for_each_element_completed(elem, start, len)) {
527 wpa_printf(MSG_DEBUG,
528 "IEEE 802.11 element parse failed @%d",
529 (int) (start + len - (const u8 *) elem));
530 wpa_hexdump(MSG_MSGDUMP, "IEs", start, len);
536 return unknown ? ParseUnknown : ParseOK;
540 int ieee802_11_ie_count(const u8 *ies, size_t ies_len)
542 const struct element *elem;
548 for_each_element(elem, ies, ies_len)
555 struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len,
559 const struct element *elem, *found = NULL;
561 for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, ies_len) {
562 if (elem->datalen >= 4 &&
563 WPA_GET_BE32(elem->data) == oui_type) {
570 return NULL; /* No specified vendor IE found */
572 buf = wpabuf_alloc(ies_len);
577 * There may be multiple vendor IEs in the message, so need to
578 * concatenate their data fields.
580 for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, ies_len) {
581 if (elem->datalen >= 4 && WPA_GET_BE32(elem->data) == oui_type)
582 wpabuf_put_data(buf, elem->data + 4, elem->datalen - 4);
589 const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len)
594 * PS-Poll frames are 16 bytes. All other frames are
595 * 24 bytes or longer.
600 fc = le_to_host16(hdr->frame_control);
601 type = WLAN_FC_GET_TYPE(fc);
602 stype = WLAN_FC_GET_STYPE(fc);
605 case WLAN_FC_TYPE_DATA:
608 switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
609 case WLAN_FC_FROMDS | WLAN_FC_TODS:
617 case WLAN_FC_TYPE_CTRL:
618 if (stype != WLAN_FC_STYPE_PSPOLL)
621 case WLAN_FC_TYPE_MGMT:
629 int hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[],
630 const char *name, const char *val)
634 struct hostapd_wmm_ac_params *ac;
636 /* skip 'wme_ac_' or 'wmm_ac_' prefix */
638 if (os_strncmp(pos, "be_", 3) == 0) {
641 } else if (os_strncmp(pos, "bk_", 3) == 0) {
644 } else if (os_strncmp(pos, "vi_", 3) == 0) {
647 } else if (os_strncmp(pos, "vo_", 3) == 0) {
651 wpa_printf(MSG_ERROR, "Unknown WMM name '%s'", pos);
655 ac = &wmm_ac_params[num];
657 if (os_strcmp(pos, "aifs") == 0) {
659 if (v < 1 || v > 255) {
660 wpa_printf(MSG_ERROR, "Invalid AIFS value %d", v);
664 } else if (os_strcmp(pos, "cwmin") == 0) {
666 if (v < 0 || v > 15) {
667 wpa_printf(MSG_ERROR, "Invalid cwMin value %d", v);
671 } else if (os_strcmp(pos, "cwmax") == 0) {
673 if (v < 0 || v > 15) {
674 wpa_printf(MSG_ERROR, "Invalid cwMax value %d", v);
678 } else if (os_strcmp(pos, "txop_limit") == 0) {
680 if (v < 0 || v > 0xffff) {
681 wpa_printf(MSG_ERROR, "Invalid txop value %d", v);
685 } else if (os_strcmp(pos, "acm") == 0) {
687 if (v < 0 || v > 1) {
688 wpa_printf(MSG_ERROR, "Invalid acm value %d", v);
691 ac->admission_control_mandatory = v;
693 wpa_printf(MSG_ERROR, "Unknown wmm_ac_ field '%s'", pos);
701 enum hostapd_hw_mode ieee80211_freq_to_chan(int freq, u8 *channel)
705 return ieee80211_freq_to_channel_ext(freq, 0, VHT_CHANWIDTH_USE_HT,
711 * ieee80211_freq_to_channel_ext - Convert frequency into channel info
712 * for HT40 and VHT. DFS channels are not covered.
713 * @freq: Frequency (MHz) to convert
714 * @sec_channel: 0 = non-HT40, 1 = sec. channel above, -1 = sec. channel below
715 * @vht: VHT channel width (VHT_CHANWIDTH_*)
716 * @op_class: Buffer for returning operating class
717 * @channel: Buffer for returning channel number
718 * Returns: hw_mode on success, NUM_HOSTAPD_MODES on failure
720 enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
721 int sec_channel, int vht,
722 u8 *op_class, u8 *channel)
726 /* TODO: more operating classes */
728 if (sec_channel > 1 || sec_channel < -1)
729 return NUM_HOSTAPD_MODES;
731 if (freq >= 2412 && freq <= 2472) {
732 if ((freq - 2407) % 5)
733 return NUM_HOSTAPD_MODES;
736 return NUM_HOSTAPD_MODES;
738 /* 2.407 GHz, channels 1..13 */
739 if (sec_channel == 1)
741 else if (sec_channel == -1)
746 *channel = (freq - 2407) / 5;
748 return HOSTAPD_MODE_IEEE80211G;
752 if (sec_channel || vht)
753 return NUM_HOSTAPD_MODES;
755 *op_class = 82; /* channel 14 */
758 return HOSTAPD_MODE_IEEE80211B;
761 if (freq >= 4900 && freq < 5000) {
762 if ((freq - 4000) % 5)
763 return NUM_HOSTAPD_MODES;
764 *channel = (freq - 4000) / 5;
765 *op_class = 0; /* TODO */
766 return HOSTAPD_MODE_IEEE80211A;
770 case VHT_CHANWIDTH_80MHZ:
773 case VHT_CHANWIDTH_160MHZ:
776 case VHT_CHANWIDTH_80P80MHZ:
784 /* 5 GHz, channels 36..48 */
785 if (freq >= 5180 && freq <= 5240) {
786 if ((freq - 5000) % 5)
787 return NUM_HOSTAPD_MODES;
790 *op_class = vht_opclass;
791 else if (sec_channel == 1)
793 else if (sec_channel == -1)
798 *channel = (freq - 5000) / 5;
800 return HOSTAPD_MODE_IEEE80211A;
803 /* 5 GHz, channels 52..64 */
804 if (freq >= 5260 && freq <= 5320) {
805 if ((freq - 5000) % 5)
806 return NUM_HOSTAPD_MODES;
809 *op_class = vht_opclass;
810 else if (sec_channel == 1)
812 else if (sec_channel == -1)
817 *channel = (freq - 5000) / 5;
819 return HOSTAPD_MODE_IEEE80211A;
822 /* 5 GHz, channels 149..169 */
823 if (freq >= 5745 && freq <= 5845) {
824 if ((freq - 5000) % 5)
825 return NUM_HOSTAPD_MODES;
828 *op_class = vht_opclass;
829 else if (sec_channel == 1)
831 else if (sec_channel == -1)
833 else if (freq <= 5805)
838 *channel = (freq - 5000) / 5;
840 return HOSTAPD_MODE_IEEE80211A;
843 /* 5 GHz, channels 100..140 */
844 if (freq >= 5000 && freq <= 5700) {
845 if ((freq - 5000) % 5)
846 return NUM_HOSTAPD_MODES;
849 *op_class = vht_opclass;
850 else if (sec_channel == 1)
852 else if (sec_channel == -1)
857 *channel = (freq - 5000) / 5;
859 return HOSTAPD_MODE_IEEE80211A;
862 if (freq >= 5000 && freq < 5900) {
863 if ((freq - 5000) % 5)
864 return NUM_HOSTAPD_MODES;
865 *channel = (freq - 5000) / 5;
866 *op_class = 0; /* TODO */
867 return HOSTAPD_MODE_IEEE80211A;
870 /* 56.16 GHz, channel 1..4 */
871 if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 4) {
872 if (sec_channel || vht)
873 return NUM_HOSTAPD_MODES;
875 *channel = (freq - 56160) / 2160;
878 return HOSTAPD_MODE_IEEE80211AD;
881 return NUM_HOSTAPD_MODES;
885 int ieee80211_chaninfo_to_channel(unsigned int freq, enum chan_width chanwidth,
886 int sec_channel, u8 *op_class, u8 *channel)
888 int vht = CHAN_WIDTH_UNKNOWN;
891 case CHAN_WIDTH_UNKNOWN:
892 case CHAN_WIDTH_20_NOHT:
895 vht = VHT_CHANWIDTH_USE_HT;
898 vht = VHT_CHANWIDTH_80MHZ;
900 case CHAN_WIDTH_80P80:
901 vht = VHT_CHANWIDTH_80P80MHZ;
904 vht = VHT_CHANWIDTH_160MHZ;
908 if (ieee80211_freq_to_channel_ext(freq, sec_channel, vht, op_class,
909 channel) == NUM_HOSTAPD_MODES) {
910 wpa_printf(MSG_WARNING,
911 "Cannot determine operating class and channel (freq=%u chanwidth=%d sec_channel=%d)",
912 freq, chanwidth, sec_channel);
920 static const char *const us_op_class_cc[] = {
924 static const char *const eu_op_class_cc[] = {
925 "AL", "AM", "AT", "AZ", "BA", "BE", "BG", "BY", "CH", "CY", "CZ", "DE",
926 "DK", "EE", "EL", "ES", "FI", "FR", "GE", "HR", "HU", "IE", "IS", "IT",
927 "LI", "LT", "LU", "LV", "MD", "ME", "MK", "MT", "NL", "NO", "PL", "PT",
928 "RO", "RS", "RU", "SE", "SI", "SK", "TR", "UA", "UK", NULL
931 static const char *const jp_op_class_cc[] = {
935 static const char *const cn_op_class_cc[] = {
940 static int country_match(const char *const cc[], const char *const country)
946 for (i = 0; cc[i]; i++) {
947 if (cc[i][0] == country[0] && cc[i][1] == country[1])
955 static int ieee80211_chan_to_freq_us(u8 op_class, u8 chan)
958 case 12: /* channels 1..11 */
959 case 32: /* channels 1..7; 40 MHz */
960 case 33: /* channels 5..11; 40 MHz */
961 if (chan < 1 || chan > 11)
963 return 2407 + 5 * chan;
964 case 1: /* channels 36,40,44,48 */
965 case 2: /* channels 52,56,60,64; dfs */
966 case 22: /* channels 36,44; 40 MHz */
967 case 23: /* channels 52,60; 40 MHz */
968 case 27: /* channels 40,48; 40 MHz */
969 case 28: /* channels 56,64; 40 MHz */
970 if (chan < 36 || chan > 64)
972 return 5000 + 5 * chan;
973 case 4: /* channels 100-144 */
974 case 24: /* channels 100-140; 40 MHz */
975 if (chan < 100 || chan > 144)
977 return 5000 + 5 * chan;
978 case 3: /* channels 149,153,157,161 */
979 case 25: /* channels 149,157; 40 MHz */
980 case 26: /* channels 149,157; 40 MHz */
981 case 30: /* channels 153,161; 40 MHz */
982 case 31: /* channels 153,161; 40 MHz */
983 if (chan < 149 || chan > 161)
985 return 5000 + 5 * chan;
986 case 5: /* channels 149,153,157,161,165 */
987 if (chan < 149 || chan > 165)
989 return 5000 + 5 * chan;
990 case 34: /* 60 GHz band, channels 1..3 */
991 if (chan < 1 || chan > 3)
993 return 56160 + 2160 * chan;
999 static int ieee80211_chan_to_freq_eu(u8 op_class, u8 chan)
1002 case 4: /* channels 1..13 */
1003 case 11: /* channels 1..9; 40 MHz */
1004 case 12: /* channels 5..13; 40 MHz */
1005 if (chan < 1 || chan > 13)
1007 return 2407 + 5 * chan;
1008 case 1: /* channels 36,40,44,48 */
1009 case 2: /* channels 52,56,60,64; dfs */
1010 case 5: /* channels 36,44; 40 MHz */
1011 case 6: /* channels 52,60; 40 MHz */
1012 case 8: /* channels 40,48; 40 MHz */
1013 case 9: /* channels 56,64; 40 MHz */
1014 if (chan < 36 || chan > 64)
1016 return 5000 + 5 * chan;
1017 case 3: /* channels 100-140 */
1018 case 7: /* channels 100-132; 40 MHz */
1019 case 10: /* channels 104-136; 40 MHz */
1020 case 16: /* channels 100-140 */
1021 if (chan < 100 || chan > 140)
1023 return 5000 + 5 * chan;
1024 case 17: /* channels 149,153,157,161,165,169 */
1025 if (chan < 149 || chan > 169)
1027 return 5000 + 5 * chan;
1028 case 18: /* 60 GHz band, channels 1..4 */
1029 if (chan < 1 || chan > 4)
1031 return 56160 + 2160 * chan;
1037 static int ieee80211_chan_to_freq_jp(u8 op_class, u8 chan)
1040 case 30: /* channels 1..13 */
1041 case 56: /* channels 1..9; 40 MHz */
1042 case 57: /* channels 5..13; 40 MHz */
1043 if (chan < 1 || chan > 13)
1045 return 2407 + 5 * chan;
1046 case 31: /* channel 14 */
1049 return 2414 + 5 * chan;
1050 case 1: /* channels 34,38,42,46(old) or 36,40,44,48 */
1051 case 32: /* channels 52,56,60,64 */
1052 case 33: /* channels 52,56,60,64 */
1053 case 36: /* channels 36,44; 40 MHz */
1054 case 37: /* channels 52,60; 40 MHz */
1055 case 38: /* channels 52,60; 40 MHz */
1056 case 41: /* channels 40,48; 40 MHz */
1057 case 42: /* channels 56,64; 40 MHz */
1058 case 43: /* channels 56,64; 40 MHz */
1059 if (chan < 34 || chan > 64)
1061 return 5000 + 5 * chan;
1062 case 34: /* channels 100-140 */
1063 case 35: /* channels 100-140 */
1064 case 39: /* channels 100-132; 40 MHz */
1065 case 40: /* channels 100-132; 40 MHz */
1066 case 44: /* channels 104-136; 40 MHz */
1067 case 45: /* channels 104-136; 40 MHz */
1068 case 58: /* channels 100-140 */
1069 if (chan < 100 || chan > 140)
1071 return 5000 + 5 * chan;
1072 case 59: /* 60 GHz band, channels 1..4 */
1073 if (chan < 1 || chan > 3)
1075 return 56160 + 2160 * chan;
1081 static int ieee80211_chan_to_freq_cn(u8 op_class, u8 chan)
1084 case 7: /* channels 1..13 */
1085 case 8: /* channels 1..9; 40 MHz */
1086 case 9: /* channels 5..13; 40 MHz */
1087 if (chan < 1 || chan > 13)
1089 return 2407 + 5 * chan;
1090 case 1: /* channels 36,40,44,48 */
1091 case 2: /* channels 52,56,60,64; dfs */
1092 case 4: /* channels 36,44; 40 MHz */
1093 case 5: /* channels 52,60; 40 MHz */
1094 if (chan < 36 || chan > 64)
1096 return 5000 + 5 * chan;
1097 case 3: /* channels 149,153,157,161,165 */
1098 case 6: /* channels 149,157; 40 MHz */
1099 if (chan < 149 || chan > 165)
1101 return 5000 + 5 * chan;
1107 static int ieee80211_chan_to_freq_global(u8 op_class, u8 chan)
1109 /* Table E-4 in IEEE Std 802.11-2012 - Global operating classes */
1112 /* channels 1..13 */
1113 if (chan < 1 || chan > 13)
1115 return 2407 + 5 * chan;
1120 return 2414 + 5 * chan;
1121 case 83: /* channels 1..9; 40 MHz */
1122 case 84: /* channels 5..13; 40 MHz */
1123 if (chan < 1 || chan > 13)
1125 return 2407 + 5 * chan;
1126 case 115: /* channels 36,40,44,48; indoor only */
1127 case 116: /* channels 36,44; 40 MHz; indoor only */
1128 case 117: /* channels 40,48; 40 MHz; indoor only */
1129 case 118: /* channels 52,56,60,64; dfs */
1130 case 119: /* channels 52,60; 40 MHz; dfs */
1131 case 120: /* channels 56,64; 40 MHz; dfs */
1132 if (chan < 36 || chan > 64)
1134 return 5000 + 5 * chan;
1135 case 121: /* channels 100-140 */
1136 case 122: /* channels 100-142; 40 MHz */
1137 case 123: /* channels 104-136; 40 MHz */
1138 if (chan < 100 || chan > 140)
1140 return 5000 + 5 * chan;
1141 case 124: /* channels 149,153,157,161 */
1142 case 126: /* channels 149,157; 40 MHz */
1143 case 127: /* channels 153,161; 40 MHz */
1144 if (chan < 149 || chan > 161)
1146 return 5000 + 5 * chan;
1147 case 125: /* channels 149,153,157,161,165,169 */
1148 if (chan < 149 || chan > 169)
1150 return 5000 + 5 * chan;
1151 case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
1152 case 130: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
1153 if (chan < 36 || chan > 161)
1155 return 5000 + 5 * chan;
1156 case 129: /* center freqs 50, 114; 160 MHz */
1157 if (chan < 36 || chan > 128)
1159 return 5000 + 5 * chan;
1160 case 180: /* 60 GHz band, channels 1..4 */
1161 if (chan < 1 || chan > 4)
1163 return 56160 + 2160 * chan;
1169 * ieee80211_chan_to_freq - Convert channel info to frequency
1170 * @country: Country code, if known; otherwise, global operating class is used
1171 * @op_class: Operating class
1172 * @chan: Channel number
1173 * Returns: Frequency in MHz or -1 if the specified channel is unknown
1175 int ieee80211_chan_to_freq(const char *country, u8 op_class, u8 chan)
1179 if (country_match(us_op_class_cc, country)) {
1180 freq = ieee80211_chan_to_freq_us(op_class, chan);
1185 if (country_match(eu_op_class_cc, country)) {
1186 freq = ieee80211_chan_to_freq_eu(op_class, chan);
1191 if (country_match(jp_op_class_cc, country)) {
1192 freq = ieee80211_chan_to_freq_jp(op_class, chan);
1197 if (country_match(cn_op_class_cc, country)) {
1198 freq = ieee80211_chan_to_freq_cn(op_class, chan);
1203 return ieee80211_chan_to_freq_global(op_class, chan);
1207 int ieee80211_is_dfs(int freq, const struct hostapd_hw_modes *modes,
1212 if (!modes || !num_modes)
1213 return (freq >= 5260 && freq <= 5320) ||
1214 (freq >= 5500 && freq <= 5700);
1216 for (i = 0; i < num_modes; i++) {
1217 for (j = 0; j < modes[i].num_channels; j++) {
1218 if (modes[i].channels[j].freq == freq &&
1219 (modes[i].channels[j].flag & HOSTAPD_CHAN_RADAR))
1228 static int is_11b(u8 rate)
1230 return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16;
1234 int supp_rates_11b_only(struct ieee802_11_elems *elems)
1236 int num_11b = 0, num_others = 0;
1239 if (elems->supp_rates == NULL && elems->ext_supp_rates == NULL)
1242 for (i = 0; elems->supp_rates && i < elems->supp_rates_len; i++) {
1243 if (is_11b(elems->supp_rates[i]))
1249 for (i = 0; elems->ext_supp_rates && i < elems->ext_supp_rates_len;
1251 if (is_11b(elems->ext_supp_rates[i]))
1257 return num_11b > 0 && num_others == 0;
1261 const char * fc2str(u16 fc)
1263 u16 stype = WLAN_FC_GET_STYPE(fc);
1264 #define C2S(x) case x: return #x;
1266 switch (WLAN_FC_GET_TYPE(fc)) {
1267 case WLAN_FC_TYPE_MGMT:
1269 C2S(WLAN_FC_STYPE_ASSOC_REQ)
1270 C2S(WLAN_FC_STYPE_ASSOC_RESP)
1271 C2S(WLAN_FC_STYPE_REASSOC_REQ)
1272 C2S(WLAN_FC_STYPE_REASSOC_RESP)
1273 C2S(WLAN_FC_STYPE_PROBE_REQ)
1274 C2S(WLAN_FC_STYPE_PROBE_RESP)
1275 C2S(WLAN_FC_STYPE_BEACON)
1276 C2S(WLAN_FC_STYPE_ATIM)
1277 C2S(WLAN_FC_STYPE_DISASSOC)
1278 C2S(WLAN_FC_STYPE_AUTH)
1279 C2S(WLAN_FC_STYPE_DEAUTH)
1280 C2S(WLAN_FC_STYPE_ACTION)
1283 case WLAN_FC_TYPE_CTRL:
1285 C2S(WLAN_FC_STYPE_PSPOLL)
1286 C2S(WLAN_FC_STYPE_RTS)
1287 C2S(WLAN_FC_STYPE_CTS)
1288 C2S(WLAN_FC_STYPE_ACK)
1289 C2S(WLAN_FC_STYPE_CFEND)
1290 C2S(WLAN_FC_STYPE_CFENDACK)
1293 case WLAN_FC_TYPE_DATA:
1295 C2S(WLAN_FC_STYPE_DATA)
1296 C2S(WLAN_FC_STYPE_DATA_CFACK)
1297 C2S(WLAN_FC_STYPE_DATA_CFPOLL)
1298 C2S(WLAN_FC_STYPE_DATA_CFACKPOLL)
1299 C2S(WLAN_FC_STYPE_NULLFUNC)
1300 C2S(WLAN_FC_STYPE_CFACK)
1301 C2S(WLAN_FC_STYPE_CFPOLL)
1302 C2S(WLAN_FC_STYPE_CFACKPOLL)
1303 C2S(WLAN_FC_STYPE_QOS_DATA)
1304 C2S(WLAN_FC_STYPE_QOS_DATA_CFACK)
1305 C2S(WLAN_FC_STYPE_QOS_DATA_CFPOLL)
1306 C2S(WLAN_FC_STYPE_QOS_DATA_CFACKPOLL)
1307 C2S(WLAN_FC_STYPE_QOS_NULL)
1308 C2S(WLAN_FC_STYPE_QOS_CFPOLL)
1309 C2S(WLAN_FC_STYPE_QOS_CFACKPOLL)
1313 return "WLAN_FC_TYPE_UNKNOWN";
1318 int mb_ies_info_by_ies(struct mb_ies_info *info, const u8 *ies_buf,
1321 const struct element *elem;
1323 os_memset(info, 0, sizeof(*info));
1328 for_each_element_id(elem, WLAN_EID_MULTI_BAND, ies_buf, ies_len) {
1329 if (info->nof_ies >= MAX_NOF_MB_IES_SUPPORTED)
1332 wpa_printf(MSG_DEBUG, "MB IE of %u bytes found",
1334 info->ies[info->nof_ies].ie = elem->data;
1335 info->ies[info->nof_ies].ie_len = elem->datalen;
1339 if (!for_each_element_completed(elem, ies_buf, ies_len)) {
1340 wpa_hexdump(MSG_DEBUG, "Truncated IEs", ies_buf, ies_len);
1348 struct wpabuf * mb_ies_by_info(struct mb_ies_info *info)
1350 struct wpabuf *mb_ies = NULL;
1352 WPA_ASSERT(info != NULL);
1354 if (info->nof_ies) {
1356 size_t mb_ies_size = 0;
1358 for (i = 0; i < info->nof_ies; i++)
1359 mb_ies_size += 2 + info->ies[i].ie_len;
1361 mb_ies = wpabuf_alloc(mb_ies_size);
1363 for (i = 0; i < info->nof_ies; i++) {
1364 wpabuf_put_u8(mb_ies, WLAN_EID_MULTI_BAND);
1365 wpabuf_put_u8(mb_ies, info->ies[i].ie_len);
1366 wpabuf_put_data(mb_ies,
1368 info->ies[i].ie_len);
1377 const struct oper_class_map global_op_class[] = {
1378 { HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20, P2P_SUPP },
1379 { HOSTAPD_MODE_IEEE80211G, 82, 14, 14, 1, BW20, NO_P2P_SUPP },
1381 /* Do not enable HT40 on 2.4 GHz for P2P use for now */
1382 { HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS, NO_P2P_SUPP },
1383 { HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS, NO_P2P_SUPP },
1385 { HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20, P2P_SUPP },
1386 { HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS, P2P_SUPP },
1387 { HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS, P2P_SUPP },
1388 { HOSTAPD_MODE_IEEE80211A, 118, 52, 64, 4, BW20, NO_P2P_SUPP },
1389 { HOSTAPD_MODE_IEEE80211A, 119, 52, 60, 8, BW40PLUS, NO_P2P_SUPP },
1390 { HOSTAPD_MODE_IEEE80211A, 120, 56, 64, 8, BW40MINUS, NO_P2P_SUPP },
1391 { HOSTAPD_MODE_IEEE80211A, 121, 100, 140, 4, BW20, NO_P2P_SUPP },
1392 { HOSTAPD_MODE_IEEE80211A, 122, 100, 132, 8, BW40PLUS, NO_P2P_SUPP },
1393 { HOSTAPD_MODE_IEEE80211A, 123, 104, 136, 8, BW40MINUS, NO_P2P_SUPP },
1394 { HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20, P2P_SUPP },
1395 { HOSTAPD_MODE_IEEE80211A, 125, 149, 169, 4, BW20, P2P_SUPP },
1396 { HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8, BW40PLUS, P2P_SUPP },
1397 { HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8, BW40MINUS, P2P_SUPP },
1400 * IEEE P802.11ac/D7.0 Table E-4 actually talks about channel center
1401 * frequency index 42, 58, 106, 122, 138, 155 with channel spacing of
1402 * 80 MHz, but currently use the following definition for simplicity
1403 * (these center frequencies are not actual channels, which makes
1404 * wpas_p2p_allow_channel() fail). wpas_p2p_verify_80mhz() should take
1405 * care of removing invalid channels.
1407 { HOSTAPD_MODE_IEEE80211A, 128, 36, 161, 4, BW80, P2P_SUPP },
1408 { HOSTAPD_MODE_IEEE80211A, 129, 50, 114, 16, BW160, P2P_SUPP },
1409 { HOSTAPD_MODE_IEEE80211A, 130, 36, 161, 4, BW80P80, P2P_SUPP },
1410 { HOSTAPD_MODE_IEEE80211AD, 180, 1, 4, 1, BW2160, P2P_SUPP },
1411 { -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP }
1415 static enum phy_type ieee80211_phy_type_by_freq(int freq)
1417 enum hostapd_hw_mode hw_mode;
1420 hw_mode = ieee80211_freq_to_chan(freq, &channel);
1423 case HOSTAPD_MODE_IEEE80211A:
1424 return PHY_TYPE_OFDM;
1425 case HOSTAPD_MODE_IEEE80211B:
1426 return PHY_TYPE_HRDSSS;
1427 case HOSTAPD_MODE_IEEE80211G:
1428 return PHY_TYPE_ERP;
1429 case HOSTAPD_MODE_IEEE80211AD:
1430 return PHY_TYPE_DMG;
1432 return PHY_TYPE_UNSPECIFIED;
1437 /* ieee80211_get_phy_type - Derive the phy type by freq and bandwidth */
1438 enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht)
1441 return PHY_TYPE_VHT;
1445 return ieee80211_phy_type_by_freq(freq);
1449 size_t global_op_class_size = ARRAY_SIZE(global_op_class);
1453 * get_ie - Fetch a specified information element from IEs buffer
1454 * @ies: Information elements buffer
1455 * @len: Information elements buffer length
1456 * @eid: Information element identifier (WLAN_EID_*)
1457 * Returns: Pointer to the information element (id field) or %NULL if not found
1459 * This function returns the first matching information element in the IEs
1460 * buffer or %NULL in case the element is not found.
1462 const u8 * get_ie(const u8 *ies, size_t len, u8 eid)
1464 const struct element *elem;
1469 for_each_element_id(elem, eid, ies, len)
1477 * get_ie_ext - Fetch a specified extended information element from IEs buffer
1478 * @ies: Information elements buffer
1479 * @len: Information elements buffer length
1480 * @ext: Information element extension identifier (WLAN_EID_EXT_*)
1481 * Returns: Pointer to the information element (id field) or %NULL if not found
1483 * This function returns the first matching information element in the IEs
1484 * buffer or %NULL in case the element is not found.
1486 const u8 * get_ie_ext(const u8 *ies, size_t len, u8 ext)
1488 const struct element *elem;
1493 for_each_element_extid(elem, ext, ies, len)
1500 const u8 * get_vendor_ie(const u8 *ies, size_t len, u32 vendor_type)
1502 const struct element *elem;
1504 for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, len) {
1505 if (elem->datalen >= 4 &&
1506 vendor_type == WPA_GET_BE32(elem->data))
1514 size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len)
1517 * MBO IE requires 6 bytes without the attributes: EID (1), length (1),
1518 * OUI (3), OUI type (1).
1520 if (len < 6 + attr_len) {
1521 wpa_printf(MSG_DEBUG,
1522 "MBO: Not enough room in buffer for MBO IE: buf len = %zu, attr_len = %zu",
1527 *buf++ = WLAN_EID_VENDOR_SPECIFIC;
1528 *buf++ = attr_len + 4;
1529 WPA_PUT_BE24(buf, OUI_WFA);
1531 *buf++ = MBO_OUI_TYPE;
1532 os_memcpy(buf, attr, attr_len);
1534 return 6 + attr_len;
1538 size_t add_multi_ap_ie(u8 *buf, size_t len, u8 value)
1545 *pos++ = WLAN_EID_VENDOR_SPECIFIC;
1546 *pos++ = 7; /* len */
1547 WPA_PUT_BE24(pos, OUI_WFA);
1549 *pos++ = MULTI_AP_OUI_TYPE;
1550 *pos++ = MULTI_AP_SUB_ELEM_TYPE;
1551 *pos++ = 1; /* len */
1558 static const struct country_op_class us_op_class[] = {
1580 static const struct country_op_class eu_op_class[] = {
1597 static const struct country_op_class jp_op_class[] = {
1621 static const struct country_op_class cn_op_class[] = {
1634 global_op_class_from_country_array(u8 op_class, size_t array_size,
1635 const struct country_op_class *country_array)
1639 for (i = 0; i < array_size; i++) {
1640 if (country_array[i].country_op_class == op_class)
1641 return country_array[i].global_op_class;
1648 u8 country_to_global_op_class(const char *country, u8 op_class)
1650 const struct country_op_class *country_array;
1654 if (country_match(us_op_class_cc, country)) {
1655 country_array = us_op_class;
1656 size = ARRAY_SIZE(us_op_class);
1657 } else if (country_match(eu_op_class_cc, country)) {
1658 country_array = eu_op_class;
1659 size = ARRAY_SIZE(eu_op_class);
1660 } else if (country_match(jp_op_class_cc, country)) {
1661 country_array = jp_op_class;
1662 size = ARRAY_SIZE(jp_op_class);
1663 } else if (country_match(cn_op_class_cc, country)) {
1664 country_array = cn_op_class;
1665 size = ARRAY_SIZE(cn_op_class);
1668 * Countries that do not match any of the above countries use
1669 * global operating classes
1674 g_op_class = global_op_class_from_country_array(op_class, size,
1678 * If the given operating class did not match any of the country's
1679 * operating classes, assume that global operating class is used.
1681 return g_op_class ? g_op_class : op_class;
1685 const struct oper_class_map * get_oper_class(const char *country, u8 op_class)
1687 const struct oper_class_map *op;
1690 op_class = country_to_global_op_class(country, op_class);
1692 op = &global_op_class[0];
1693 while (op->op_class && op->op_class != op_class)
1703 int oper_class_bw_to_int(const struct oper_class_map *map)
1724 int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
1727 u8 *nei_pos = nei_rep;
1731 * BSS Transition Candidate List Entries - Neighbor Report elements
1732 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
1733 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
1740 pos = os_strstr(pos, " neighbor=");
1743 if (nei_pos + 15 > nei_rep + nei_rep_len) {
1744 wpa_printf(MSG_DEBUG,
1745 "Not enough room for additional neighbor");
1750 nei_start = nei_pos;
1751 *nei_pos++ = WLAN_EID_NEIGHBOR_REPORT;
1752 nei_pos++; /* length to be filled in */
1754 if (hwaddr_aton(pos, nei_pos)) {
1755 wpa_printf(MSG_DEBUG, "Invalid BSSID");
1758 nei_pos += ETH_ALEN;
1761 wpa_printf(MSG_DEBUG, "Missing BSSID Information");
1766 val = strtol(pos, &endptr, 0);
1767 WPA_PUT_LE32(nei_pos, val);
1769 if (*endptr != ',') {
1770 wpa_printf(MSG_DEBUG, "Missing Operating Class");
1775 *nei_pos++ = atoi(pos); /* Operating Class */
1776 pos = os_strchr(pos, ',');
1778 wpa_printf(MSG_DEBUG, "Missing Channel Number");
1783 *nei_pos++ = atoi(pos); /* Channel Number */
1784 pos = os_strchr(pos, ',');
1786 wpa_printf(MSG_DEBUG, "Missing PHY Type");
1791 *nei_pos++ = atoi(pos); /* PHY Type */
1792 end = os_strchr(pos, ' ');
1793 tmp = os_strchr(pos, ',');
1794 if (tmp && (!end || tmp < end)) {
1795 /* Optional Subelements (hexdump) */
1799 end = os_strchr(pos, ' ');
1803 len = os_strlen(pos);
1804 if (nei_pos + len / 2 > nei_rep + nei_rep_len) {
1805 wpa_printf(MSG_DEBUG,
1806 "Not enough room for neighbor subelements");
1810 hexstr2bin(pos, nei_pos, len / 2) < 0) {
1811 wpa_printf(MSG_DEBUG,
1812 "Invalid neighbor subelement info");
1819 nei_start[1] = nei_pos - nei_start - 2;
1822 return nei_pos - nei_rep;
1826 int ieee802_11_ext_capab(const u8 *ie, unsigned int capab)
1828 if (!ie || ie[1] <= capab / 8)
1830 return !!(ie[2 + capab / 8] & BIT(capab % 8));