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 "qca-vendor.h"
15 #include "ieee802_11_defs.h"
16 #include "ieee802_11_common.h"
19 static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen,
20 struct ieee802_11_elems *elems,
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
30 wpa_printf(MSG_MSGDUMP, "short vendor specific "
31 "information element ignored (len=%lu)",
32 (unsigned long) elen);
37 oui = WPA_GET_BE24(pos);
40 /* Microsoft/Wi-Fi information elements are further typed and
44 /* Microsoft OUI (00:50:F2) with OUI Type 1:
45 * real WPA information element */
47 elems->wpa_ie_len = elen;
50 /* WMM information element */
52 wpa_printf(MSG_MSGDUMP, "short WMM "
53 "information element ignored "
55 (unsigned long) elen);
59 case WMM_OUI_SUBTYPE_INFORMATION_ELEMENT:
60 case WMM_OUI_SUBTYPE_PARAMETER_ELEMENT:
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
68 elems->wmm_len = elen;
70 case WMM_OUI_SUBTYPE_TSPEC_ELEMENT:
71 elems->wmm_tspec = pos;
72 elems->wmm_tspec_len = elen;
75 wpa_printf(MSG_EXCESSIVE, "unknown WMM "
76 "information element ignored "
77 "(subtype=%d len=%lu)",
78 pos[4], (unsigned long) elen);
83 /* Wi-Fi Protected Setup (WPS) IE */
85 elems->wps_ie_len = elen;
88 wpa_printf(MSG_EXCESSIVE, "Unknown Microsoft "
89 "information element ignored "
91 pos[3], (unsigned long) elen);
99 /* Wi-Fi Alliance - P2P IE */
101 elems->p2p_len = elen;
104 /* Wi-Fi Alliance - WFD IE */
106 elems->wfd_len = elen;
108 case HS20_INDICATION_OUI_TYPE:
111 elems->hs20_len = elen;
113 case HS20_OSEN_OUI_TYPE:
114 /* Hotspot 2.0 OSEN */
116 elems->osen_len = elen;
121 elems->mbo_len = elen;
124 wpa_printf(MSG_MSGDUMP, "Unknown WFA "
125 "information element ignored "
127 pos[3], (unsigned long) elen);
134 case VENDOR_HT_CAPAB_OUI_TYPE:
135 elems->vendor_ht_cap = pos;
136 elems->vendor_ht_cap_len = elen;
138 case VENDOR_VHT_TYPE:
140 (pos[4] == VENDOR_VHT_SUBTYPE ||
141 pos[4] == VENDOR_VHT_SUBTYPE2)) {
142 elems->vendor_vht = pos;
143 elems->vendor_vht_len = elen;
148 wpa_printf(MSG_EXCESSIVE, "Unknown Broadcom "
149 "information element ignored "
151 pos[3], (unsigned long) elen);
158 case QCA_VENDOR_ELEM_P2P_PREF_CHAN_LIST:
159 elems->pref_freq_list = pos;
160 elems->pref_freq_list_len = elen;
163 wpa_printf(MSG_EXCESSIVE,
164 "Unknown QCA information element ignored (type=%d len=%lu)",
165 pos[3], (unsigned long) elen);
171 wpa_printf(MSG_EXCESSIVE, "unknown vendor specific "
172 "information element ignored (vendor OUI "
173 "%02x:%02x:%02x len=%lu)",
174 pos[0], pos[1], pos[2], (unsigned long) elen);
183 * ieee802_11_parse_elems - Parse information elements in management frames
184 * @start: Pointer to the start of IEs
185 * @len: Length of IE buffer in octets
186 * @elems: Data structure for parsed elements
187 * @show_errors: Whether to show parsing errors in debug log
188 * Returns: Parsing result
190 ParseRes ieee802_11_parse_elems(const u8 *start, size_t len,
191 struct ieee802_11_elems *elems,
195 const u8 *pos = start;
198 os_memset(elems, 0, sizeof(*elems));
209 wpa_printf(MSG_DEBUG, "IEEE 802.11 element "
210 "parse failed (id=%d elen=%d "
212 id, elen, (unsigned long) left);
213 wpa_hexdump(MSG_MSGDUMP, "IEs", start, len);
220 if (elen > SSID_MAX_LEN) {
221 wpa_printf(MSG_DEBUG,
222 "Ignored too long SSID element (elen=%u)",
227 elems->ssid_len = elen;
229 case WLAN_EID_SUPP_RATES:
230 elems->supp_rates = pos;
231 elems->supp_rates_len = elen;
233 case WLAN_EID_DS_PARAMS:
236 elems->ds_params = pos;
238 case WLAN_EID_CF_PARAMS:
241 case WLAN_EID_CHALLENGE:
242 elems->challenge = pos;
243 elems->challenge_len = elen;
245 case WLAN_EID_ERP_INFO:
248 elems->erp_info = pos;
250 case WLAN_EID_EXT_SUPP_RATES:
251 elems->ext_supp_rates = pos;
252 elems->ext_supp_rates_len = elen;
254 case WLAN_EID_VENDOR_SPECIFIC:
255 if (ieee802_11_parse_vendor_specific(pos, elen,
262 elems->rsn_ie_len = elen;
264 case WLAN_EID_PWR_CAPABILITY:
266 case WLAN_EID_SUPPORTED_CHANNELS:
267 elems->supp_channels = pos;
268 elems->supp_channels_len = elen;
270 case WLAN_EID_MOBILITY_DOMAIN:
271 if (elen < sizeof(struct rsn_mdie))
274 elems->mdie_len = elen;
276 case WLAN_EID_FAST_BSS_TRANSITION:
277 if (elen < sizeof(struct rsn_ftie))
280 elems->ftie_len = elen;
282 case WLAN_EID_TIMEOUT_INTERVAL:
285 elems->timeout_int = pos;
287 case WLAN_EID_HT_CAP:
288 if (elen < sizeof(struct ieee80211_ht_capabilities))
290 elems->ht_capabilities = pos;
292 case WLAN_EID_HT_OPERATION:
293 if (elen < sizeof(struct ieee80211_ht_operation))
295 elems->ht_operation = pos;
297 case WLAN_EID_MESH_CONFIG:
298 elems->mesh_config = pos;
299 elems->mesh_config_len = elen;
301 case WLAN_EID_MESH_ID:
302 elems->mesh_id = pos;
303 elems->mesh_id_len = elen;
305 case WLAN_EID_PEER_MGMT:
306 elems->peer_mgmt = pos;
307 elems->peer_mgmt_len = elen;
309 case WLAN_EID_VHT_CAP:
310 if (elen < sizeof(struct ieee80211_vht_capabilities))
312 elems->vht_capabilities = pos;
314 case WLAN_EID_VHT_OPERATION:
315 if (elen < sizeof(struct ieee80211_vht_operation))
317 elems->vht_operation = pos;
319 case WLAN_EID_VHT_OPERATING_MODE_NOTIFICATION:
322 elems->vht_opmode_notif = pos;
324 case WLAN_EID_LINK_ID:
327 elems->link_id = pos;
329 case WLAN_EID_INTERWORKING:
330 elems->interworking = pos;
331 elems->interworking_len = elen;
333 case WLAN_EID_QOS_MAP_SET:
336 elems->qos_map_set = pos;
337 elems->qos_map_set_len = elen;
339 case WLAN_EID_EXT_CAPAB:
340 elems->ext_capab = pos;
341 elems->ext_capab_len = elen;
343 case WLAN_EID_BSS_MAX_IDLE_PERIOD:
346 elems->bss_max_idle_period = pos;
348 case WLAN_EID_SSID_LIST:
349 elems->ssid_list = pos;
350 elems->ssid_list_len = elen;
354 elems->ampe_len = elen;
358 elems->mic_len = elen;
359 /* after mic everything is encrypted, so stop. */
362 case WLAN_EID_MULTI_BAND:
363 if (elems->mb_ies.nof_ies >= MAX_NOF_MB_IES_SUPPORTED) {
364 wpa_printf(MSG_MSGDUMP,
365 "IEEE 802.11 element parse ignored MB IE (id=%d elen=%d)",
370 elems->mb_ies.ies[elems->mb_ies.nof_ies].ie = pos;
371 elems->mb_ies.ies[elems->mb_ies.nof_ies].ie_len = elen;
372 elems->mb_ies.nof_ies++;
374 case WLAN_EID_SUPPORTED_OPERATING_CLASSES:
375 elems->supp_op_classes = pos;
376 elems->supp_op_classes_len = elen;
378 case WLAN_EID_RRM_ENABLED_CAPABILITIES:
379 elems->rrm_enabled = pos;
380 elems->rrm_enabled_len = elen;
386 wpa_printf(MSG_MSGDUMP, "IEEE 802.11 element parse "
387 "ignored unknown element (id=%d elen=%d)",
399 return unknown ? ParseUnknown : ParseOK;
403 int ieee802_11_ie_count(const u8 *ies, size_t ies_len)
414 while (end - pos >= 2) {
415 if (2 + pos[1] > end - pos)
425 struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len,
429 const u8 *end, *pos, *ie;
435 while (end - pos > 1) {
436 if (2 + pos[1] > end - pos)
438 if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
439 WPA_GET_BE32(&pos[2]) == oui_type) {
447 return NULL; /* No specified vendor IE found */
449 buf = wpabuf_alloc(ies_len);
454 * There may be multiple vendor IEs in the message, so need to
455 * concatenate their data fields.
457 while (end - pos > 1) {
458 if (2 + pos[1] > end - pos)
460 if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
461 WPA_GET_BE32(&pos[2]) == oui_type)
462 wpabuf_put_data(buf, pos + 6, pos[1] - 4);
470 const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len)
475 * PS-Poll frames are 16 bytes. All other frames are
476 * 24 bytes or longer.
481 fc = le_to_host16(hdr->frame_control);
482 type = WLAN_FC_GET_TYPE(fc);
483 stype = WLAN_FC_GET_STYPE(fc);
486 case WLAN_FC_TYPE_DATA:
489 switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
490 case WLAN_FC_FROMDS | WLAN_FC_TODS:
498 case WLAN_FC_TYPE_CTRL:
499 if (stype != WLAN_FC_STYPE_PSPOLL)
502 case WLAN_FC_TYPE_MGMT:
510 int hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[],
511 const char *name, const char *val)
515 struct hostapd_wmm_ac_params *ac;
517 /* skip 'wme_ac_' or 'wmm_ac_' prefix */
519 if (os_strncmp(pos, "be_", 3) == 0) {
522 } else if (os_strncmp(pos, "bk_", 3) == 0) {
525 } else if (os_strncmp(pos, "vi_", 3) == 0) {
528 } else if (os_strncmp(pos, "vo_", 3) == 0) {
532 wpa_printf(MSG_ERROR, "Unknown WMM name '%s'", pos);
536 ac = &wmm_ac_params[num];
538 if (os_strcmp(pos, "aifs") == 0) {
540 if (v < 1 || v > 255) {
541 wpa_printf(MSG_ERROR, "Invalid AIFS value %d", v);
545 } else if (os_strcmp(pos, "cwmin") == 0) {
547 if (v < 0 || v > 15) {
548 wpa_printf(MSG_ERROR, "Invalid cwMin value %d", v);
552 } else if (os_strcmp(pos, "cwmax") == 0) {
554 if (v < 0 || v > 15) {
555 wpa_printf(MSG_ERROR, "Invalid cwMax value %d", v);
559 } else if (os_strcmp(pos, "txop_limit") == 0) {
561 if (v < 0 || v > 0xffff) {
562 wpa_printf(MSG_ERROR, "Invalid txop value %d", v);
566 } else if (os_strcmp(pos, "acm") == 0) {
568 if (v < 0 || v > 1) {
569 wpa_printf(MSG_ERROR, "Invalid acm value %d", v);
572 ac->admission_control_mandatory = v;
574 wpa_printf(MSG_ERROR, "Unknown wmm_ac_ field '%s'", pos);
582 enum hostapd_hw_mode ieee80211_freq_to_chan(int freq, u8 *channel)
586 return ieee80211_freq_to_channel_ext(freq, 0, VHT_CHANWIDTH_USE_HT,
592 * ieee80211_freq_to_channel_ext - Convert frequency into channel info
593 * for HT40 and VHT. DFS channels are not covered.
594 * @freq: Frequency (MHz) to convert
595 * @sec_channel: 0 = non-HT40, 1 = sec. channel above, -1 = sec. channel below
596 * @vht: VHT channel width (VHT_CHANWIDTH_*)
597 * @op_class: Buffer for returning operating class
598 * @channel: Buffer for returning channel number
599 * Returns: hw_mode on success, NUM_HOSTAPD_MODES on failure
601 enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
602 int sec_channel, int vht,
603 u8 *op_class, u8 *channel)
607 /* TODO: more operating classes */
609 if (sec_channel > 1 || sec_channel < -1)
610 return NUM_HOSTAPD_MODES;
612 if (freq >= 2412 && freq <= 2472) {
613 if ((freq - 2407) % 5)
614 return NUM_HOSTAPD_MODES;
617 return NUM_HOSTAPD_MODES;
619 /* 2.407 GHz, channels 1..13 */
620 if (sec_channel == 1)
622 else if (sec_channel == -1)
627 *channel = (freq - 2407) / 5;
629 return HOSTAPD_MODE_IEEE80211G;
633 if (sec_channel || vht)
634 return NUM_HOSTAPD_MODES;
636 *op_class = 82; /* channel 14 */
639 return HOSTAPD_MODE_IEEE80211B;
642 if (freq >= 4900 && freq < 5000) {
643 if ((freq - 4000) % 5)
644 return NUM_HOSTAPD_MODES;
645 *channel = (freq - 4000) / 5;
646 *op_class = 0; /* TODO */
647 return HOSTAPD_MODE_IEEE80211A;
651 case VHT_CHANWIDTH_80MHZ:
654 case VHT_CHANWIDTH_160MHZ:
657 case VHT_CHANWIDTH_80P80MHZ:
665 /* 5 GHz, channels 36..48 */
666 if (freq >= 5180 && freq <= 5240) {
667 if ((freq - 5000) % 5)
668 return NUM_HOSTAPD_MODES;
671 *op_class = vht_opclass;
672 else if (sec_channel == 1)
674 else if (sec_channel == -1)
679 *channel = (freq - 5000) / 5;
681 return HOSTAPD_MODE_IEEE80211A;
684 /* 5 GHz, channels 149..169 */
685 if (freq >= 5745 && freq <= 5845) {
686 if ((freq - 5000) % 5)
687 return NUM_HOSTAPD_MODES;
690 *op_class = vht_opclass;
691 else if (sec_channel == 1)
693 else if (sec_channel == -1)
695 else if (freq <= 5805)
700 *channel = (freq - 5000) / 5;
702 return HOSTAPD_MODE_IEEE80211A;
705 /* 5 GHz, channels 100..140 */
706 if (freq >= 5000 && freq <= 5700) {
707 if ((freq - 5000) % 5)
708 return NUM_HOSTAPD_MODES;
711 *op_class = vht_opclass;
712 else if (sec_channel == 1)
714 else if (sec_channel == -1)
719 *channel = (freq - 5000) / 5;
721 return HOSTAPD_MODE_IEEE80211A;
724 if (freq >= 5000 && freq < 5900) {
725 if ((freq - 5000) % 5)
726 return NUM_HOSTAPD_MODES;
727 *channel = (freq - 5000) / 5;
728 *op_class = 0; /* TODO */
729 return HOSTAPD_MODE_IEEE80211A;
732 /* 56.16 GHz, channel 1..4 */
733 if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 4) {
734 if (sec_channel || vht)
735 return NUM_HOSTAPD_MODES;
737 *channel = (freq - 56160) / 2160;
740 return HOSTAPD_MODE_IEEE80211AD;
743 return NUM_HOSTAPD_MODES;
747 static const char *const us_op_class_cc[] = {
751 static const char *const eu_op_class_cc[] = {
752 "AL", "AM", "AT", "AZ", "BA", "BE", "BG", "BY", "CH", "CY", "CZ", "DE",
753 "DK", "EE", "EL", "ES", "FI", "FR", "GE", "HR", "HU", "IE", "IS", "IT",
754 "LI", "LT", "LU", "LV", "MD", "ME", "MK", "MT", "NL", "NO", "PL", "PT",
755 "RO", "RS", "RU", "SE", "SI", "SK", "TR", "UA", "UK", NULL
758 static const char *const jp_op_class_cc[] = {
762 static const char *const cn_op_class_cc[] = {
767 static int country_match(const char *const cc[], const char *const country)
773 for (i = 0; cc[i]; i++) {
774 if (cc[i][0] == country[0] && cc[i][1] == country[1])
782 static int ieee80211_chan_to_freq_us(u8 op_class, u8 chan)
785 case 12: /* channels 1..11 */
786 case 32: /* channels 1..7; 40 MHz */
787 case 33: /* channels 5..11; 40 MHz */
788 if (chan < 1 || chan > 11)
790 return 2407 + 5 * chan;
791 case 1: /* channels 36,40,44,48 */
792 case 2: /* channels 52,56,60,64; dfs */
793 case 22: /* channels 36,44; 40 MHz */
794 case 23: /* channels 52,60; 40 MHz */
795 case 27: /* channels 40,48; 40 MHz */
796 case 28: /* channels 56,64; 40 MHz */
797 if (chan < 36 || chan > 64)
799 return 5000 + 5 * chan;
800 case 4: /* channels 100-144 */
801 case 24: /* channels 100-140; 40 MHz */
802 if (chan < 100 || chan > 144)
804 return 5000 + 5 * chan;
805 case 3: /* channels 149,153,157,161 */
806 case 25: /* channels 149,157; 40 MHz */
807 case 26: /* channels 149,157; 40 MHz */
808 case 30: /* channels 153,161; 40 MHz */
809 case 31: /* channels 153,161; 40 MHz */
810 if (chan < 149 || chan > 161)
812 return 5000 + 5 * chan;
813 case 5: /* channels 149,153,157,161,165 */
814 if (chan < 149 || chan > 165)
816 return 5000 + 5 * chan;
817 case 34: /* 60 GHz band, channels 1..3 */
818 if (chan < 1 || chan > 3)
820 return 56160 + 2160 * chan;
826 static int ieee80211_chan_to_freq_eu(u8 op_class, u8 chan)
829 case 4: /* channels 1..13 */
830 case 11: /* channels 1..9; 40 MHz */
831 case 12: /* channels 5..13; 40 MHz */
832 if (chan < 1 || chan > 13)
834 return 2407 + 5 * chan;
835 case 1: /* channels 36,40,44,48 */
836 case 2: /* channels 52,56,60,64; dfs */
837 case 5: /* channels 36,44; 40 MHz */
838 case 6: /* channels 52,60; 40 MHz */
839 case 8: /* channels 40,48; 40 MHz */
840 case 9: /* channels 56,64; 40 MHz */
841 if (chan < 36 || chan > 64)
843 return 5000 + 5 * chan;
844 case 3: /* channels 100-140 */
845 case 7: /* channels 100-132; 40 MHz */
846 case 10: /* channels 104-136; 40 MHz */
847 case 16: /* channels 100-140 */
848 if (chan < 100 || chan > 140)
850 return 5000 + 5 * chan;
851 case 17: /* channels 149,153,157,161,165,169 */
852 if (chan < 149 || chan > 169)
854 return 5000 + 5 * chan;
855 case 18: /* 60 GHz band, channels 1..4 */
856 if (chan < 1 || chan > 4)
858 return 56160 + 2160 * chan;
864 static int ieee80211_chan_to_freq_jp(u8 op_class, u8 chan)
867 case 30: /* channels 1..13 */
868 case 56: /* channels 1..9; 40 MHz */
869 case 57: /* channels 5..13; 40 MHz */
870 if (chan < 1 || chan > 13)
872 return 2407 + 5 * chan;
873 case 31: /* channel 14 */
876 return 2414 + 5 * chan;
877 case 1: /* channels 34,38,42,46(old) or 36,40,44,48 */
878 case 32: /* channels 52,56,60,64 */
879 case 33: /* channels 52,56,60,64 */
880 case 36: /* channels 36,44; 40 MHz */
881 case 37: /* channels 52,60; 40 MHz */
882 case 38: /* channels 52,60; 40 MHz */
883 case 41: /* channels 40,48; 40 MHz */
884 case 42: /* channels 56,64; 40 MHz */
885 case 43: /* channels 56,64; 40 MHz */
886 if (chan < 34 || chan > 64)
888 return 5000 + 5 * chan;
889 case 34: /* channels 100-140 */
890 case 35: /* channels 100-140 */
891 case 39: /* channels 100-132; 40 MHz */
892 case 40: /* channels 100-132; 40 MHz */
893 case 44: /* channels 104-136; 40 MHz */
894 case 45: /* channels 104-136; 40 MHz */
895 case 58: /* channels 100-140 */
896 if (chan < 100 || chan > 140)
898 return 5000 + 5 * chan;
899 case 59: /* 60 GHz band, channels 1..4 */
900 if (chan < 1 || chan > 3)
902 return 56160 + 2160 * chan;
908 static int ieee80211_chan_to_freq_cn(u8 op_class, u8 chan)
911 case 7: /* channels 1..13 */
912 case 8: /* channels 1..9; 40 MHz */
913 case 9: /* channels 5..13; 40 MHz */
914 if (chan < 1 || chan > 13)
916 return 2407 + 5 * chan;
917 case 1: /* channels 36,40,44,48 */
918 case 2: /* channels 52,56,60,64; dfs */
919 case 4: /* channels 36,44; 40 MHz */
920 case 5: /* channels 52,60; 40 MHz */
921 if (chan < 36 || chan > 64)
923 return 5000 + 5 * chan;
924 case 3: /* channels 149,153,157,161,165 */
925 case 6: /* channels 149,157; 40 MHz */
926 if (chan < 149 || chan > 165)
928 return 5000 + 5 * chan;
934 static int ieee80211_chan_to_freq_global(u8 op_class, u8 chan)
936 /* Table E-4 in IEEE Std 802.11-2012 - Global operating classes */
940 if (chan < 1 || chan > 13)
942 return 2407 + 5 * chan;
947 return 2414 + 5 * chan;
948 case 83: /* channels 1..9; 40 MHz */
949 case 84: /* channels 5..13; 40 MHz */
950 if (chan < 1 || chan > 13)
952 return 2407 + 5 * chan;
953 case 115: /* channels 36,40,44,48; indoor only */
954 case 116: /* channels 36,44; 40 MHz; indoor only */
955 case 117: /* channels 40,48; 40 MHz; indoor only */
956 case 118: /* channels 52,56,60,64; dfs */
957 case 119: /* channels 52,60; 40 MHz; dfs */
958 case 120: /* channels 56,64; 40 MHz; dfs */
959 if (chan < 36 || chan > 64)
961 return 5000 + 5 * chan;
962 case 121: /* channels 100-140 */
963 case 122: /* channels 100-142; 40 MHz */
964 case 123: /* channels 104-136; 40 MHz */
965 if (chan < 100 || chan > 140)
967 return 5000 + 5 * chan;
968 case 124: /* channels 149,153,157,161 */
969 case 126: /* channels 149,157; 40 MHz */
970 case 127: /* channels 153,161; 40 MHz */
971 if (chan < 149 || chan > 161)
973 return 5000 + 5 * chan;
974 case 125: /* channels 149,153,157,161,165,169 */
975 if (chan < 149 || chan > 169)
977 return 5000 + 5 * chan;
978 case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
979 case 130: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
980 if (chan < 36 || chan > 161)
982 return 5000 + 5 * chan;
983 case 129: /* center freqs 50, 114; 160 MHz */
984 if (chan < 50 || chan > 114)
986 return 5000 + 5 * chan;
987 case 180: /* 60 GHz band, channels 1..4 */
988 if (chan < 1 || chan > 4)
990 return 56160 + 2160 * chan;
996 * ieee80211_chan_to_freq - Convert channel info to frequency
997 * @country: Country code, if known; otherwise, global operating class is used
998 * @op_class: Operating class
999 * @chan: Channel number
1000 * Returns: Frequency in MHz or -1 if the specified channel is unknown
1002 int ieee80211_chan_to_freq(const char *country, u8 op_class, u8 chan)
1006 if (country_match(us_op_class_cc, country)) {
1007 freq = ieee80211_chan_to_freq_us(op_class, chan);
1012 if (country_match(eu_op_class_cc, country)) {
1013 freq = ieee80211_chan_to_freq_eu(op_class, chan);
1018 if (country_match(jp_op_class_cc, country)) {
1019 freq = ieee80211_chan_to_freq_jp(op_class, chan);
1024 if (country_match(cn_op_class_cc, country)) {
1025 freq = ieee80211_chan_to_freq_cn(op_class, chan);
1030 return ieee80211_chan_to_freq_global(op_class, chan);
1034 int ieee80211_is_dfs(int freq)
1036 /* TODO: this could be more accurate to better cover all domains */
1037 return (freq >= 5260 && freq <= 5320) || (freq >= 5500 && freq <= 5700);
1041 static int is_11b(u8 rate)
1043 return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16;
1047 int supp_rates_11b_only(struct ieee802_11_elems *elems)
1049 int num_11b = 0, num_others = 0;
1052 if (elems->supp_rates == NULL && elems->ext_supp_rates == NULL)
1055 for (i = 0; elems->supp_rates && i < elems->supp_rates_len; i++) {
1056 if (is_11b(elems->supp_rates[i]))
1062 for (i = 0; elems->ext_supp_rates && i < elems->ext_supp_rates_len;
1064 if (is_11b(elems->ext_supp_rates[i]))
1070 return num_11b > 0 && num_others == 0;
1074 const char * fc2str(u16 fc)
1076 u16 stype = WLAN_FC_GET_STYPE(fc);
1077 #define C2S(x) case x: return #x;
1079 switch (WLAN_FC_GET_TYPE(fc)) {
1080 case WLAN_FC_TYPE_MGMT:
1082 C2S(WLAN_FC_STYPE_ASSOC_REQ)
1083 C2S(WLAN_FC_STYPE_ASSOC_RESP)
1084 C2S(WLAN_FC_STYPE_REASSOC_REQ)
1085 C2S(WLAN_FC_STYPE_REASSOC_RESP)
1086 C2S(WLAN_FC_STYPE_PROBE_REQ)
1087 C2S(WLAN_FC_STYPE_PROBE_RESP)
1088 C2S(WLAN_FC_STYPE_BEACON)
1089 C2S(WLAN_FC_STYPE_ATIM)
1090 C2S(WLAN_FC_STYPE_DISASSOC)
1091 C2S(WLAN_FC_STYPE_AUTH)
1092 C2S(WLAN_FC_STYPE_DEAUTH)
1093 C2S(WLAN_FC_STYPE_ACTION)
1096 case WLAN_FC_TYPE_CTRL:
1098 C2S(WLAN_FC_STYPE_PSPOLL)
1099 C2S(WLAN_FC_STYPE_RTS)
1100 C2S(WLAN_FC_STYPE_CTS)
1101 C2S(WLAN_FC_STYPE_ACK)
1102 C2S(WLAN_FC_STYPE_CFEND)
1103 C2S(WLAN_FC_STYPE_CFENDACK)
1106 case WLAN_FC_TYPE_DATA:
1108 C2S(WLAN_FC_STYPE_DATA)
1109 C2S(WLAN_FC_STYPE_DATA_CFACK)
1110 C2S(WLAN_FC_STYPE_DATA_CFPOLL)
1111 C2S(WLAN_FC_STYPE_DATA_CFACKPOLL)
1112 C2S(WLAN_FC_STYPE_NULLFUNC)
1113 C2S(WLAN_FC_STYPE_CFACK)
1114 C2S(WLAN_FC_STYPE_CFPOLL)
1115 C2S(WLAN_FC_STYPE_CFACKPOLL)
1116 C2S(WLAN_FC_STYPE_QOS_DATA)
1117 C2S(WLAN_FC_STYPE_QOS_DATA_CFACK)
1118 C2S(WLAN_FC_STYPE_QOS_DATA_CFPOLL)
1119 C2S(WLAN_FC_STYPE_QOS_DATA_CFACKPOLL)
1120 C2S(WLAN_FC_STYPE_QOS_NULL)
1121 C2S(WLAN_FC_STYPE_QOS_CFPOLL)
1122 C2S(WLAN_FC_STYPE_QOS_CFACKPOLL)
1126 return "WLAN_FC_TYPE_UNKNOWN";
1131 int mb_ies_info_by_ies(struct mb_ies_info *info, const u8 *ies_buf,
1134 os_memset(info, 0, sizeof(*info));
1136 while (ies_buf && ies_len >= 2 &&
1137 info->nof_ies < MAX_NOF_MB_IES_SUPPORTED) {
1138 size_t len = 2 + ies_buf[1];
1140 if (len > ies_len) {
1141 wpa_hexdump(MSG_DEBUG, "Truncated IEs",
1146 if (ies_buf[0] == WLAN_EID_MULTI_BAND) {
1147 wpa_printf(MSG_DEBUG, "MB IE of %zu bytes found", len);
1148 info->ies[info->nof_ies].ie = ies_buf + 2;
1149 info->ies[info->nof_ies].ie_len = ies_buf[1];
1161 struct wpabuf * mb_ies_by_info(struct mb_ies_info *info)
1163 struct wpabuf *mb_ies = NULL;
1165 WPA_ASSERT(info != NULL);
1167 if (info->nof_ies) {
1169 size_t mb_ies_size = 0;
1171 for (i = 0; i < info->nof_ies; i++)
1172 mb_ies_size += 2 + info->ies[i].ie_len;
1174 mb_ies = wpabuf_alloc(mb_ies_size);
1176 for (i = 0; i < info->nof_ies; i++) {
1177 wpabuf_put_u8(mb_ies, WLAN_EID_MULTI_BAND);
1178 wpabuf_put_u8(mb_ies, info->ies[i].ie_len);
1179 wpabuf_put_data(mb_ies,
1181 info->ies[i].ie_len);
1190 const struct oper_class_map global_op_class[] = {
1191 { HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20, P2P_SUPP },
1192 { HOSTAPD_MODE_IEEE80211G, 82, 14, 14, 1, BW20, NO_P2P_SUPP },
1194 /* Do not enable HT40 on 2.4 GHz for P2P use for now */
1195 { HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS, NO_P2P_SUPP },
1196 { HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS, NO_P2P_SUPP },
1198 { HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20, P2P_SUPP },
1199 { HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS, P2P_SUPP },
1200 { HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS, P2P_SUPP },
1201 { HOSTAPD_MODE_IEEE80211A, 118, 52, 64, 4, BW20, NO_P2P_SUPP },
1202 { HOSTAPD_MODE_IEEE80211A, 119, 52, 60, 8, BW40PLUS, NO_P2P_SUPP },
1203 { HOSTAPD_MODE_IEEE80211A, 120, 56, 64, 8, BW40MINUS, NO_P2P_SUPP },
1204 { HOSTAPD_MODE_IEEE80211A, 121, 100, 140, 4, BW20, NO_P2P_SUPP },
1205 { HOSTAPD_MODE_IEEE80211A, 122, 100, 132, 8, BW40PLUS, NO_P2P_SUPP },
1206 { HOSTAPD_MODE_IEEE80211A, 123, 104, 136, 8, BW40MINUS, NO_P2P_SUPP },
1207 { HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20, P2P_SUPP },
1208 { HOSTAPD_MODE_IEEE80211A, 125, 149, 169, 4, BW20, P2P_SUPP },
1209 { HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8, BW40PLUS, P2P_SUPP },
1210 { HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8, BW40MINUS, P2P_SUPP },
1213 * IEEE P802.11ac/D7.0 Table E-4 actually talks about channel center
1214 * frequency index 42, 58, 106, 122, 138, 155 with channel spacing of
1215 * 80 MHz, but currently use the following definition for simplicity
1216 * (these center frequencies are not actual channels, which makes
1217 * wpas_p2p_allow_channel() fail). wpas_p2p_verify_80mhz() should take
1218 * care of removing invalid channels.
1220 { HOSTAPD_MODE_IEEE80211A, 128, 36, 161, 4, BW80, P2P_SUPP },
1221 { HOSTAPD_MODE_IEEE80211A, 129, 50, 114, 16, BW160, P2P_SUPP },
1222 { HOSTAPD_MODE_IEEE80211A, 130, 36, 161, 4, BW80P80, P2P_SUPP },
1223 { HOSTAPD_MODE_IEEE80211AD, 180, 1, 4, 1, BW2160, P2P_SUPP },
1224 { -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP }
1228 static enum phy_type ieee80211_phy_type_by_freq(int freq)
1230 enum hostapd_hw_mode hw_mode;
1233 hw_mode = ieee80211_freq_to_chan(freq, &channel);
1236 case HOSTAPD_MODE_IEEE80211A:
1237 return PHY_TYPE_OFDM;
1238 case HOSTAPD_MODE_IEEE80211B:
1239 return PHY_TYPE_HRDSSS;
1240 case HOSTAPD_MODE_IEEE80211G:
1241 return PHY_TYPE_ERP;
1242 case HOSTAPD_MODE_IEEE80211AD:
1243 return PHY_TYPE_DMG;
1245 return PHY_TYPE_UNSPECIFIED;
1250 /* ieee80211_get_phy_type - Derive the phy type by freq and bandwidth */
1251 enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht)
1254 return PHY_TYPE_VHT;
1258 return ieee80211_phy_type_by_freq(freq);
1262 size_t global_op_class_size = ARRAY_SIZE(global_op_class);
1266 * get_ie - Fetch a specified information element from IEs buffer
1267 * @ies: Information elements buffer
1268 * @len: Information elements buffer length
1269 * @eid: Information element identifier (WLAN_EID_*)
1270 * Returns: Pointer to the information element (id field) or %NULL if not found
1272 * This function returns the first matching information element in the IEs
1273 * buffer or %NULL in case the element is not found.
1275 const u8 * get_ie(const u8 *ies, size_t len, u8 eid)
1284 while (end - ies > 1) {
1285 if (2 + ies[1] > end - ies)
1298 size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len)
1301 * MBO IE requires 6 bytes without the attributes: EID (1), length (1),
1302 * OUI (3), OUI type (1).
1304 if (len < 6 + attr_len) {
1305 wpa_printf(MSG_DEBUG,
1306 "MBO: Not enough room in buffer for MBO IE: buf len = %zu, attr_len = %zu",
1311 *buf++ = WLAN_EID_VENDOR_SPECIFIC;
1312 *buf++ = attr_len + 4;
1313 WPA_PUT_BE24(buf, OUI_WFA);
1315 *buf++ = MBO_OUI_TYPE;
1316 os_memcpy(buf, attr, attr_len);
1318 return 6 + attr_len;