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;
119 wpa_printf(MSG_MSGDUMP, "Unknown WFA "
120 "information element ignored "
122 pos[3], (unsigned long) elen);
129 case VENDOR_HT_CAPAB_OUI_TYPE:
130 elems->vendor_ht_cap = pos;
131 elems->vendor_ht_cap_len = elen;
133 case VENDOR_VHT_TYPE:
135 (pos[4] == VENDOR_VHT_SUBTYPE ||
136 pos[4] == VENDOR_VHT_SUBTYPE2)) {
137 elems->vendor_vht = pos;
138 elems->vendor_vht_len = elen;
143 wpa_printf(MSG_EXCESSIVE, "Unknown Broadcom "
144 "information element ignored "
146 pos[3], (unsigned long) elen);
153 case QCA_VENDOR_ELEM_P2P_PREF_CHAN_LIST:
154 elems->pref_freq_list = pos;
155 elems->pref_freq_list_len = elen;
158 wpa_printf(MSG_EXCESSIVE,
159 "Unknown QCA information element ignored (type=%d len=%lu)",
160 pos[3], (unsigned long) elen);
166 wpa_printf(MSG_EXCESSIVE, "unknown vendor specific "
167 "information element ignored (vendor OUI "
168 "%02x:%02x:%02x len=%lu)",
169 pos[0], pos[1], pos[2], (unsigned long) elen);
178 * ieee802_11_parse_elems - Parse information elements in management frames
179 * @start: Pointer to the start of IEs
180 * @len: Length of IE buffer in octets
181 * @elems: Data structure for parsed elements
182 * @show_errors: Whether to show parsing errors in debug log
183 * Returns: Parsing result
185 ParseRes ieee802_11_parse_elems(const u8 *start, size_t len,
186 struct ieee802_11_elems *elems,
190 const u8 *pos = start;
193 os_memset(elems, 0, sizeof(*elems));
204 wpa_printf(MSG_DEBUG, "IEEE 802.11 element "
205 "parse failed (id=%d elen=%d "
207 id, elen, (unsigned long) left);
208 wpa_hexdump(MSG_MSGDUMP, "IEs", start, len);
215 if (elen > SSID_MAX_LEN) {
216 wpa_printf(MSG_DEBUG,
217 "Ignored too long SSID element (elen=%u)",
222 elems->ssid_len = elen;
224 case WLAN_EID_SUPP_RATES:
225 elems->supp_rates = pos;
226 elems->supp_rates_len = elen;
228 case WLAN_EID_DS_PARAMS:
231 elems->ds_params = pos;
233 case WLAN_EID_CF_PARAMS:
236 case WLAN_EID_CHALLENGE:
237 elems->challenge = pos;
238 elems->challenge_len = elen;
240 case WLAN_EID_ERP_INFO:
243 elems->erp_info = pos;
245 case WLAN_EID_EXT_SUPP_RATES:
246 elems->ext_supp_rates = pos;
247 elems->ext_supp_rates_len = elen;
249 case WLAN_EID_VENDOR_SPECIFIC:
250 if (ieee802_11_parse_vendor_specific(pos, elen,
257 elems->rsn_ie_len = elen;
259 case WLAN_EID_PWR_CAPABILITY:
261 case WLAN_EID_SUPPORTED_CHANNELS:
262 elems->supp_channels = pos;
263 elems->supp_channels_len = elen;
265 case WLAN_EID_MOBILITY_DOMAIN:
266 if (elen < sizeof(struct rsn_mdie))
269 elems->mdie_len = elen;
271 case WLAN_EID_FAST_BSS_TRANSITION:
272 if (elen < sizeof(struct rsn_ftie))
275 elems->ftie_len = elen;
277 case WLAN_EID_TIMEOUT_INTERVAL:
280 elems->timeout_int = pos;
282 case WLAN_EID_HT_CAP:
283 if (elen < sizeof(struct ieee80211_ht_capabilities))
285 elems->ht_capabilities = pos;
287 case WLAN_EID_HT_OPERATION:
288 if (elen < sizeof(struct ieee80211_ht_operation))
290 elems->ht_operation = pos;
292 case WLAN_EID_MESH_CONFIG:
293 elems->mesh_config = pos;
294 elems->mesh_config_len = elen;
296 case WLAN_EID_MESH_ID:
297 elems->mesh_id = pos;
298 elems->mesh_id_len = elen;
300 case WLAN_EID_PEER_MGMT:
301 elems->peer_mgmt = pos;
302 elems->peer_mgmt_len = elen;
304 case WLAN_EID_VHT_CAP:
305 if (elen < sizeof(struct ieee80211_vht_capabilities))
307 elems->vht_capabilities = pos;
309 case WLAN_EID_VHT_OPERATION:
310 if (elen < sizeof(struct ieee80211_vht_operation))
312 elems->vht_operation = pos;
314 case WLAN_EID_VHT_OPERATING_MODE_NOTIFICATION:
317 elems->vht_opmode_notif = pos;
319 case WLAN_EID_LINK_ID:
322 elems->link_id = pos;
324 case WLAN_EID_INTERWORKING:
325 elems->interworking = pos;
326 elems->interworking_len = elen;
328 case WLAN_EID_QOS_MAP_SET:
331 elems->qos_map_set = pos;
332 elems->qos_map_set_len = elen;
334 case WLAN_EID_EXT_CAPAB:
335 elems->ext_capab = pos;
336 elems->ext_capab_len = elen;
338 case WLAN_EID_BSS_MAX_IDLE_PERIOD:
341 elems->bss_max_idle_period = pos;
343 case WLAN_EID_SSID_LIST:
344 elems->ssid_list = pos;
345 elems->ssid_list_len = elen;
349 elems->ampe_len = elen;
353 elems->mic_len = elen;
354 /* after mic everything is encrypted, so stop. */
357 case WLAN_EID_MULTI_BAND:
358 if (elems->mb_ies.nof_ies >= MAX_NOF_MB_IES_SUPPORTED) {
359 wpa_printf(MSG_MSGDUMP,
360 "IEEE 802.11 element parse ignored MB IE (id=%d elen=%d)",
365 elems->mb_ies.ies[elems->mb_ies.nof_ies].ie = pos;
366 elems->mb_ies.ies[elems->mb_ies.nof_ies].ie_len = elen;
367 elems->mb_ies.nof_ies++;
373 wpa_printf(MSG_MSGDUMP, "IEEE 802.11 element parse "
374 "ignored unknown element (id=%d elen=%d)",
386 return unknown ? ParseUnknown : ParseOK;
390 int ieee802_11_ie_count(const u8 *ies, size_t ies_len)
401 while (pos + 2 <= end) {
402 if (pos + 2 + pos[1] > end)
412 struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len,
416 const u8 *end, *pos, *ie;
422 while (pos + 1 < end) {
423 if (pos + 2 + pos[1] > end)
425 if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
426 WPA_GET_BE32(&pos[2]) == oui_type) {
434 return NULL; /* No specified vendor IE found */
436 buf = wpabuf_alloc(ies_len);
441 * There may be multiple vendor IEs in the message, so need to
442 * concatenate their data fields.
444 while (pos + 1 < end) {
445 if (pos + 2 + pos[1] > end)
447 if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
448 WPA_GET_BE32(&pos[2]) == oui_type)
449 wpabuf_put_data(buf, pos + 6, pos[1] - 4);
457 const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len)
462 * PS-Poll frames are 16 bytes. All other frames are
463 * 24 bytes or longer.
468 fc = le_to_host16(hdr->frame_control);
469 type = WLAN_FC_GET_TYPE(fc);
470 stype = WLAN_FC_GET_STYPE(fc);
473 case WLAN_FC_TYPE_DATA:
476 switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
477 case WLAN_FC_FROMDS | WLAN_FC_TODS:
485 case WLAN_FC_TYPE_CTRL:
486 if (stype != WLAN_FC_STYPE_PSPOLL)
489 case WLAN_FC_TYPE_MGMT:
497 int hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[],
498 const char *name, const char *val)
502 struct hostapd_wmm_ac_params *ac;
504 /* skip 'wme_ac_' or 'wmm_ac_' prefix */
506 if (os_strncmp(pos, "be_", 3) == 0) {
509 } else if (os_strncmp(pos, "bk_", 3) == 0) {
512 } else if (os_strncmp(pos, "vi_", 3) == 0) {
515 } else if (os_strncmp(pos, "vo_", 3) == 0) {
519 wpa_printf(MSG_ERROR, "Unknown WMM name '%s'", pos);
523 ac = &wmm_ac_params[num];
525 if (os_strcmp(pos, "aifs") == 0) {
527 if (v < 1 || v > 255) {
528 wpa_printf(MSG_ERROR, "Invalid AIFS value %d", v);
532 } else if (os_strcmp(pos, "cwmin") == 0) {
534 if (v < 0 || v > 15) {
535 wpa_printf(MSG_ERROR, "Invalid cwMin value %d", v);
539 } else if (os_strcmp(pos, "cwmax") == 0) {
541 if (v < 0 || v > 15) {
542 wpa_printf(MSG_ERROR, "Invalid cwMax value %d", v);
546 } else if (os_strcmp(pos, "txop_limit") == 0) {
548 if (v < 0 || v > 0xffff) {
549 wpa_printf(MSG_ERROR, "Invalid txop value %d", v);
553 } else if (os_strcmp(pos, "acm") == 0) {
555 if (v < 0 || v > 1) {
556 wpa_printf(MSG_ERROR, "Invalid acm value %d", v);
559 ac->admission_control_mandatory = v;
561 wpa_printf(MSG_ERROR, "Unknown wmm_ac_ field '%s'", pos);
569 enum hostapd_hw_mode ieee80211_freq_to_chan(int freq, u8 *channel)
573 return ieee80211_freq_to_channel_ext(freq, 0, 0, &op_class, channel);
578 * ieee80211_freq_to_channel_ext - Convert frequency into channel info
579 * for HT40 and VHT. DFS channels are not covered.
580 * @freq: Frequency (MHz) to convert
581 * @sec_channel: 0 = non-HT40, 1 = sec. channel above, -1 = sec. channel below
582 * @vht: 0 - non-VHT, 1 - 80 MHz
583 * @op_class: Buffer for returning operating class
584 * @channel: Buffer for returning channel number
585 * Returns: hw_mode on success, NUM_HOSTAPD_MODES on failure
587 enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
588 int sec_channel, int vht,
589 u8 *op_class, u8 *channel)
591 /* TODO: more operating classes */
593 if (sec_channel > 1 || sec_channel < -1)
594 return NUM_HOSTAPD_MODES;
596 if (freq >= 2412 && freq <= 2472) {
597 if ((freq - 2407) % 5)
598 return NUM_HOSTAPD_MODES;
601 return NUM_HOSTAPD_MODES;
603 /* 2.407 GHz, channels 1..13 */
604 if (sec_channel == 1)
606 else if (sec_channel == -1)
611 *channel = (freq - 2407) / 5;
613 return HOSTAPD_MODE_IEEE80211G;
617 if (sec_channel || vht)
618 return NUM_HOSTAPD_MODES;
620 *op_class = 82; /* channel 14 */
623 return HOSTAPD_MODE_IEEE80211B;
626 if (freq >= 4900 && freq < 5000) {
627 if ((freq - 4000) % 5)
628 return NUM_HOSTAPD_MODES;
629 *channel = (freq - 4000) / 5;
630 *op_class = 0; /* TODO */
631 return HOSTAPD_MODE_IEEE80211A;
634 /* 5 GHz, channels 36..48 */
635 if (freq >= 5180 && freq <= 5240) {
636 if ((freq - 5000) % 5)
637 return NUM_HOSTAPD_MODES;
639 if (sec_channel == 1)
641 else if (sec_channel == -1)
648 *channel = (freq - 5000) / 5;
650 return HOSTAPD_MODE_IEEE80211A;
653 /* 5 GHz, channels 149..161 */
654 if (freq >= 5745 && freq <= 5805) {
655 if ((freq - 5000) % 5)
656 return NUM_HOSTAPD_MODES;
658 if (sec_channel == 1)
660 else if (sec_channel == -1)
667 *channel = (freq - 5000) / 5;
669 return HOSTAPD_MODE_IEEE80211A;
672 /* 5 GHz, channels 149..169 */
673 if (freq >= 5745 && freq <= 5845) {
674 if ((freq - 5000) % 5)
675 return NUM_HOSTAPD_MODES;
679 *channel = (freq - 5000) / 5;
681 return HOSTAPD_MODE_IEEE80211A;
684 if (freq >= 5000 && freq < 5900) {
685 if ((freq - 5000) % 5)
686 return NUM_HOSTAPD_MODES;
687 *channel = (freq - 5000) / 5;
688 *op_class = 0; /* TODO */
689 return HOSTAPD_MODE_IEEE80211A;
692 /* 56.16 GHz, channel 1..4 */
693 if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 4) {
694 if (sec_channel || vht)
695 return NUM_HOSTAPD_MODES;
697 *channel = (freq - 56160) / 2160;
700 return HOSTAPD_MODE_IEEE80211AD;
703 return NUM_HOSTAPD_MODES;
707 static const char *const us_op_class_cc[] = {
711 static const char *const eu_op_class_cc[] = {
712 "AL", "AM", "AT", "AZ", "BA", "BE", "BG", "BY", "CH", "CY", "CZ", "DE",
713 "DK", "EE", "EL", "ES", "FI", "FR", "GE", "HR", "HU", "IE", "IS", "IT",
714 "LI", "LT", "LU", "LV", "MD", "ME", "MK", "MT", "NL", "NO", "PL", "PT",
715 "RO", "RS", "RU", "SE", "SI", "SK", "TR", "UA", "UK", NULL
718 static const char *const jp_op_class_cc[] = {
722 static const char *const cn_op_class_cc[] = {
727 static int country_match(const char *const cc[], const char *const country)
733 for (i = 0; cc[i]; i++) {
734 if (cc[i][0] == country[0] && cc[i][1] == country[1])
742 static int ieee80211_chan_to_freq_us(u8 op_class, u8 chan)
745 case 12: /* channels 1..11 */
746 case 32: /* channels 1..7; 40 MHz */
747 case 33: /* channels 5..11; 40 MHz */
748 if (chan < 1 || chan > 11)
750 return 2407 + 5 * chan;
751 case 1: /* channels 36,40,44,48 */
752 case 2: /* channels 52,56,60,64; dfs */
753 case 22: /* channels 36,44; 40 MHz */
754 case 23: /* channels 52,60; 40 MHz */
755 case 27: /* channels 40,48; 40 MHz */
756 case 28: /* channels 56,64; 40 MHz */
757 if (chan < 36 || chan > 64)
759 return 5000 + 5 * chan;
760 case 4: /* channels 100-144 */
761 case 24: /* channels 100-140; 40 MHz */
762 if (chan < 100 || chan > 144)
764 return 5000 + 5 * chan;
765 case 3: /* channels 149,153,157,161 */
766 case 25: /* channels 149,157; 40 MHz */
767 case 26: /* channels 149,157; 40 MHz */
768 case 30: /* channels 153,161; 40 MHz */
769 case 31: /* channels 153,161; 40 MHz */
770 if (chan < 149 || chan > 161)
772 return 5000 + 5 * chan;
773 case 5: /* channels 149,153,157,161,165 */
774 if (chan < 149 || chan > 165)
776 return 5000 + 5 * chan;
777 case 34: /* 60 GHz band, channels 1..3 */
778 if (chan < 1 || chan > 3)
780 return 56160 + 2160 * chan;
786 static int ieee80211_chan_to_freq_eu(u8 op_class, u8 chan)
789 case 4: /* channels 1..13 */
790 case 11: /* channels 1..9; 40 MHz */
791 case 12: /* channels 5..13; 40 MHz */
792 if (chan < 1 || chan > 13)
794 return 2407 + 5 * chan;
795 case 1: /* channels 36,40,44,48 */
796 case 2: /* channels 52,56,60,64; dfs */
797 case 5: /* channels 36,44; 40 MHz */
798 case 6: /* channels 52,60; 40 MHz */
799 case 8: /* channels 40,48; 40 MHz */
800 case 9: /* channels 56,64; 40 MHz */
801 if (chan < 36 || chan > 64)
803 return 5000 + 5 * chan;
804 case 3: /* channels 100-140 */
805 case 7: /* channels 100-132; 40 MHz */
806 case 10: /* channels 104-136; 40 MHz */
807 case 16: /* channels 100-140 */
808 if (chan < 100 || chan > 140)
810 return 5000 + 5 * chan;
811 case 17: /* channels 149,153,157,161,165,169 */
812 if (chan < 149 || chan > 169)
814 return 5000 + 5 * chan;
815 case 18: /* 60 GHz band, channels 1..4 */
816 if (chan < 1 || chan > 4)
818 return 56160 + 2160 * chan;
824 static int ieee80211_chan_to_freq_jp(u8 op_class, u8 chan)
827 case 30: /* channels 1..13 */
828 case 56: /* channels 1..9; 40 MHz */
829 case 57: /* channels 5..13; 40 MHz */
830 if (chan < 1 || chan > 13)
832 return 2407 + 5 * chan;
833 case 31: /* channel 14 */
836 return 2414 + 5 * chan;
837 case 1: /* channels 34,38,42,46(old) or 36,40,44,48 */
838 case 32: /* channels 52,56,60,64 */
839 case 33: /* channels 52,56,60,64 */
840 case 36: /* channels 36,44; 40 MHz */
841 case 37: /* channels 52,60; 40 MHz */
842 case 38: /* channels 52,60; 40 MHz */
843 case 41: /* channels 40,48; 40 MHz */
844 case 42: /* channels 56,64; 40 MHz */
845 case 43: /* channels 56,64; 40 MHz */
846 if (chan < 34 || chan > 64)
848 return 5000 + 5 * chan;
849 case 34: /* channels 100-140 */
850 case 35: /* channels 100-140 */
851 case 39: /* channels 100-132; 40 MHz */
852 case 40: /* channels 100-132; 40 MHz */
853 case 44: /* channels 104-136; 40 MHz */
854 case 45: /* channels 104-136; 40 MHz */
855 case 58: /* channels 100-140 */
856 if (chan < 100 || chan > 140)
858 return 5000 + 5 * chan;
859 case 59: /* 60 GHz band, channels 1..4 */
860 if (chan < 1 || chan > 3)
862 return 56160 + 2160 * chan;
868 static int ieee80211_chan_to_freq_cn(u8 op_class, u8 chan)
871 case 7: /* channels 1..13 */
872 case 8: /* channels 1..9; 40 MHz */
873 case 9: /* channels 5..13; 40 MHz */
874 if (chan < 1 || chan > 13)
876 return 2407 + 5 * chan;
877 case 1: /* channels 36,40,44,48 */
878 case 2: /* channels 52,56,60,64; dfs */
879 case 4: /* channels 36,44; 40 MHz */
880 case 5: /* channels 52,60; 40 MHz */
881 if (chan < 36 || chan > 64)
883 return 5000 + 5 * chan;
884 case 3: /* channels 149,153,157,161,165 */
885 case 6: /* channels 149,157; 40 MHz */
886 if (chan < 149 || chan > 165)
888 return 5000 + 5 * chan;
894 static int ieee80211_chan_to_freq_global(u8 op_class, u8 chan)
896 /* Table E-4 in IEEE Std 802.11-2012 - Global operating classes */
900 if (chan < 1 || chan > 13)
902 return 2407 + 5 * chan;
907 return 2414 + 5 * chan;
908 case 83: /* channels 1..9; 40 MHz */
909 case 84: /* channels 5..13; 40 MHz */
910 if (chan < 1 || chan > 13)
912 return 2407 + 5 * chan;
913 case 115: /* channels 36,40,44,48; indoor only */
914 case 116: /* channels 36,44; 40 MHz; indoor only */
915 case 117: /* channels 40,48; 40 MHz; indoor only */
916 case 118: /* channels 52,56,60,64; dfs */
917 case 119: /* channels 52,60; 40 MHz; dfs */
918 case 120: /* channels 56,64; 40 MHz; dfs */
919 if (chan < 36 || chan > 64)
921 return 5000 + 5 * chan;
922 case 121: /* channels 100-140 */
923 case 122: /* channels 100-142; 40 MHz */
924 case 123: /* channels 104-136; 40 MHz */
925 if (chan < 100 || chan > 140)
927 return 5000 + 5 * chan;
928 case 124: /* channels 149,153,157,161 */
929 case 126: /* channels 149,157; 40 MHz */
930 case 127: /* channels 153,161; 40 MHz */
931 if (chan < 149 || chan > 161)
933 return 5000 + 5 * chan;
934 case 125: /* channels 149,153,157,161,165,169 */
935 if (chan < 149 || chan > 169)
937 return 5000 + 5 * chan;
938 case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
939 case 130: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
940 if (chan < 36 || chan > 161)
942 return 5000 + 5 * chan;
943 case 129: /* center freqs 50, 114; 160 MHz */
944 if (chan < 50 || chan > 114)
946 return 5000 + 5 * chan;
947 case 180: /* 60 GHz band, channels 1..4 */
948 if (chan < 1 || chan > 4)
950 return 56160 + 2160 * chan;
956 * ieee80211_chan_to_freq - Convert channel info to frequency
957 * @country: Country code, if known; otherwise, global operating class is used
958 * @op_class: Operating class
959 * @chan: Channel number
960 * Returns: Frequency in MHz or -1 if the specified channel is unknown
962 int ieee80211_chan_to_freq(const char *country, u8 op_class, u8 chan)
966 if (country_match(us_op_class_cc, country)) {
967 freq = ieee80211_chan_to_freq_us(op_class, chan);
972 if (country_match(eu_op_class_cc, country)) {
973 freq = ieee80211_chan_to_freq_eu(op_class, chan);
978 if (country_match(jp_op_class_cc, country)) {
979 freq = ieee80211_chan_to_freq_jp(op_class, chan);
984 if (country_match(cn_op_class_cc, country)) {
985 freq = ieee80211_chan_to_freq_cn(op_class, chan);
990 return ieee80211_chan_to_freq_global(op_class, chan);
994 int ieee80211_is_dfs(int freq)
996 /* TODO: this could be more accurate to better cover all domains */
997 return (freq >= 5260 && freq <= 5320) || (freq >= 5500 && freq <= 5700);
1001 static int is_11b(u8 rate)
1003 return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16;
1007 int supp_rates_11b_only(struct ieee802_11_elems *elems)
1009 int num_11b = 0, num_others = 0;
1012 if (elems->supp_rates == NULL && elems->ext_supp_rates == NULL)
1015 for (i = 0; elems->supp_rates && i < elems->supp_rates_len; i++) {
1016 if (is_11b(elems->supp_rates[i]))
1022 for (i = 0; elems->ext_supp_rates && i < elems->ext_supp_rates_len;
1024 if (is_11b(elems->ext_supp_rates[i]))
1030 return num_11b > 0 && num_others == 0;
1034 const char * fc2str(u16 fc)
1036 u16 stype = WLAN_FC_GET_STYPE(fc);
1037 #define C2S(x) case x: return #x;
1039 switch (WLAN_FC_GET_TYPE(fc)) {
1040 case WLAN_FC_TYPE_MGMT:
1042 C2S(WLAN_FC_STYPE_ASSOC_REQ)
1043 C2S(WLAN_FC_STYPE_ASSOC_RESP)
1044 C2S(WLAN_FC_STYPE_REASSOC_REQ)
1045 C2S(WLAN_FC_STYPE_REASSOC_RESP)
1046 C2S(WLAN_FC_STYPE_PROBE_REQ)
1047 C2S(WLAN_FC_STYPE_PROBE_RESP)
1048 C2S(WLAN_FC_STYPE_BEACON)
1049 C2S(WLAN_FC_STYPE_ATIM)
1050 C2S(WLAN_FC_STYPE_DISASSOC)
1051 C2S(WLAN_FC_STYPE_AUTH)
1052 C2S(WLAN_FC_STYPE_DEAUTH)
1053 C2S(WLAN_FC_STYPE_ACTION)
1056 case WLAN_FC_TYPE_CTRL:
1058 C2S(WLAN_FC_STYPE_PSPOLL)
1059 C2S(WLAN_FC_STYPE_RTS)
1060 C2S(WLAN_FC_STYPE_CTS)
1061 C2S(WLAN_FC_STYPE_ACK)
1062 C2S(WLAN_FC_STYPE_CFEND)
1063 C2S(WLAN_FC_STYPE_CFENDACK)
1066 case WLAN_FC_TYPE_DATA:
1068 C2S(WLAN_FC_STYPE_DATA)
1069 C2S(WLAN_FC_STYPE_DATA_CFACK)
1070 C2S(WLAN_FC_STYPE_DATA_CFPOLL)
1071 C2S(WLAN_FC_STYPE_DATA_CFACKPOLL)
1072 C2S(WLAN_FC_STYPE_NULLFUNC)
1073 C2S(WLAN_FC_STYPE_CFACK)
1074 C2S(WLAN_FC_STYPE_CFPOLL)
1075 C2S(WLAN_FC_STYPE_CFACKPOLL)
1076 C2S(WLAN_FC_STYPE_QOS_DATA)
1077 C2S(WLAN_FC_STYPE_QOS_DATA_CFACK)
1078 C2S(WLAN_FC_STYPE_QOS_DATA_CFPOLL)
1079 C2S(WLAN_FC_STYPE_QOS_DATA_CFACKPOLL)
1080 C2S(WLAN_FC_STYPE_QOS_NULL)
1081 C2S(WLAN_FC_STYPE_QOS_CFPOLL)
1082 C2S(WLAN_FC_STYPE_QOS_CFACKPOLL)
1086 return "WLAN_FC_TYPE_UNKNOWN";
1091 int mb_ies_info_by_ies(struct mb_ies_info *info, const u8 *ies_buf,
1094 os_memset(info, 0, sizeof(*info));
1096 while (ies_buf && ies_len >= 2 &&
1097 info->nof_ies < MAX_NOF_MB_IES_SUPPORTED) {
1098 size_t len = 2 + ies_buf[1];
1100 if (len > ies_len) {
1101 wpa_hexdump(MSG_DEBUG, "Truncated IEs",
1106 if (ies_buf[0] == WLAN_EID_MULTI_BAND) {
1107 wpa_printf(MSG_DEBUG, "MB IE of %zu bytes found", len);
1108 info->ies[info->nof_ies].ie = ies_buf + 2;
1109 info->ies[info->nof_ies].ie_len = ies_buf[1];
1121 struct wpabuf * mb_ies_by_info(struct mb_ies_info *info)
1123 struct wpabuf *mb_ies = NULL;
1125 WPA_ASSERT(info != NULL);
1127 if (info->nof_ies) {
1129 size_t mb_ies_size = 0;
1131 for (i = 0; i < info->nof_ies; i++)
1132 mb_ies_size += 2 + info->ies[i].ie_len;
1134 mb_ies = wpabuf_alloc(mb_ies_size);
1136 for (i = 0; i < info->nof_ies; i++) {
1137 wpabuf_put_u8(mb_ies, WLAN_EID_MULTI_BAND);
1138 wpabuf_put_u8(mb_ies, info->ies[i].ie_len);
1139 wpabuf_put_data(mb_ies,
1141 info->ies[i].ie_len);