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 /* OWE Transition Mode element */
137 wpa_printf(MSG_MSGDUMP
, "Unknown WFA "
138 "information element ignored "
140 pos
[3], (unsigned long) elen
);
147 case VENDOR_HT_CAPAB_OUI_TYPE
:
148 elems
->vendor_ht_cap
= pos
;
149 elems
->vendor_ht_cap_len
= elen
;
151 case VENDOR_VHT_TYPE
:
153 (pos
[4] == VENDOR_VHT_SUBTYPE
||
154 pos
[4] == VENDOR_VHT_SUBTYPE2
)) {
155 elems
->vendor_vht
= pos
;
156 elems
->vendor_vht_len
= elen
;
161 wpa_printf(MSG_EXCESSIVE
, "Unknown Broadcom "
162 "information element ignored "
164 pos
[3], (unsigned long) elen
);
171 case QCA_VENDOR_ELEM_P2P_PREF_CHAN_LIST
:
172 elems
->pref_freq_list
= pos
;
173 elems
->pref_freq_list_len
= elen
;
176 wpa_printf(MSG_EXCESSIVE
,
177 "Unknown QCA information element ignored (type=%d len=%lu)",
178 pos
[3], (unsigned long) elen
);
184 wpa_printf(MSG_EXCESSIVE
, "unknown vendor specific "
185 "information element ignored (vendor OUI "
186 "%02x:%02x:%02x len=%lu)",
187 pos
[0], pos
[1], pos
[2], (unsigned long) elen
);
195 static int ieee802_11_parse_extension(const u8
*pos
, size_t elen
,
196 struct ieee802_11_elems
*elems
,
203 wpa_printf(MSG_MSGDUMP
,
204 "short information element (Ext)");
212 elems
->frag_ies
.last_eid_ext
= 0;
215 case WLAN_EID_EXT_ASSOC_DELAY_INFO
:
218 elems
->assoc_delay_info
= pos
;
220 case WLAN_EID_EXT_FILS_REQ_PARAMS
:
223 elems
->fils_req_params
= pos
;
224 elems
->fils_req_params_len
= elen
;
226 case WLAN_EID_EXT_FILS_KEY_CONFIRM
:
227 elems
->fils_key_confirm
= pos
;
228 elems
->fils_key_confirm_len
= elen
;
230 case WLAN_EID_EXT_FILS_SESSION
:
231 if (elen
!= FILS_SESSION_LEN
)
233 elems
->fils_session
= pos
;
235 case WLAN_EID_EXT_FILS_HLP_CONTAINER
:
236 if (elen
< 2 * ETH_ALEN
)
238 elems
->fils_hlp
= pos
;
239 elems
->fils_hlp_len
= elen
;
241 case WLAN_EID_EXT_FILS_IP_ADDR_ASSIGN
:
244 elems
->fils_ip_addr_assign
= pos
;
245 elems
->fils_ip_addr_assign_len
= elen
;
247 case WLAN_EID_EXT_KEY_DELIVERY
:
248 if (elen
< WPA_KEY_RSC_LEN
)
250 elems
->key_delivery
= pos
;
251 elems
->key_delivery_len
= elen
;
253 case WLAN_EID_EXT_WRAPPED_DATA
:
254 elems
->wrapped_data
= pos
;
255 elems
->wrapped_data_len
= elen
;
257 case WLAN_EID_EXT_FILS_PUBLIC_KEY
:
260 elems
->fils_pk
= pos
;
261 elems
->fils_pk_len
= elen
;
263 case WLAN_EID_EXT_FILS_NONCE
:
264 if (elen
!= FILS_NONCE_LEN
)
266 elems
->fils_nonce
= pos
;
268 case WLAN_EID_EXT_OWE_DH_PARAM
:
272 elems
->owe_dh_len
= elen
;
274 case WLAN_EID_EXT_PASSWORD_IDENTIFIER
:
275 elems
->password_id
= pos
;
276 elems
->password_id_len
= elen
;
278 case WLAN_EID_EXT_HE_CAPABILITIES
:
279 elems
->he_capabilities
= pos
;
280 elems
->he_capabilities_len
= elen
;
282 case WLAN_EID_EXT_HE_OPERATION
:
283 elems
->he_operation
= pos
;
284 elems
->he_operation_len
= elen
;
286 case WLAN_EID_EXT_OCV_OCI
:
288 elems
->oci_len
= elen
;
290 case WLAN_EID_EXT_SHORT_SSID_LIST
:
291 elems
->short_ssid_list
= pos
;
292 elems
->short_ssid_list_len
= elen
;
296 wpa_printf(MSG_MSGDUMP
,
297 "IEEE 802.11 element parsing ignored unknown element extension (ext_id=%u elen=%u)",
298 ext_id
, (unsigned int) elen
);
304 elems
->frag_ies
.last_eid_ext
= ext_id
;
310 static void ieee802_11_parse_fragment(struct frag_ies_info
*frag_ies
,
311 const u8
*pos
, u8 elen
)
313 if (frag_ies
->n_frags
>= MAX_NUM_FRAG_IES_SUPPORTED
) {
314 wpa_printf(MSG_MSGDUMP
, "Too many element fragments - skip");
319 * Note: while EID == 0 is a valid ID (SSID IE), it should not be
322 if (!frag_ies
->last_eid
) {
323 wpa_printf(MSG_MSGDUMP
,
324 "Fragment without a valid last element - skip");
328 frag_ies
->frags
[frag_ies
->n_frags
].ie
= pos
;
329 frag_ies
->frags
[frag_ies
->n_frags
].ie_len
= elen
;
330 frag_ies
->frags
[frag_ies
->n_frags
].eid
= frag_ies
->last_eid
;
331 frag_ies
->frags
[frag_ies
->n_frags
].eid_ext
= frag_ies
->last_eid_ext
;
337 * ieee802_11_parse_elems - Parse information elements in management frames
338 * @start: Pointer to the start of IEs
339 * @len: Length of IE buffer in octets
340 * @elems: Data structure for parsed elements
341 * @show_errors: Whether to show parsing errors in debug log
342 * Returns: Parsing result
344 ParseRes
ieee802_11_parse_elems(const u8
*start
, size_t len
,
345 struct ieee802_11_elems
*elems
,
348 const struct element
*elem
;
351 os_memset(elems
, 0, sizeof(*elems
));
356 for_each_element(elem
, start
, len
) {
357 u8 id
= elem
->id
, elen
= elem
->datalen
;
358 const u8
*pos
= elem
->data
;
362 if (elen
> SSID_MAX_LEN
) {
363 wpa_printf(MSG_DEBUG
,
364 "Ignored too long SSID element (elen=%u)",
369 elems
->ssid_len
= elen
;
371 case WLAN_EID_SUPP_RATES
:
372 elems
->supp_rates
= pos
;
373 elems
->supp_rates_len
= elen
;
375 case WLAN_EID_DS_PARAMS
:
378 elems
->ds_params
= pos
;
380 case WLAN_EID_CF_PARAMS
:
383 case WLAN_EID_CHALLENGE
:
384 elems
->challenge
= pos
;
385 elems
->challenge_len
= elen
;
387 case WLAN_EID_ERP_INFO
:
390 elems
->erp_info
= pos
;
392 case WLAN_EID_EXT_SUPP_RATES
:
393 elems
->ext_supp_rates
= pos
;
394 elems
->ext_supp_rates_len
= elen
;
396 case WLAN_EID_VENDOR_SPECIFIC
:
397 if (ieee802_11_parse_vendor_specific(pos
, elen
,
404 elems
->rsn_ie_len
= elen
;
408 elems
->rsnxe_len
= elen
;
410 case WLAN_EID_PWR_CAPABILITY
:
413 elems
->power_capab
= pos
;
414 elems
->power_capab_len
= elen
;
416 case WLAN_EID_SUPPORTED_CHANNELS
:
417 elems
->supp_channels
= pos
;
418 elems
->supp_channels_len
= elen
;
420 case WLAN_EID_MOBILITY_DOMAIN
:
421 if (elen
< sizeof(struct rsn_mdie
))
424 elems
->mdie_len
= elen
;
426 case WLAN_EID_FAST_BSS_TRANSITION
:
427 if (elen
< sizeof(struct rsn_ftie
))
430 elems
->ftie_len
= elen
;
432 case WLAN_EID_TIMEOUT_INTERVAL
:
435 elems
->timeout_int
= pos
;
437 case WLAN_EID_HT_CAP
:
438 if (elen
< sizeof(struct ieee80211_ht_capabilities
))
440 elems
->ht_capabilities
= pos
;
442 case WLAN_EID_HT_OPERATION
:
443 if (elen
< sizeof(struct ieee80211_ht_operation
))
445 elems
->ht_operation
= pos
;
447 case WLAN_EID_MESH_CONFIG
:
448 elems
->mesh_config
= pos
;
449 elems
->mesh_config_len
= elen
;
451 case WLAN_EID_MESH_ID
:
452 elems
->mesh_id
= pos
;
453 elems
->mesh_id_len
= elen
;
455 case WLAN_EID_PEER_MGMT
:
456 elems
->peer_mgmt
= pos
;
457 elems
->peer_mgmt_len
= elen
;
459 case WLAN_EID_VHT_CAP
:
460 if (elen
< sizeof(struct ieee80211_vht_capabilities
))
462 elems
->vht_capabilities
= pos
;
464 case WLAN_EID_VHT_OPERATION
:
465 if (elen
< sizeof(struct ieee80211_vht_operation
))
467 elems
->vht_operation
= pos
;
469 case WLAN_EID_VHT_OPERATING_MODE_NOTIFICATION
:
472 elems
->vht_opmode_notif
= pos
;
474 case WLAN_EID_LINK_ID
:
477 elems
->link_id
= pos
;
479 case WLAN_EID_INTERWORKING
:
480 elems
->interworking
= pos
;
481 elems
->interworking_len
= elen
;
483 case WLAN_EID_QOS_MAP_SET
:
486 elems
->qos_map_set
= pos
;
487 elems
->qos_map_set_len
= elen
;
489 case WLAN_EID_EXT_CAPAB
:
490 elems
->ext_capab
= pos
;
491 elems
->ext_capab_len
= elen
;
493 case WLAN_EID_BSS_MAX_IDLE_PERIOD
:
496 elems
->bss_max_idle_period
= pos
;
498 case WLAN_EID_SSID_LIST
:
499 elems
->ssid_list
= pos
;
500 elems
->ssid_list_len
= elen
;
504 elems
->ampe_len
= elen
;
508 elems
->mic_len
= elen
;
509 /* after mic everything is encrypted, so stop. */
511 case WLAN_EID_MULTI_BAND
:
512 if (elems
->mb_ies
.nof_ies
>= MAX_NOF_MB_IES_SUPPORTED
) {
513 wpa_printf(MSG_MSGDUMP
,
514 "IEEE 802.11 element parse ignored MB IE (id=%d elen=%d)",
519 elems
->mb_ies
.ies
[elems
->mb_ies
.nof_ies
].ie
= pos
;
520 elems
->mb_ies
.ies
[elems
->mb_ies
.nof_ies
].ie_len
= elen
;
521 elems
->mb_ies
.nof_ies
++;
523 case WLAN_EID_SUPPORTED_OPERATING_CLASSES
:
524 elems
->supp_op_classes
= pos
;
525 elems
->supp_op_classes_len
= elen
;
527 case WLAN_EID_RRM_ENABLED_CAPABILITIES
:
528 elems
->rrm_enabled
= pos
;
529 elems
->rrm_enabled_len
= elen
;
531 case WLAN_EID_CAG_NUMBER
:
532 elems
->cag_number
= pos
;
533 elems
->cag_number_len
= elen
;
535 case WLAN_EID_AP_CSN
:
540 case WLAN_EID_FILS_INDICATION
:
543 elems
->fils_indic
= pos
;
544 elems
->fils_indic_len
= elen
;
550 elems
->dils_len
= elen
;
552 case WLAN_EID_FRAGMENT
:
553 ieee802_11_parse_fragment(&elems
->frag_ies
, pos
, elen
);
555 case WLAN_EID_EXTENSION
:
556 if (ieee802_11_parse_extension(pos
, elen
, elems
,
564 wpa_printf(MSG_MSGDUMP
, "IEEE 802.11 element parse "
565 "ignored unknown element (id=%d elen=%d)",
570 if (id
!= WLAN_EID_FRAGMENT
&& elen
== 255)
571 elems
->frag_ies
.last_eid
= id
;
573 if (id
== WLAN_EID_EXTENSION
&& !elems
->frag_ies
.last_eid_ext
)
574 elems
->frag_ies
.last_eid
= 0;
577 if (!for_each_element_completed(elem
, start
, len
)) {
579 wpa_printf(MSG_DEBUG
,
580 "IEEE 802.11 element parse failed @%d",
581 (int) (start
+ len
- (const u8
*) elem
));
582 wpa_hexdump(MSG_MSGDUMP
, "IEs", start
, len
);
588 return unknown
? ParseUnknown
: ParseOK
;
592 int ieee802_11_ie_count(const u8
*ies
, size_t ies_len
)
594 const struct element
*elem
;
600 for_each_element(elem
, ies
, ies_len
)
607 struct wpabuf
* ieee802_11_vendor_ie_concat(const u8
*ies
, size_t ies_len
,
611 const struct element
*elem
, *found
= NULL
;
613 for_each_element_id(elem
, WLAN_EID_VENDOR_SPECIFIC
, ies
, ies_len
) {
614 if (elem
->datalen
>= 4 &&
615 WPA_GET_BE32(elem
->data
) == oui_type
) {
622 return NULL
; /* No specified vendor IE found */
624 buf
= wpabuf_alloc(ies_len
);
629 * There may be multiple vendor IEs in the message, so need to
630 * concatenate their data fields.
632 for_each_element_id(elem
, WLAN_EID_VENDOR_SPECIFIC
, ies
, ies_len
) {
633 if (elem
->datalen
>= 4 && WPA_GET_BE32(elem
->data
) == oui_type
)
634 wpabuf_put_data(buf
, elem
->data
+ 4, elem
->datalen
- 4);
641 const u8
* get_hdr_bssid(const struct ieee80211_hdr
*hdr
, size_t len
)
646 * PS-Poll frames are 16 bytes. All other frames are
647 * 24 bytes or longer.
652 fc
= le_to_host16(hdr
->frame_control
);
653 type
= WLAN_FC_GET_TYPE(fc
);
654 stype
= WLAN_FC_GET_STYPE(fc
);
657 case WLAN_FC_TYPE_DATA
:
660 switch (fc
& (WLAN_FC_FROMDS
| WLAN_FC_TODS
)) {
661 case WLAN_FC_FROMDS
| WLAN_FC_TODS
:
669 case WLAN_FC_TYPE_CTRL
:
670 if (stype
!= WLAN_FC_STYPE_PSPOLL
)
673 case WLAN_FC_TYPE_MGMT
:
681 int hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params
[],
682 const char *name
, const char *val
)
686 struct hostapd_wmm_ac_params
*ac
;
688 /* skip 'wme_ac_' or 'wmm_ac_' prefix */
690 if (os_strncmp(pos
, "be_", 3) == 0) {
693 } else if (os_strncmp(pos
, "bk_", 3) == 0) {
696 } else if (os_strncmp(pos
, "vi_", 3) == 0) {
699 } else if (os_strncmp(pos
, "vo_", 3) == 0) {
703 wpa_printf(MSG_ERROR
, "Unknown WMM name '%s'", pos
);
707 ac
= &wmm_ac_params
[num
];
709 if (os_strcmp(pos
, "aifs") == 0) {
711 if (v
< 1 || v
> 255) {
712 wpa_printf(MSG_ERROR
, "Invalid AIFS value %d", v
);
716 } else if (os_strcmp(pos
, "cwmin") == 0) {
718 if (v
< 0 || v
> 15) {
719 wpa_printf(MSG_ERROR
, "Invalid cwMin value %d", v
);
723 } else if (os_strcmp(pos
, "cwmax") == 0) {
725 if (v
< 0 || v
> 15) {
726 wpa_printf(MSG_ERROR
, "Invalid cwMax value %d", v
);
730 } else if (os_strcmp(pos
, "txop_limit") == 0) {
732 if (v
< 0 || v
> 0xffff) {
733 wpa_printf(MSG_ERROR
, "Invalid txop value %d", v
);
737 } else if (os_strcmp(pos
, "acm") == 0) {
739 if (v
< 0 || v
> 1) {
740 wpa_printf(MSG_ERROR
, "Invalid acm value %d", v
);
743 ac
->admission_control_mandatory
= v
;
745 wpa_printf(MSG_ERROR
, "Unknown wmm_ac_ field '%s'", pos
);
753 enum hostapd_hw_mode
ieee80211_freq_to_chan(int freq
, u8
*channel
)
757 return ieee80211_freq_to_channel_ext(freq
, 0, CHANWIDTH_USE_HT
,
763 * ieee80211_freq_to_channel_ext - Convert frequency into channel info
764 * for HT40 and VHT. DFS channels are not covered.
765 * @freq: Frequency (MHz) to convert
766 * @sec_channel: 0 = non-HT40, 1 = sec. channel above, -1 = sec. channel below
767 * @chanwidth: VHT/EDMG channel width (CHANWIDTH_*)
768 * @op_class: Buffer for returning operating class
769 * @channel: Buffer for returning channel number
770 * Returns: hw_mode on success, NUM_HOSTAPD_MODES on failure
772 enum hostapd_hw_mode
ieee80211_freq_to_channel_ext(unsigned int freq
,
775 u8
*op_class
, u8
*channel
)
779 /* TODO: more operating classes */
781 if (sec_channel
> 1 || sec_channel
< -1)
782 return NUM_HOSTAPD_MODES
;
784 if (freq
>= 2412 && freq
<= 2472) {
785 if ((freq
- 2407) % 5)
786 return NUM_HOSTAPD_MODES
;
789 return NUM_HOSTAPD_MODES
;
791 /* 2.407 GHz, channels 1..13 */
792 if (sec_channel
== 1)
794 else if (sec_channel
== -1)
799 *channel
= (freq
- 2407) / 5;
801 return HOSTAPD_MODE_IEEE80211G
;
805 if (sec_channel
|| chanwidth
)
806 return NUM_HOSTAPD_MODES
;
808 *op_class
= 82; /* channel 14 */
811 return HOSTAPD_MODE_IEEE80211B
;
814 if (freq
>= 4900 && freq
< 5000) {
815 if ((freq
- 4000) % 5)
816 return NUM_HOSTAPD_MODES
;
817 *channel
= (freq
- 4000) / 5;
818 *op_class
= 0; /* TODO */
819 return HOSTAPD_MODE_IEEE80211A
;
823 case CHANWIDTH_80MHZ
:
826 case CHANWIDTH_160MHZ
:
829 case CHANWIDTH_80P80MHZ
:
837 /* 5 GHz, channels 36..48 */
838 if (freq
>= 5180 && freq
<= 5240) {
839 if ((freq
- 5000) % 5)
840 return NUM_HOSTAPD_MODES
;
843 *op_class
= vht_opclass
;
844 else if (sec_channel
== 1)
846 else if (sec_channel
== -1)
851 *channel
= (freq
- 5000) / 5;
853 return HOSTAPD_MODE_IEEE80211A
;
856 /* 5 GHz, channels 52..64 */
857 if (freq
>= 5260 && freq
<= 5320) {
858 if ((freq
- 5000) % 5)
859 return NUM_HOSTAPD_MODES
;
862 *op_class
= vht_opclass
;
863 else if (sec_channel
== 1)
865 else if (sec_channel
== -1)
870 *channel
= (freq
- 5000) / 5;
872 return HOSTAPD_MODE_IEEE80211A
;
875 /* 5 GHz, channels 149..169 */
876 if (freq
>= 5745 && freq
<= 5845) {
877 if ((freq
- 5000) % 5)
878 return NUM_HOSTAPD_MODES
;
881 *op_class
= vht_opclass
;
882 else if (sec_channel
== 1)
884 else if (sec_channel
== -1)
886 else if (freq
<= 5805)
891 *channel
= (freq
- 5000) / 5;
893 return HOSTAPD_MODE_IEEE80211A
;
896 /* 5 GHz, channels 100..140 */
897 if (freq
>= 5000 && freq
<= 5700) {
898 if ((freq
- 5000) % 5)
899 return NUM_HOSTAPD_MODES
;
902 *op_class
= vht_opclass
;
903 else if (sec_channel
== 1)
905 else if (sec_channel
== -1)
910 *channel
= (freq
- 5000) / 5;
912 return HOSTAPD_MODE_IEEE80211A
;
915 if (freq
>= 5000 && freq
< 5900) {
916 if ((freq
- 5000) % 5)
917 return NUM_HOSTAPD_MODES
;
918 *channel
= (freq
- 5000) / 5;
919 *op_class
= 0; /* TODO */
920 return HOSTAPD_MODE_IEEE80211A
;
923 if (freq
> 5940 && freq
<= 7105) {
925 u8 idx
= (freq
- 5940) / 5;
927 bw
= center_idx_to_bw_6ghz(idx
);
929 return NUM_HOSTAPD_MODES
;
932 *op_class
= 131 + bw
;
933 return HOSTAPD_MODE_IEEE80211A
;
936 /* 56.16 GHz, channel 1..6 */
937 if (freq
>= 56160 + 2160 * 1 && freq
<= 56160 + 2160 * 6) {
939 return NUM_HOSTAPD_MODES
;
942 case CHANWIDTH_USE_HT
:
943 case CHANWIDTH_2160MHZ
:
944 *channel
= (freq
- 56160) / 2160;
947 case CHANWIDTH_4320MHZ
:
948 /* EDMG channels 9 - 13 */
949 if (freq
> 56160 + 2160 * 5)
950 return NUM_HOSTAPD_MODES
;
952 *channel
= (freq
- 56160) / 2160 + 8;
955 case CHANWIDTH_6480MHZ
:
956 /* EDMG channels 17 - 20 */
957 if (freq
> 56160 + 2160 * 4)
958 return NUM_HOSTAPD_MODES
;
960 *channel
= (freq
- 56160) / 2160 + 16;
963 case CHANWIDTH_8640MHZ
:
964 /* EDMG channels 25 - 27 */
965 if (freq
> 56160 + 2160 * 3)
966 return NUM_HOSTAPD_MODES
;
968 *channel
= (freq
- 56160) / 2160 + 24;
972 return NUM_HOSTAPD_MODES
;
975 return HOSTAPD_MODE_IEEE80211AD
;
978 return NUM_HOSTAPD_MODES
;
982 int ieee80211_chaninfo_to_channel(unsigned int freq
, enum chan_width chanwidth
,
983 int sec_channel
, u8
*op_class
, u8
*channel
)
985 int cw
= CHAN_WIDTH_UNKNOWN
;
988 case CHAN_WIDTH_UNKNOWN
:
989 case CHAN_WIDTH_20_NOHT
:
992 cw
= CHANWIDTH_USE_HT
;
995 cw
= CHANWIDTH_80MHZ
;
997 case CHAN_WIDTH_80P80
:
998 cw
= CHANWIDTH_80P80MHZ
;
1000 case CHAN_WIDTH_160
:
1001 cw
= CHANWIDTH_160MHZ
;
1003 case CHAN_WIDTH_2160
:
1004 cw
= CHANWIDTH_2160MHZ
;
1006 case CHAN_WIDTH_4320
:
1007 cw
= CHANWIDTH_4320MHZ
;
1009 case CHAN_WIDTH_6480
:
1010 cw
= CHANWIDTH_6480MHZ
;
1012 case CHAN_WIDTH_8640
:
1013 cw
= CHANWIDTH_8640MHZ
;
1017 if (ieee80211_freq_to_channel_ext(freq
, sec_channel
, cw
, op_class
,
1018 channel
) == NUM_HOSTAPD_MODES
) {
1019 wpa_printf(MSG_WARNING
,
1020 "Cannot determine operating class and channel (freq=%u chanwidth=%d sec_channel=%d)",
1021 freq
, chanwidth
, sec_channel
);
1029 static const char *const us_op_class_cc
[] = {
1033 static const char *const eu_op_class_cc
[] = {
1034 "AL", "AM", "AT", "AZ", "BA", "BE", "BG", "BY", "CH", "CY", "CZ", "DE",
1035 "DK", "EE", "EL", "ES", "FI", "FR", "GE", "HR", "HU", "IE", "IS", "IT",
1036 "LI", "LT", "LU", "LV", "MD", "ME", "MK", "MT", "NL", "NO", "PL", "PT",
1037 "RO", "RS", "RU", "SE", "SI", "SK", "TR", "UA", "UK", NULL
1040 static const char *const jp_op_class_cc
[] = {
1044 static const char *const cn_op_class_cc
[] = {
1049 static int country_match(const char *const cc
[], const char *const country
)
1053 if (country
== NULL
)
1055 for (i
= 0; cc
[i
]; i
++) {
1056 if (cc
[i
][0] == country
[0] && cc
[i
][1] == country
[1])
1064 static int ieee80211_chan_to_freq_us(u8 op_class
, u8 chan
)
1067 case 12: /* channels 1..11 */
1068 case 32: /* channels 1..7; 40 MHz */
1069 case 33: /* channels 5..11; 40 MHz */
1070 if (chan
< 1 || chan
> 11)
1072 return 2407 + 5 * chan
;
1073 case 1: /* channels 36,40,44,48 */
1074 case 2: /* channels 52,56,60,64; dfs */
1075 case 22: /* channels 36,44; 40 MHz */
1076 case 23: /* channels 52,60; 40 MHz */
1077 case 27: /* channels 40,48; 40 MHz */
1078 case 28: /* channels 56,64; 40 MHz */
1079 if (chan
< 36 || chan
> 64)
1081 return 5000 + 5 * chan
;
1082 case 4: /* channels 100-144 */
1083 case 24: /* channels 100-140; 40 MHz */
1084 if (chan
< 100 || chan
> 144)
1086 return 5000 + 5 * chan
;
1087 case 3: /* channels 149,153,157,161 */
1088 case 25: /* channels 149,157; 40 MHz */
1089 case 26: /* channels 149,157; 40 MHz */
1090 case 30: /* channels 153,161; 40 MHz */
1091 case 31: /* channels 153,161; 40 MHz */
1092 if (chan
< 149 || chan
> 161)
1094 return 5000 + 5 * chan
;
1095 case 5: /* channels 149,153,157,161,165 */
1096 if (chan
< 149 || chan
> 165)
1098 return 5000 + 5 * chan
;
1099 case 34: /* 60 GHz band, channels 1..8 */
1100 if (chan
< 1 || chan
> 8)
1102 return 56160 + 2160 * chan
;
1103 case 37: /* 60 GHz band, EDMG CB2, channels 9..15 */
1104 if (chan
< 9 || chan
> 15)
1106 return 56160 + 2160 * (chan
- 8);
1107 case 38: /* 60 GHz band, EDMG CB3, channels 17..22 */
1108 if (chan
< 17 || chan
> 22)
1110 return 56160 + 2160 * (chan
- 16);
1111 case 39: /* 60 GHz band, EDMG CB4, channels 25..29 */
1112 if (chan
< 25 || chan
> 29)
1114 return 56160 + 2160 * (chan
- 24);
1120 static int ieee80211_chan_to_freq_eu(u8 op_class
, u8 chan
)
1123 case 4: /* channels 1..13 */
1124 case 11: /* channels 1..9; 40 MHz */
1125 case 12: /* channels 5..13; 40 MHz */
1126 if (chan
< 1 || chan
> 13)
1128 return 2407 + 5 * chan
;
1129 case 1: /* channels 36,40,44,48 */
1130 case 2: /* channels 52,56,60,64; dfs */
1131 case 5: /* channels 36,44; 40 MHz */
1132 case 6: /* channels 52,60; 40 MHz */
1133 case 8: /* channels 40,48; 40 MHz */
1134 case 9: /* channels 56,64; 40 MHz */
1135 if (chan
< 36 || chan
> 64)
1137 return 5000 + 5 * chan
;
1138 case 3: /* channels 100-140 */
1139 case 7: /* channels 100-132; 40 MHz */
1140 case 10: /* channels 104-136; 40 MHz */
1141 case 16: /* channels 100-140 */
1142 if (chan
< 100 || chan
> 140)
1144 return 5000 + 5 * chan
;
1145 case 17: /* channels 149,153,157,161,165,169 */
1146 if (chan
< 149 || chan
> 169)
1148 return 5000 + 5 * chan
;
1149 case 18: /* 60 GHz band, channels 1..6 */
1150 if (chan
< 1 || chan
> 6)
1152 return 56160 + 2160 * chan
;
1153 case 21: /* 60 GHz band, EDMG CB2, channels 9..11 */
1154 if (chan
< 9 || chan
> 11)
1156 return 56160 + 2160 * (chan
- 8);
1157 case 22: /* 60 GHz band, EDMG CB3, channels 17..18 */
1158 if (chan
< 17 || chan
> 18)
1160 return 56160 + 2160 * (chan
- 16);
1161 case 23: /* 60 GHz band, EDMG CB4, channels 25 */
1164 return 56160 + 2160 * (chan
- 24);
1170 static int ieee80211_chan_to_freq_jp(u8 op_class
, u8 chan
)
1173 case 30: /* channels 1..13 */
1174 case 56: /* channels 1..9; 40 MHz */
1175 case 57: /* channels 5..13; 40 MHz */
1176 if (chan
< 1 || chan
> 13)
1178 return 2407 + 5 * chan
;
1179 case 31: /* channel 14 */
1182 return 2414 + 5 * chan
;
1183 case 1: /* channels 34,38,42,46(old) or 36,40,44,48 */
1184 case 32: /* channels 52,56,60,64 */
1185 case 33: /* channels 52,56,60,64 */
1186 case 36: /* channels 36,44; 40 MHz */
1187 case 37: /* channels 52,60; 40 MHz */
1188 case 38: /* channels 52,60; 40 MHz */
1189 case 41: /* channels 40,48; 40 MHz */
1190 case 42: /* channels 56,64; 40 MHz */
1191 case 43: /* channels 56,64; 40 MHz */
1192 if (chan
< 34 || chan
> 64)
1194 return 5000 + 5 * chan
;
1195 case 34: /* channels 100-140 */
1196 case 35: /* channels 100-140 */
1197 case 39: /* channels 100-132; 40 MHz */
1198 case 40: /* channels 100-132; 40 MHz */
1199 case 44: /* channels 104-136; 40 MHz */
1200 case 45: /* channels 104-136; 40 MHz */
1201 case 58: /* channels 100-140 */
1202 if (chan
< 100 || chan
> 140)
1204 return 5000 + 5 * chan
;
1205 case 59: /* 60 GHz band, channels 1..6 */
1206 if (chan
< 1 || chan
> 6)
1208 return 56160 + 2160 * chan
;
1209 case 62: /* 60 GHz band, EDMG CB2, channels 9..11 */
1210 if (chan
< 9 || chan
> 11)
1212 return 56160 + 2160 * (chan
- 8);
1213 case 63: /* 60 GHz band, EDMG CB3, channels 17..18 */
1214 if (chan
< 17 || chan
> 18)
1216 return 56160 + 2160 * (chan
- 16);
1217 case 64: /* 60 GHz band, EDMG CB4, channel 25 */
1220 return 56160 + 2160 * (chan
- 24);
1226 static int ieee80211_chan_to_freq_cn(u8 op_class
, u8 chan
)
1229 case 7: /* channels 1..13 */
1230 case 8: /* channels 1..9; 40 MHz */
1231 case 9: /* channels 5..13; 40 MHz */
1232 if (chan
< 1 || chan
> 13)
1234 return 2407 + 5 * chan
;
1235 case 1: /* channels 36,40,44,48 */
1236 case 2: /* channels 52,56,60,64; dfs */
1237 case 4: /* channels 36,44; 40 MHz */
1238 case 5: /* channels 52,60; 40 MHz */
1239 if (chan
< 36 || chan
> 64)
1241 return 5000 + 5 * chan
;
1242 case 3: /* channels 149,153,157,161,165 */
1243 case 6: /* channels 149,157; 40 MHz */
1244 if (chan
< 149 || chan
> 165)
1246 return 5000 + 5 * chan
;
1252 static int ieee80211_chan_to_freq_global(u8 op_class
, u8 chan
)
1254 /* Table E-4 in IEEE Std 802.11-2012 - Global operating classes */
1257 /* channels 1..13 */
1258 if (chan
< 1 || chan
> 13)
1260 return 2407 + 5 * chan
;
1265 return 2414 + 5 * chan
;
1266 case 83: /* channels 1..9; 40 MHz */
1267 case 84: /* channels 5..13; 40 MHz */
1268 if (chan
< 1 || chan
> 13)
1270 return 2407 + 5 * chan
;
1271 case 115: /* channels 36,40,44,48; indoor only */
1272 case 116: /* channels 36,44; 40 MHz; indoor only */
1273 case 117: /* channels 40,48; 40 MHz; indoor only */
1274 case 118: /* channels 52,56,60,64; dfs */
1275 case 119: /* channels 52,60; 40 MHz; dfs */
1276 case 120: /* channels 56,64; 40 MHz; dfs */
1277 if (chan
< 36 || chan
> 64)
1279 return 5000 + 5 * chan
;
1280 case 121: /* channels 100-140 */
1281 case 122: /* channels 100-142; 40 MHz */
1282 case 123: /* channels 104-136; 40 MHz */
1283 if (chan
< 100 || chan
> 140)
1285 return 5000 + 5 * chan
;
1286 case 124: /* channels 149,153,157,161 */
1287 case 126: /* channels 149,157; 40 MHz */
1288 case 127: /* channels 153,161; 40 MHz */
1289 if (chan
< 149 || chan
> 161)
1291 return 5000 + 5 * chan
;
1292 case 125: /* channels 149,153,157,161,165,169 */
1293 if (chan
< 149 || chan
> 169)
1295 return 5000 + 5 * chan
;
1296 case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
1297 case 130: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
1298 if (chan
< 36 || chan
> 161)
1300 return 5000 + 5 * chan
;
1301 case 129: /* center freqs 50, 114; 160 MHz */
1302 if (chan
< 36 || chan
> 128)
1304 return 5000 + 5 * chan
;
1305 case 131: /* UHB channels, 20 MHz: 1, 5, 9.. */
1306 case 132: /* UHB channels, 40 MHz: 3, 11, 19.. */
1307 case 133: /* UHB channels, 80 MHz: 7, 23, 39.. */
1308 case 134: /* UHB channels, 160 MHz: 15, 47, 79.. */
1309 case 135: /* UHB channels, 80+80 MHz: 7, 23, 39.. */
1310 if (chan
< 1 || chan
> 233)
1312 return 5940 + chan
* 5;
1313 case 180: /* 60 GHz band, channels 1..8 */
1314 if (chan
< 1 || chan
> 8)
1316 return 56160 + 2160 * chan
;
1317 case 181: /* 60 GHz band, EDMG CB2, channels 9..15 */
1318 if (chan
< 9 || chan
> 15)
1320 return 56160 + 2160 * (chan
- 8);
1321 case 182: /* 60 GHz band, EDMG CB3, channels 17..22 */
1322 if (chan
< 17 || chan
> 22)
1324 return 56160 + 2160 * (chan
- 16);
1325 case 183: /* 60 GHz band, EDMG CB4, channel 25..29 */
1326 if (chan
< 25 || chan
> 29)
1328 return 56160 + 2160 * (chan
- 24);
1334 * ieee80211_chan_to_freq - Convert channel info to frequency
1335 * @country: Country code, if known; otherwise, global operating class is used
1336 * @op_class: Operating class
1337 * @chan: Channel number
1338 * Returns: Frequency in MHz or -1 if the specified channel is unknown
1340 int ieee80211_chan_to_freq(const char *country
, u8 op_class
, u8 chan
)
1344 if (country_match(us_op_class_cc
, country
)) {
1345 freq
= ieee80211_chan_to_freq_us(op_class
, chan
);
1350 if (country_match(eu_op_class_cc
, country
)) {
1351 freq
= ieee80211_chan_to_freq_eu(op_class
, chan
);
1356 if (country_match(jp_op_class_cc
, country
)) {
1357 freq
= ieee80211_chan_to_freq_jp(op_class
, chan
);
1362 if (country_match(cn_op_class_cc
, country
)) {
1363 freq
= ieee80211_chan_to_freq_cn(op_class
, chan
);
1368 return ieee80211_chan_to_freq_global(op_class
, chan
);
1372 int ieee80211_is_dfs(int freq
, const struct hostapd_hw_modes
*modes
,
1377 if (!modes
|| !num_modes
)
1378 return (freq
>= 5260 && freq
<= 5320) ||
1379 (freq
>= 5500 && freq
<= 5700);
1381 for (i
= 0; i
< num_modes
; i
++) {
1382 for (j
= 0; j
< modes
[i
].num_channels
; j
++) {
1383 if (modes
[i
].channels
[j
].freq
== freq
&&
1384 (modes
[i
].channels
[j
].flag
& HOSTAPD_CHAN_RADAR
))
1393 static int is_11b(u8 rate
)
1395 return rate
== 0x02 || rate
== 0x04 || rate
== 0x0b || rate
== 0x16;
1399 int supp_rates_11b_only(struct ieee802_11_elems
*elems
)
1401 int num_11b
= 0, num_others
= 0;
1404 if (elems
->supp_rates
== NULL
&& elems
->ext_supp_rates
== NULL
)
1407 for (i
= 0; elems
->supp_rates
&& i
< elems
->supp_rates_len
; i
++) {
1408 if (is_11b(elems
->supp_rates
[i
]))
1414 for (i
= 0; elems
->ext_supp_rates
&& i
< elems
->ext_supp_rates_len
;
1416 if (is_11b(elems
->ext_supp_rates
[i
]))
1422 return num_11b
> 0 && num_others
== 0;
1426 const char * fc2str(u16 fc
)
1428 u16 stype
= WLAN_FC_GET_STYPE(fc
);
1429 #define C2S(x) case x: return #x;
1431 switch (WLAN_FC_GET_TYPE(fc
)) {
1432 case WLAN_FC_TYPE_MGMT
:
1434 C2S(WLAN_FC_STYPE_ASSOC_REQ
)
1435 C2S(WLAN_FC_STYPE_ASSOC_RESP
)
1436 C2S(WLAN_FC_STYPE_REASSOC_REQ
)
1437 C2S(WLAN_FC_STYPE_REASSOC_RESP
)
1438 C2S(WLAN_FC_STYPE_PROBE_REQ
)
1439 C2S(WLAN_FC_STYPE_PROBE_RESP
)
1440 C2S(WLAN_FC_STYPE_BEACON
)
1441 C2S(WLAN_FC_STYPE_ATIM
)
1442 C2S(WLAN_FC_STYPE_DISASSOC
)
1443 C2S(WLAN_FC_STYPE_AUTH
)
1444 C2S(WLAN_FC_STYPE_DEAUTH
)
1445 C2S(WLAN_FC_STYPE_ACTION
)
1448 case WLAN_FC_TYPE_CTRL
:
1450 C2S(WLAN_FC_STYPE_PSPOLL
)
1451 C2S(WLAN_FC_STYPE_RTS
)
1452 C2S(WLAN_FC_STYPE_CTS
)
1453 C2S(WLAN_FC_STYPE_ACK
)
1454 C2S(WLAN_FC_STYPE_CFEND
)
1455 C2S(WLAN_FC_STYPE_CFENDACK
)
1458 case WLAN_FC_TYPE_DATA
:
1460 C2S(WLAN_FC_STYPE_DATA
)
1461 C2S(WLAN_FC_STYPE_DATA_CFACK
)
1462 C2S(WLAN_FC_STYPE_DATA_CFPOLL
)
1463 C2S(WLAN_FC_STYPE_DATA_CFACKPOLL
)
1464 C2S(WLAN_FC_STYPE_NULLFUNC
)
1465 C2S(WLAN_FC_STYPE_CFACK
)
1466 C2S(WLAN_FC_STYPE_CFPOLL
)
1467 C2S(WLAN_FC_STYPE_CFACKPOLL
)
1468 C2S(WLAN_FC_STYPE_QOS_DATA
)
1469 C2S(WLAN_FC_STYPE_QOS_DATA_CFACK
)
1470 C2S(WLAN_FC_STYPE_QOS_DATA_CFPOLL
)
1471 C2S(WLAN_FC_STYPE_QOS_DATA_CFACKPOLL
)
1472 C2S(WLAN_FC_STYPE_QOS_NULL
)
1473 C2S(WLAN_FC_STYPE_QOS_CFPOLL
)
1474 C2S(WLAN_FC_STYPE_QOS_CFACKPOLL
)
1478 return "WLAN_FC_TYPE_UNKNOWN";
1483 const char * reason2str(u16 reason
)
1485 #define R2S(r) case WLAN_REASON_ ## r: return #r;
1488 R2S(PREV_AUTH_NOT_VALID
)
1490 R2S(DISASSOC_DUE_TO_INACTIVITY
)
1491 R2S(DISASSOC_AP_BUSY
)
1492 R2S(CLASS2_FRAME_FROM_NONAUTH_STA
)
1493 R2S(CLASS3_FRAME_FROM_NONASSOC_STA
)
1494 R2S(DISASSOC_STA_HAS_LEFT
)
1495 R2S(STA_REQ_ASSOC_WITHOUT_AUTH
)
1496 R2S(PWR_CAPABILITY_NOT_VALID
)
1497 R2S(SUPPORTED_CHANNEL_NOT_VALID
)
1498 R2S(BSS_TRANSITION_DISASSOC
)
1500 R2S(MICHAEL_MIC_FAILURE
)
1501 R2S(4WAY_HANDSHAKE_TIMEOUT
)
1502 R2S(GROUP_KEY_UPDATE_TIMEOUT
)
1503 R2S(IE_IN_4WAY_DIFFERS
)
1504 R2S(GROUP_CIPHER_NOT_VALID
)
1505 R2S(PAIRWISE_CIPHER_NOT_VALID
)
1507 R2S(UNSUPPORTED_RSN_IE_VERSION
)
1508 R2S(INVALID_RSN_IE_CAPAB
)
1509 R2S(IEEE_802_1X_AUTH_FAILED
)
1510 R2S(CIPHER_SUITE_REJECTED
)
1511 R2S(TDLS_TEARDOWN_UNREACHABLE
)
1512 R2S(TDLS_TEARDOWN_UNSPECIFIED
)
1513 R2S(SSP_REQUESTED_DISASSOC
)
1514 R2S(NO_SSP_ROAMING_AGREEMENT
)
1515 R2S(BAD_CIPHER_OR_AKM
)
1516 R2S(NOT_AUTHORIZED_THIS_LOCATION
)
1517 R2S(SERVICE_CHANGE_PRECLUDES_TS
)
1518 R2S(UNSPECIFIED_QOS_REASON
)
1519 R2S(NOT_ENOUGH_BANDWIDTH
)
1520 R2S(DISASSOC_LOW_ACK
)
1526 R2S(PEERKEY_MISMATCH
)
1527 R2S(AUTHORIZED_ACCESS_LIMIT_REACHED
)
1528 R2S(EXTERNAL_SERVICE_REQUIREMENTS
)
1529 R2S(INVALID_FT_ACTION_FRAME_COUNT
)
1533 R2S(MESH_PEERING_CANCELLED
)
1535 R2S(MESH_CONFIG_POLICY_VIOLATION
)
1536 R2S(MESH_CLOSE_RCVD
)
1537 R2S(MESH_MAX_RETRIES
)
1538 R2S(MESH_CONFIRM_TIMEOUT
)
1539 R2S(MESH_INVALID_GTK
)
1540 R2S(MESH_INCONSISTENT_PARAMS
)
1541 R2S(MESH_INVALID_SECURITY_CAP
)
1542 R2S(MESH_PATH_ERROR_NO_PROXY_INFO
)
1543 R2S(MESH_PATH_ERROR_NO_FORWARDING_INFO
)
1544 R2S(MESH_PATH_ERROR_DEST_UNREACHABLE
)
1545 R2S(MAC_ADDRESS_ALREADY_EXISTS_IN_MBSS
)
1546 R2S(MESH_CHANNEL_SWITCH_REGULATORY_REQ
)
1547 R2S(MESH_CHANNEL_SWITCH_UNSPECIFIED
)
1554 const char * status2str(u16 status
)
1556 #define S2S(s) case WLAN_STATUS_ ## s: return #s;
1559 S2S(UNSPECIFIED_FAILURE
)
1560 S2S(TDLS_WAKEUP_ALTERNATE
)
1561 S2S(TDLS_WAKEUP_REJECT
)
1562 S2S(SECURITY_DISABLED
)
1563 S2S(UNACCEPTABLE_LIFETIME
)
1564 S2S(NOT_IN_SAME_BSS
)
1565 S2S(CAPS_UNSUPPORTED
)
1566 S2S(REASSOC_NO_ASSOC
)
1567 S2S(ASSOC_DENIED_UNSPEC
)
1568 S2S(NOT_SUPPORTED_AUTH_ALG
)
1569 S2S(UNKNOWN_AUTH_TRANSACTION
)
1572 S2S(AP_UNABLE_TO_HANDLE_NEW_STA
)
1573 S2S(ASSOC_DENIED_RATES
)
1574 S2S(ASSOC_DENIED_NOSHORT
)
1575 S2S(SPEC_MGMT_REQUIRED
)
1576 S2S(PWR_CAPABILITY_NOT_VALID
)
1577 S2S(SUPPORTED_CHANNEL_NOT_VALID
)
1578 S2S(ASSOC_DENIED_NO_SHORT_SLOT_TIME
)
1579 S2S(ASSOC_DENIED_NO_HT
)
1580 S2S(R0KH_UNREACHABLE
)
1581 S2S(ASSOC_DENIED_NO_PCO
)
1582 S2S(ASSOC_REJECTED_TEMPORARILY
)
1583 S2S(ROBUST_MGMT_FRAME_POLICY_VIOLATION
)
1584 S2S(UNSPECIFIED_QOS_FAILURE
)
1585 S2S(DENIED_INSUFFICIENT_BANDWIDTH
)
1586 S2S(DENIED_POOR_CHANNEL_CONDITIONS
)
1587 S2S(DENIED_QOS_NOT_SUPPORTED
)
1588 S2S(REQUEST_DECLINED
)
1589 S2S(INVALID_PARAMETERS
)
1590 S2S(REJECTED_WITH_SUGGESTED_CHANGES
)
1592 S2S(GROUP_CIPHER_NOT_VALID
)
1593 S2S(PAIRWISE_CIPHER_NOT_VALID
)
1595 S2S(UNSUPPORTED_RSN_IE_VERSION
)
1596 S2S(INVALID_RSN_IE_CAPAB
)
1597 S2S(CIPHER_REJECTED_PER_POLICY
)
1599 S2S(DIRECT_LINK_NOT_ALLOWED
)
1600 S2S(DEST_STA_NOT_PRESENT
)
1601 S2S(DEST_STA_NOT_QOS_STA
)
1602 S2S(ASSOC_DENIED_LISTEN_INT_TOO_LARGE
)
1603 S2S(INVALID_FT_ACTION_FRAME_COUNT
)
1607 S2S(REQUESTED_TCLAS_NOT_SUPPORTED
)
1608 S2S(INSUFFICIENT_TCLAS_PROCESSING_RESOURCES
)
1609 S2S(TRY_ANOTHER_BSS
)
1610 S2S(GAS_ADV_PROTO_NOT_SUPPORTED
)
1611 S2S(NO_OUTSTANDING_GAS_REQ
)
1612 S2S(GAS_RESP_NOT_RECEIVED
)
1613 S2S(STA_TIMED_OUT_WAITING_FOR_GAS_RESP
)
1614 S2S(GAS_RESP_LARGER_THAN_LIMIT
)
1615 S2S(REQ_REFUSED_HOME
)
1616 S2S(ADV_SRV_UNREACHABLE
)
1617 S2S(REQ_REFUSED_SSPN
)
1618 S2S(REQ_REFUSED_UNAUTH_ACCESS
)
1620 S2S(U_APSD_COEX_NOT_SUPPORTED
)
1621 S2S(U_APSD_COEX_MODE_NOT_SUPPORTED
)
1622 S2S(BAD_INTERVAL_WITH_U_APSD_COEX
)
1623 S2S(ANTI_CLOGGING_TOKEN_REQ
)
1624 S2S(FINITE_CYCLIC_GROUP_NOT_SUPPORTED
)
1625 S2S(CANNOT_FIND_ALT_TBTT
)
1626 S2S(TRANSMISSION_FAILURE
)
1627 S2S(REQ_TCLAS_NOT_SUPPORTED
)
1628 S2S(TCLAS_RESOURCES_EXCHAUSTED
)
1629 S2S(REJECTED_WITH_SUGGESTED_BSS_TRANSITION
)
1630 S2S(REJECT_WITH_SCHEDULE
)
1631 S2S(REJECT_NO_WAKEUP_SPECIFIED
)
1632 S2S(SUCCESS_POWER_SAVE_MODE
)
1633 S2S(PENDING_ADMITTING_FST_SESSION
)
1634 S2S(PERFORMING_FST_NOW
)
1635 S2S(PENDING_GAP_IN_BA_WINDOW
)
1636 S2S(REJECT_U_PID_SETTING
)
1637 S2S(REFUSED_EXTERNAL_REASON
)
1638 S2S(REFUSED_AP_OUT_OF_MEMORY
)
1639 S2S(REJECTED_EMERGENCY_SERVICE_NOT_SUPPORTED
)
1640 S2S(QUERY_RESP_OUTSTANDING
)
1641 S2S(REJECT_DSE_BAND
)
1642 S2S(TCLAS_PROCESSING_TERMINATED
)
1643 S2S(TS_SCHEDULE_CONFLICT
)
1644 S2S(DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL
)
1645 S2S(MCCAOP_RESERVATION_CONFLICT
)
1646 S2S(MAF_LIMIT_EXCEEDED
)
1647 S2S(MCCA_TRACK_LIMIT_EXCEEDED
)
1648 S2S(DENIED_DUE_TO_SPECTRUM_MANAGEMENT
)
1649 S2S(ASSOC_DENIED_NO_VHT
)
1650 S2S(ENABLEMENT_DENIED
)
1651 S2S(RESTRICTION_FROM_AUTHORIZED_GDB
)
1652 S2S(AUTHORIZATION_DEENABLED
)
1653 S2S(FILS_AUTHENTICATION_FAILURE
)
1654 S2S(UNKNOWN_AUTHENTICATION_SERVER
)
1655 S2S(UNKNOWN_PASSWORD_IDENTIFIER
)
1656 S2S(SAE_HASH_TO_ELEMENT
)
1663 int mb_ies_info_by_ies(struct mb_ies_info
*info
, const u8
*ies_buf
,
1666 const struct element
*elem
;
1668 os_memset(info
, 0, sizeof(*info
));
1673 for_each_element_id(elem
, WLAN_EID_MULTI_BAND
, ies_buf
, ies_len
) {
1674 if (info
->nof_ies
>= MAX_NOF_MB_IES_SUPPORTED
)
1677 wpa_printf(MSG_DEBUG
, "MB IE of %u bytes found",
1679 info
->ies
[info
->nof_ies
].ie
= elem
->data
;
1680 info
->ies
[info
->nof_ies
].ie_len
= elem
->datalen
;
1684 if (!for_each_element_completed(elem
, ies_buf
, ies_len
)) {
1685 wpa_hexdump(MSG_DEBUG
, "Truncated IEs", ies_buf
, ies_len
);
1693 struct wpabuf
* mb_ies_by_info(struct mb_ies_info
*info
)
1695 struct wpabuf
*mb_ies
= NULL
;
1697 WPA_ASSERT(info
!= NULL
);
1699 if (info
->nof_ies
) {
1701 size_t mb_ies_size
= 0;
1703 for (i
= 0; i
< info
->nof_ies
; i
++)
1704 mb_ies_size
+= 2 + info
->ies
[i
].ie_len
;
1706 mb_ies
= wpabuf_alloc(mb_ies_size
);
1708 for (i
= 0; i
< info
->nof_ies
; i
++) {
1709 wpabuf_put_u8(mb_ies
, WLAN_EID_MULTI_BAND
);
1710 wpabuf_put_u8(mb_ies
, info
->ies
[i
].ie_len
);
1711 wpabuf_put_data(mb_ies
,
1713 info
->ies
[i
].ie_len
);
1722 const struct oper_class_map global_op_class
[] = {
1723 { HOSTAPD_MODE_IEEE80211G
, 81, 1, 13, 1, BW20
, P2P_SUPP
},
1724 { HOSTAPD_MODE_IEEE80211G
, 82, 14, 14, 1, BW20
, NO_P2P_SUPP
},
1726 /* Do not enable HT40 on 2.4 GHz for P2P use for now */
1727 { HOSTAPD_MODE_IEEE80211G
, 83, 1, 9, 1, BW40PLUS
, NO_P2P_SUPP
},
1728 { HOSTAPD_MODE_IEEE80211G
, 84, 5, 13, 1, BW40MINUS
, NO_P2P_SUPP
},
1730 { HOSTAPD_MODE_IEEE80211A
, 115, 36, 48, 4, BW20
, P2P_SUPP
},
1731 { HOSTAPD_MODE_IEEE80211A
, 116, 36, 44, 8, BW40PLUS
, P2P_SUPP
},
1732 { HOSTAPD_MODE_IEEE80211A
, 117, 40, 48, 8, BW40MINUS
, P2P_SUPP
},
1733 { HOSTAPD_MODE_IEEE80211A
, 118, 52, 64, 4, BW20
, NO_P2P_SUPP
},
1734 { HOSTAPD_MODE_IEEE80211A
, 119, 52, 60, 8, BW40PLUS
, NO_P2P_SUPP
},
1735 { HOSTAPD_MODE_IEEE80211A
, 120, 56, 64, 8, BW40MINUS
, NO_P2P_SUPP
},
1736 { HOSTAPD_MODE_IEEE80211A
, 121, 100, 140, 4, BW20
, NO_P2P_SUPP
},
1737 { HOSTAPD_MODE_IEEE80211A
, 122, 100, 132, 8, BW40PLUS
, NO_P2P_SUPP
},
1738 { HOSTAPD_MODE_IEEE80211A
, 123, 104, 136, 8, BW40MINUS
, NO_P2P_SUPP
},
1739 { HOSTAPD_MODE_IEEE80211A
, 124, 149, 161, 4, BW20
, P2P_SUPP
},
1740 { HOSTAPD_MODE_IEEE80211A
, 125, 149, 169, 4, BW20
, P2P_SUPP
},
1741 { HOSTAPD_MODE_IEEE80211A
, 126, 149, 157, 8, BW40PLUS
, P2P_SUPP
},
1742 { HOSTAPD_MODE_IEEE80211A
, 127, 153, 161, 8, BW40MINUS
, P2P_SUPP
},
1745 * IEEE P802.11ac/D7.0 Table E-4 actually talks about channel center
1746 * frequency index 42, 58, 106, 122, 138, 155 with channel spacing of
1747 * 80 MHz, but currently use the following definition for simplicity
1748 * (these center frequencies are not actual channels, which makes
1749 * wpas_p2p_allow_channel() fail). wpas_p2p_verify_80mhz() should take
1750 * care of removing invalid channels.
1752 { HOSTAPD_MODE_IEEE80211A
, 128, 36, 161, 4, BW80
, P2P_SUPP
},
1753 { HOSTAPD_MODE_IEEE80211A
, 129, 50, 114, 16, BW160
, P2P_SUPP
},
1754 { HOSTAPD_MODE_IEEE80211A
, 130, 36, 161, 4, BW80P80
, P2P_SUPP
},
1755 { HOSTAPD_MODE_IEEE80211A
, 131, 1, 233, 4, BW20
, P2P_SUPP
},
1758 * IEEE Std 802.11ad-2012 and P802.ay/D5.0 60 GHz operating classes.
1759 * Class 180 has the legacy channels 1-6. Classes 181-183 include
1760 * channels which implement channel bonding features.
1762 { HOSTAPD_MODE_IEEE80211AD
, 180, 1, 6, 1, BW2160
, P2P_SUPP
},
1763 { HOSTAPD_MODE_IEEE80211AD
, 181, 9, 13, 1, BW4320
, P2P_SUPP
},
1764 { HOSTAPD_MODE_IEEE80211AD
, 182, 17, 20, 1, BW6480
, P2P_SUPP
},
1765 { HOSTAPD_MODE_IEEE80211AD
, 183, 25, 27, 1, BW8640
, P2P_SUPP
},
1766 { -1, 0, 0, 0, 0, BW20
, NO_P2P_SUPP
}
1770 static enum phy_type
ieee80211_phy_type_by_freq(int freq
)
1772 enum hostapd_hw_mode hw_mode
;
1775 hw_mode
= ieee80211_freq_to_chan(freq
, &channel
);
1778 case HOSTAPD_MODE_IEEE80211A
:
1779 return PHY_TYPE_OFDM
;
1780 case HOSTAPD_MODE_IEEE80211B
:
1781 return PHY_TYPE_HRDSSS
;
1782 case HOSTAPD_MODE_IEEE80211G
:
1783 return PHY_TYPE_ERP
;
1784 case HOSTAPD_MODE_IEEE80211AD
:
1785 return PHY_TYPE_DMG
;
1787 return PHY_TYPE_UNSPECIFIED
;
1792 /* ieee80211_get_phy_type - Derive the phy type by freq and bandwidth */
1793 enum phy_type
ieee80211_get_phy_type(int freq
, int ht
, int vht
)
1796 return PHY_TYPE_VHT
;
1800 return ieee80211_phy_type_by_freq(freq
);
1804 size_t global_op_class_size
= ARRAY_SIZE(global_op_class
);
1808 * get_ie - Fetch a specified information element from IEs buffer
1809 * @ies: Information elements buffer
1810 * @len: Information elements buffer length
1811 * @eid: Information element identifier (WLAN_EID_*)
1812 * Returns: Pointer to the information element (id field) or %NULL if not found
1814 * This function returns the first matching information element in the IEs
1815 * buffer or %NULL in case the element is not found.
1817 const u8
* get_ie(const u8
*ies
, size_t len
, u8 eid
)
1819 const struct element
*elem
;
1824 for_each_element_id(elem
, eid
, ies
, len
)
1832 * get_ie_ext - Fetch a specified extended information element from IEs buffer
1833 * @ies: Information elements buffer
1834 * @len: Information elements buffer length
1835 * @ext: Information element extension identifier (WLAN_EID_EXT_*)
1836 * Returns: Pointer to the information element (id field) or %NULL if not found
1838 * This function returns the first matching information element in the IEs
1839 * buffer or %NULL in case the element is not found.
1841 const u8
* get_ie_ext(const u8
*ies
, size_t len
, u8 ext
)
1843 const struct element
*elem
;
1848 for_each_element_extid(elem
, ext
, ies
, len
)
1855 const u8
* get_vendor_ie(const u8
*ies
, size_t len
, u32 vendor_type
)
1857 const struct element
*elem
;
1859 for_each_element_id(elem
, WLAN_EID_VENDOR_SPECIFIC
, ies
, len
) {
1860 if (elem
->datalen
>= 4 &&
1861 vendor_type
== WPA_GET_BE32(elem
->data
))
1869 size_t mbo_add_ie(u8
*buf
, size_t len
, const u8
*attr
, size_t attr_len
)
1872 * MBO IE requires 6 bytes without the attributes: EID (1), length (1),
1873 * OUI (3), OUI type (1).
1875 if (len
< 6 + attr_len
) {
1876 wpa_printf(MSG_DEBUG
,
1877 "MBO: Not enough room in buffer for MBO IE: buf len = %zu, attr_len = %zu",
1882 *buf
++ = WLAN_EID_VENDOR_SPECIFIC
;
1883 *buf
++ = attr_len
+ 4;
1884 WPA_PUT_BE24(buf
, OUI_WFA
);
1886 *buf
++ = MBO_OUI_TYPE
;
1887 os_memcpy(buf
, attr
, attr_len
);
1889 return 6 + attr_len
;
1893 size_t add_multi_ap_ie(u8
*buf
, size_t len
, u8 value
)
1900 *pos
++ = WLAN_EID_VENDOR_SPECIFIC
;
1901 *pos
++ = 7; /* len */
1902 WPA_PUT_BE24(pos
, OUI_WFA
);
1904 *pos
++ = MULTI_AP_OUI_TYPE
;
1905 *pos
++ = MULTI_AP_SUB_ELEM_TYPE
;
1906 *pos
++ = 1; /* len */
1913 static const struct country_op_class us_op_class
[] = {
1935 static const struct country_op_class eu_op_class
[] = {
1952 static const struct country_op_class jp_op_class
[] = {
1976 static const struct country_op_class cn_op_class
[] = {
1989 global_op_class_from_country_array(u8 op_class
, size_t array_size
,
1990 const struct country_op_class
*country_array
)
1994 for (i
= 0; i
< array_size
; i
++) {
1995 if (country_array
[i
].country_op_class
== op_class
)
1996 return country_array
[i
].global_op_class
;
2003 u8
country_to_global_op_class(const char *country
, u8 op_class
)
2005 const struct country_op_class
*country_array
;
2009 if (country_match(us_op_class_cc
, country
)) {
2010 country_array
= us_op_class
;
2011 size
= ARRAY_SIZE(us_op_class
);
2012 } else if (country_match(eu_op_class_cc
, country
)) {
2013 country_array
= eu_op_class
;
2014 size
= ARRAY_SIZE(eu_op_class
);
2015 } else if (country_match(jp_op_class_cc
, country
)) {
2016 country_array
= jp_op_class
;
2017 size
= ARRAY_SIZE(jp_op_class
);
2018 } else if (country_match(cn_op_class_cc
, country
)) {
2019 country_array
= cn_op_class
;
2020 size
= ARRAY_SIZE(cn_op_class
);
2023 * Countries that do not match any of the above countries use
2024 * global operating classes
2029 g_op_class
= global_op_class_from_country_array(op_class
, size
,
2033 * If the given operating class did not match any of the country's
2034 * operating classes, assume that global operating class is used.
2036 return g_op_class
? g_op_class
: op_class
;
2040 const struct oper_class_map
* get_oper_class(const char *country
, u8 op_class
)
2042 const struct oper_class_map
*op
;
2045 op_class
= country_to_global_op_class(country
, op_class
);
2047 op
= &global_op_class
[0];
2048 while (op
->op_class
&& op
->op_class
!= op_class
)
2058 int oper_class_bw_to_int(const struct oper_class_map
*map
)
2079 int center_idx_to_bw_6ghz(u8 idx
)
2081 /* channels: 1, 5, 9, 13... */
2082 if ((idx
& 0x3) == 0x1)
2083 return 0; /* 20 MHz */
2084 /* channels 3, 11, 19... */
2085 if ((idx
& 0x7) == 0x3)
2086 return 1; /* 40 MHz */
2087 /* channels 7, 23, 39.. */
2088 if ((idx
& 0xf) == 0x7)
2089 return 2; /* 80 MHz */
2090 /* channels 15, 47, 79...*/
2091 if ((idx
& 0x1f) == 0xf)
2092 return 3; /* 160 MHz */
2098 int is_6ghz_freq(int freq
)
2100 if (freq
< 5940 || freq
> 7105)
2103 if (center_idx_to_bw_6ghz((freq
- 5940) / 5) < 0)
2110 int is_6ghz_op_class(u8 op_class
)
2112 return op_class
>= 131 && op_class
<= 135;
2116 int is_6ghz_psc_frequency(int freq
)
2120 if (!is_6ghz_freq(freq
))
2122 if ((((freq
- 5940) / 5) & 0x3) != 0x1)
2125 i
= (freq
- 5940 + 55) % 80;
2127 i
= (freq
- 5940 + 55) / 80;
2129 if (i
>= 1 && i
<= 15)
2136 int ieee802_11_parse_candidate_list(const char *pos
, u8
*nei_rep
,
2139 u8
*nei_pos
= nei_rep
;
2143 * BSS Transition Candidate List Entries - Neighbor Report elements
2144 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
2145 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
2152 pos
= os_strstr(pos
, " neighbor=");
2155 if (nei_pos
+ 15 > nei_rep
+ nei_rep_len
) {
2156 wpa_printf(MSG_DEBUG
,
2157 "Not enough room for additional neighbor");
2162 nei_start
= nei_pos
;
2163 *nei_pos
++ = WLAN_EID_NEIGHBOR_REPORT
;
2164 nei_pos
++; /* length to be filled in */
2166 if (hwaddr_aton(pos
, nei_pos
)) {
2167 wpa_printf(MSG_DEBUG
, "Invalid BSSID");
2170 nei_pos
+= ETH_ALEN
;
2173 wpa_printf(MSG_DEBUG
, "Missing BSSID Information");
2178 val
= strtol(pos
, &endptr
, 0);
2179 WPA_PUT_LE32(nei_pos
, val
);
2181 if (*endptr
!= ',') {
2182 wpa_printf(MSG_DEBUG
, "Missing Operating Class");
2187 *nei_pos
++ = atoi(pos
); /* Operating Class */
2188 pos
= os_strchr(pos
, ',');
2190 wpa_printf(MSG_DEBUG
, "Missing Channel Number");
2195 *nei_pos
++ = atoi(pos
); /* Channel Number */
2196 pos
= os_strchr(pos
, ',');
2198 wpa_printf(MSG_DEBUG
, "Missing PHY Type");
2203 *nei_pos
++ = atoi(pos
); /* PHY Type */
2204 end
= os_strchr(pos
, ' ');
2205 tmp
= os_strchr(pos
, ',');
2206 if (tmp
&& (!end
|| tmp
< end
)) {
2207 /* Optional Subelements (hexdump) */
2211 end
= os_strchr(pos
, ' ');
2215 len
= os_strlen(pos
);
2216 if (nei_pos
+ len
/ 2 > nei_rep
+ nei_rep_len
) {
2217 wpa_printf(MSG_DEBUG
,
2218 "Not enough room for neighbor subelements");
2222 hexstr2bin(pos
, nei_pos
, len
/ 2) < 0) {
2223 wpa_printf(MSG_DEBUG
,
2224 "Invalid neighbor subelement info");
2231 nei_start
[1] = nei_pos
- nei_start
- 2;
2234 return nei_pos
- nei_rep
;
2238 int ieee802_11_ext_capab(const u8
*ie
, unsigned int capab
)
2240 if (!ie
|| ie
[1] <= capab
/ 8)
2242 return !!(ie
[2 + capab
/ 8] & BIT(capab
% 8));
2246 void hostapd_encode_edmg_chan(int edmg_enable
, u8 edmg_channel
,
2247 int primary_channel
,
2248 struct ieee80211_edmg_config
*edmg
)
2252 edmg
->bw_config
= 0;
2256 /* Only EDMG CB1 and EDMG CB2 contiguous channels supported for now */
2257 switch (edmg_channel
) {
2258 case EDMG_CHANNEL_9
:
2259 edmg
->channels
= EDMG_CHANNEL_9_SUBCHANNELS
;
2260 edmg
->bw_config
= EDMG_BW_CONFIG_5
;
2262 case EDMG_CHANNEL_10
:
2263 edmg
->channels
= EDMG_CHANNEL_10_SUBCHANNELS
;
2264 edmg
->bw_config
= EDMG_BW_CONFIG_5
;
2266 case EDMG_CHANNEL_11
:
2267 edmg
->channels
= EDMG_CHANNEL_11_SUBCHANNELS
;
2268 edmg
->bw_config
= EDMG_BW_CONFIG_5
;
2270 case EDMG_CHANNEL_12
:
2271 edmg
->channels
= EDMG_CHANNEL_12_SUBCHANNELS
;
2272 edmg
->bw_config
= EDMG_BW_CONFIG_5
;
2274 case EDMG_CHANNEL_13
:
2275 edmg
->channels
= EDMG_CHANNEL_13_SUBCHANNELS
;
2276 edmg
->bw_config
= EDMG_BW_CONFIG_5
;
2279 if (primary_channel
> 0 && primary_channel
< 7) {
2280 edmg
->channels
= BIT(primary_channel
- 1);
2281 edmg
->bw_config
= EDMG_BW_CONFIG_4
;
2284 edmg
->bw_config
= 0;
2291 /* Check if the requested EDMG configuration is a subset of the allowed
2292 * EDMG configuration. */
2293 int ieee802_edmg_is_allowed(struct ieee80211_edmg_config allowed
,
2294 struct ieee80211_edmg_config requested
)
2297 * The validation check if the requested EDMG configuration
2298 * is a subset of the allowed EDMG configuration:
2299 * 1. Check that the requested channels are part (set) of the allowed
2301 * 2. P802.11ay defines the values of bw_config between 4 and 15.
2302 * (bw config % 4) will give us 4 groups inside bw_config definition,
2303 * inside each group we can check the subset just by comparing the
2305 * Between this 4 groups, there is no subset relation - as a result of
2306 * the P802.11ay definition.
2307 * bw_config defined by IEEE P802.11ay/D4.0, 9.4.2.251, Table 13.
2309 if (((requested
.channels
& allowed
.channels
) != requested
.channels
) ||
2310 ((requested
.bw_config
% 4) > (allowed
.bw_config
% 4)) ||
2311 requested
.bw_config
> allowed
.bw_config
)
2318 int op_class_to_bandwidth(u8 op_class
)
2324 case 83: /* channels 1..9; 40 MHz */
2325 case 84: /* channels 5..13; 40 MHz */
2327 case 115: /* channels 36,40,44,48; indoor only */
2329 case 116: /* channels 36,44; 40 MHz; indoor only */
2330 case 117: /* channels 40,48; 40 MHz; indoor only */
2332 case 118: /* channels 52,56,60,64; dfs */
2334 case 119: /* channels 52,60; 40 MHz; dfs */
2335 case 120: /* channels 56,64; 40 MHz; dfs */
2337 case 121: /* channels 100-140 */
2339 case 122: /* channels 100-142; 40 MHz */
2340 case 123: /* channels 104-136; 40 MHz */
2342 case 124: /* channels 149,153,157,161 */
2343 case 125: /* channels 149,153,157,161,165,169 */
2345 case 126: /* channels 149,157; 40 MHz */
2346 case 127: /* channels 153,161; 40 MHz */
2348 case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
2350 case 129: /* center freqs 50, 114; 160 MHz */
2352 case 130: /* center freqs 42, 58, 106, 122, 138, 155; 80+80 MHz */
2354 case 131: /* UHB channels, 20 MHz: 1, 5, 9.. */
2356 case 132: /* UHB channels, 40 MHz: 3, 11, 19.. */
2358 case 133: /* UHB channels, 80 MHz: 7, 23, 39.. */
2360 case 134: /* UHB channels, 160 MHz: 15, 47, 79.. */
2361 case 135: /* UHB channels, 80+80 MHz: 7, 23, 39.. */
2363 case 180: /* 60 GHz band, channels 1..8 */
2365 case 181: /* 60 GHz band, EDMG CB2, channels 9..15 */
2367 case 182: /* 60 GHz band, EDMG CB3, channels 17..22 */
2369 case 183: /* 60 GHz band, EDMG CB4, channel 25..29 */
2377 int op_class_to_ch_width(u8 op_class
)
2382 return CHANWIDTH_USE_HT
;
2383 case 83: /* channels 1..9; 40 MHz */
2384 case 84: /* channels 5..13; 40 MHz */
2385 return CHANWIDTH_USE_HT
;
2386 case 115: /* channels 36,40,44,48; indoor only */
2387 return CHANWIDTH_USE_HT
;
2388 case 116: /* channels 36,44; 40 MHz; indoor only */
2389 case 117: /* channels 40,48; 40 MHz; indoor only */
2390 return CHANWIDTH_USE_HT
;
2391 case 118: /* channels 52,56,60,64; dfs */
2392 return CHANWIDTH_USE_HT
;
2393 case 119: /* channels 52,60; 40 MHz; dfs */
2394 case 120: /* channels 56,64; 40 MHz; dfs */
2395 return CHANWIDTH_USE_HT
;
2396 case 121: /* channels 100-140 */
2397 return CHANWIDTH_USE_HT
;
2398 case 122: /* channels 100-142; 40 MHz */
2399 case 123: /* channels 104-136; 40 MHz */
2400 return CHANWIDTH_USE_HT
;
2401 case 124: /* channels 149,153,157,161 */
2402 case 125: /* channels 149,153,157,161,165,169 */
2403 return CHANWIDTH_USE_HT
;
2404 case 126: /* channels 149,157; 40 MHz */
2405 case 127: /* channels 153,161; 40 MHz */
2406 return CHANWIDTH_USE_HT
;
2407 case 128: /* center freqs 42, 58, 106, 122, 138, 155; 80 MHz */
2408 return CHANWIDTH_80MHZ
;
2409 case 129: /* center freqs 50, 114; 160 MHz */
2410 return CHANWIDTH_160MHZ
;
2411 case 130: /* center freqs 42, 58, 106, 122, 138, 155; 80+80 MHz */
2412 return CHANWIDTH_80P80MHZ
;
2413 case 131: /* UHB channels, 20 MHz: 1, 5, 9.. */
2414 return CHANWIDTH_USE_HT
;
2415 case 132: /* UHB channels, 40 MHz: 3, 11, 19.. */
2416 return CHANWIDTH_USE_HT
;
2417 case 133: /* UHB channels, 80 MHz: 7, 23, 39.. */
2418 return CHANWIDTH_80MHZ
;
2419 case 134: /* UHB channels, 160 MHz: 15, 47, 79.. */
2420 return CHANWIDTH_160MHZ
;
2421 case 135: /* UHB channels, 80+80 MHz: 7, 23, 39.. */
2422 return CHANWIDTH_80P80MHZ
;
2423 case 180: /* 60 GHz band, channels 1..8 */
2424 return CHANWIDTH_2160MHZ
;
2425 case 181: /* 60 GHz band, EDMG CB2, channels 9..15 */
2426 return CHANWIDTH_4320MHZ
;
2427 case 182: /* 60 GHz band, EDMG CB3, channels 17..22 */
2428 return CHANWIDTH_6480MHZ
;
2429 case 183: /* 60 GHz band, EDMG CB4, channel 25..29 */
2430 return CHANWIDTH_8640MHZ
;
2432 return CHANWIDTH_USE_HT
;
2436 struct wpabuf
* ieee802_11_defrag_data(struct ieee802_11_elems
*elems
,
2438 const u8
*data
, u8 len
)
2440 struct frag_ies_info
*frag_ies
= &elems
->frag_ies
;
2444 if (!elems
|| !data
|| !len
)
2447 buf
= wpabuf_alloc_copy(data
, len
);
2451 for (i
= 0; i
< frag_ies
->n_frags
; i
++) {
2454 if (frag_ies
->frags
[i
].eid
!= eid
||
2455 frag_ies
->frags
[i
].eid_ext
!= eid_ext
)
2458 ret
= wpabuf_resize(&buf
, frag_ies
->frags
[i
].ie_len
);
2464 /* Copy only the fragment data (without the EID and length) */
2465 wpabuf_put_data(buf
, frag_ies
->frags
[i
].ie
,
2466 frag_ies
->frags
[i
].ie_len
);
2473 struct wpabuf
* ieee802_11_defrag(struct ieee802_11_elems
*elems
,
2480 * TODO: Defragmentation mechanism can be supported for all IEs. For now
2481 * handle only those that are used (or use ieee802_11_defrag_data()).
2484 case WLAN_EID_EXTENSION
:
2486 case WLAN_EID_EXT_FILS_HLP_CONTAINER
:
2487 data
= elems
->fils_hlp
;
2488 len
= elems
->fils_hlp_len
;
2490 case WLAN_EID_EXT_WRAPPED_DATA
:
2491 data
= elems
->wrapped_data
;
2492 len
= elems
->wrapped_data_len
;
2495 wpa_printf(MSG_DEBUG
,
2496 "Defragmentation not supported. eid_ext=%u",
2502 wpa_printf(MSG_DEBUG
,
2503 "Defragmentation not supported. eid=%u", eid
);
2507 return ieee802_11_defrag_data(elems
, eid
, eid_ext
, data
, len
);