1 /*
2 * IEEE 802.11 Common routines
3 * Copyright (c) 2002-2019, Jouni Malinen <j@w1.fi>
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9 #include "includes.h"
10
11 #include "common.h"
12 #include "defs.h"
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"
18
19 #if defined(CONFIG_OPEN_HARMONY_PATCH) && defined(OPEN_HARMONY_MIRACAST_SINK_OPT)
20 #include "hm_miracast_sink.h"
21 #endif
22
ieee802_11_parse_vendor_specific(const u8 * pos,size_t elen,struct ieee802_11_elems * elems,int show_errors)23 static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen,
24 struct ieee802_11_elems *elems,
25 int show_errors)
26 {
27 unsigned int oui;
28
29 /* first 3 bytes in vendor specific information element are the IEEE
30 * OUI of the vendor. The following byte is used a vendor specific
31 * sub-type. */
32 if (elen < 4) {
33 if (show_errors) {
34 wpa_printf(MSG_MSGDUMP, "short vendor specific "
35 "information element ignored (len=%lu)",
36 (unsigned long) elen);
37 }
38 return -1;
39 }
40
41 oui = WPA_GET_BE24(pos);
42 switch (oui) {
43 case OUI_MICROSOFT:
44 /* Microsoft/Wi-Fi information elements are further typed and
45 * subtyped */
46 switch (pos[3]) {
47 case 1:
48 /* Microsoft OUI (00:50:F2) with OUI Type 1:
49 * real WPA information element */
50 elems->wpa_ie = pos;
51 elems->wpa_ie_len = elen;
52 break;
53 case WMM_OUI_TYPE:
54 /* WMM information element */
55 if (elen < 5) {
56 wpa_printf(MSG_MSGDUMP, "short WMM "
57 "information element ignored "
58 "(len=%lu)",
59 (unsigned long) elen);
60 return -1;
61 }
62 switch (pos[4]) {
63 case WMM_OUI_SUBTYPE_INFORMATION_ELEMENT:
64 case WMM_OUI_SUBTYPE_PARAMETER_ELEMENT:
65 /*
66 * Share same pointer since only one of these
67 * is used and they start with same data.
68 * Length field can be used to distinguish the
69 * IEs.
70 */
71 elems->wmm = pos;
72 elems->wmm_len = elen;
73 break;
74 case WMM_OUI_SUBTYPE_TSPEC_ELEMENT:
75 elems->wmm_tspec = pos;
76 elems->wmm_tspec_len = elen;
77 break;
78 default:
79 wpa_printf(MSG_EXCESSIVE, "unknown WMM "
80 "information element ignored "
81 "(subtype=%d len=%lu)",
82 pos[4], (unsigned long) elen);
83 return -1;
84 }
85 break;
86 case 4:
87 /* Wi-Fi Protected Setup (WPS) IE */
88 elems->wps_ie = pos;
89 elems->wps_ie_len = elen;
90 break;
91 default:
92 wpa_printf(MSG_EXCESSIVE, "Unknown Microsoft "
93 "information element ignored "
94 "(type=%d len=%lu)",
95 pos[3], (unsigned long) elen);
96 return -1;
97 }
98 break;
99
100 case OUI_WFA:
101 switch (pos[3]) {
102 case P2P_OUI_TYPE:
103 /* Wi-Fi Alliance - P2P IE */
104 elems->p2p = pos;
105 elems->p2p_len = elen;
106 break;
107 case WFD_OUI_TYPE:
108 /* Wi-Fi Alliance - WFD IE */
109 elems->wfd = pos;
110 elems->wfd_len = elen;
111 break;
112 case HS20_INDICATION_OUI_TYPE:
113 /* Hotspot 2.0 */
114 elems->hs20 = pos;
115 elems->hs20_len = elen;
116 break;
117 case HS20_OSEN_OUI_TYPE:
118 /* Hotspot 2.0 OSEN */
119 elems->osen = pos;
120 elems->osen_len = elen;
121 break;
122 case MBO_OUI_TYPE:
123 /* MBO-OCE */
124 elems->mbo = pos;
125 elems->mbo_len = elen;
126 break;
127 case HS20_ROAMING_CONS_SEL_OUI_TYPE:
128 /* Hotspot 2.0 Roaming Consortium Selection */
129 elems->roaming_cons_sel = pos;
130 elems->roaming_cons_sel_len = elen;
131 break;
132 case MULTI_AP_OUI_TYPE:
133 elems->multi_ap = pos;
134 elems->multi_ap_len = elen;
135 break;
136 case OWE_OUI_TYPE:
137 /* OWE Transition Mode element */
138 break;
139 case DPP_CC_OUI_TYPE:
140 /* DPP Configurator Connectivity element */
141 break;
142 case SAE_PK_OUI_TYPE:
143 elems->sae_pk = pos + 4;
144 elems->sae_pk_len = elen - 4;
145 break;
146 default:
147 wpa_printf(MSG_MSGDUMP, "Unknown WFA "
148 "information element ignored "
149 "(type=%d len=%lu)",
150 pos[3], (unsigned long) elen);
151 return -1;
152 }
153 break;
154
155 case OUI_BROADCOM:
156 switch (pos[3]) {
157 case VENDOR_HT_CAPAB_OUI_TYPE:
158 elems->vendor_ht_cap = pos;
159 elems->vendor_ht_cap_len = elen;
160 break;
161 case VENDOR_VHT_TYPE:
162 if (elen > 4 &&
163 (pos[4] == VENDOR_VHT_SUBTYPE ||
164 pos[4] == VENDOR_VHT_SUBTYPE2)) {
165 elems->vendor_vht = pos;
166 elems->vendor_vht_len = elen;
167 } else
168 return -1;
169 break;
170 default:
171 wpa_printf(MSG_EXCESSIVE, "Unknown Broadcom "
172 "information element ignored "
173 "(type=%d len=%lu)",
174 pos[3], (unsigned long) elen);
175 return -1;
176 }
177 break;
178
179 case OUI_QCA:
180 switch (pos[3]) {
181 case QCA_VENDOR_ELEM_P2P_PREF_CHAN_LIST:
182 elems->pref_freq_list = pos;
183 elems->pref_freq_list_len = elen;
184 break;
185 #if defined(CONFIG_OPEN_HARMONY_PATCH) && defined(OPEN_HARMONY_MIRACAST_SINK_OPT)
186 case HM_PVT_VENDOR_P2P_OUI:
187 if (hm_ieee80211_parse_vendor_opt_ie(pos, elen, elems))
188 wpa_printf(MSG_ERROR, "hm_ieee80211_parse_vendor_opt_ie parse vendor p2p oui fail");
189 break;
190 #endif
191 default:
192 wpa_printf(MSG_EXCESSIVE,
193 "Unknown QCA information element ignored (type=%d len=%lu)",
194 pos[3], (unsigned long) elen);
195 return -1;
196 }
197 break;
198
199 default:
200 wpa_printf(MSG_EXCESSIVE, "unknown vendor specific "
201 "information element ignored (vendor OUI "
202 "%02x:%02x:%02x len=%lu)",
203 pos[0], pos[1], pos[2], (unsigned long) elen);
204 return -1;
205 }
206
207 return 0;
208 }
209
210 #ifdef CONFIG_MLD_PATCH
ieee802_11_parse_mle(const u8 * pos,size_t elen,size_t ** total_len,struct ieee802_11_elems * elems,int show_errors)211 static int ieee802_11_parse_mle(const u8 *pos, size_t elen, size_t **total_len,
212 struct ieee802_11_elems *elems,
213 int show_errors)
214 {
215 u8 mle_type = pos[0] & MULTI_LINK_CONTROL_TYPE_MASK;
216
217 switch (mle_type) {
218 case MULTI_LINK_CONTROL_TYPE_BASIC:
219 elems->basic_mle = pos;
220 elems->basic_mle_len = elen;
221 *total_len = &elems->basic_mle_len;
222 break;
223 case MULTI_LINK_CONTROL_TYPE_PROBE_REQ:
224 elems->probe_req_mle = pos;
225 elems->probe_req_mle_len = elen;
226 *total_len = &elems->probe_req_mle_len;
227 break;
228 case MULTI_LINK_CONTROL_TYPE_RECONF:
229 elems->reconf_mle = pos;
230 elems->reconf_mle_len = elen;
231 *total_len = &elems->reconf_mle_len;
232 break;
233 case MULTI_LINK_CONTROL_TYPE_TDLS:
234 elems->tdls_mle = pos;
235 elems->tdls_mle_len = elen;
236 *total_len = &elems->tdls_mle_len;
237 break;
238 case MULTI_LINK_CONTROL_TYPE_PRIOR_ACCESS:
239 elems->prior_access_mle = pos;
240 elems->prior_access_mle_len = elen;
241 *total_len = &elems->prior_access_mle_len;
242 break;
243 default:
244 if (show_errors) {
245 wpa_printf(MSG_MSGDUMP,
246 "Unknown Multi-Link element type %u",
247 mle_type);
248 }
249 return -1;
250 }
251
252 return 0;
253 }
254
255
ieee802_11_fragments_length(struct ieee802_11_elems * elems,const u8 * start,size_t len)256 static size_t ieee802_11_fragments_length(struct ieee802_11_elems *elems,
257 const u8 *start, size_t len)
258 {
259 const struct element *elem;
260 size_t frags_len = 0;
261
262 for_each_element(elem, start, len) {
263 if (elem->id != WLAN_EID_FRAGMENT)
264 break;
265
266 frags_len += elem->datalen + 2;
267 elems->num_frag_elems++;
268 }
269
270 return frags_len;
271 }
272 #endif
273
ieee802_11_parse_extension(const u8 * pos,size_t elen,struct ieee802_11_elems * elems,const u8 * start,size_t len,int show_errors)274 static int ieee802_11_parse_extension(const u8 *pos, size_t elen,
275 struct ieee802_11_elems *elems,
276 #ifdef CONFIG_MLD_PATCH
277 const u8 *start, size_t len,
278 #endif
279 int show_errors)
280 {
281 u8 ext_id;
282 #ifdef CONFIG_MLD_PATCH
283 size_t *total_len = NULL;
284 #endif
285 if (elen < 1) {
286 if (show_errors) {
287 wpa_printf(MSG_MSGDUMP,
288 "short information element (Ext)");
289 }
290 return -1;
291 }
292
293 ext_id = *pos++;
294 elen--;
295 #ifndef CONFIG_MLD_PATCH
296 elems->frag_ies.last_eid_ext = 0;
297 #endif
298 switch (ext_id) {
299 case WLAN_EID_EXT_ASSOC_DELAY_INFO:
300 if (elen != 1)
301 break;
302 elems->assoc_delay_info = pos;
303 break;
304 case WLAN_EID_EXT_FILS_REQ_PARAMS:
305 if (elen < 3)
306 break;
307 elems->fils_req_params = pos;
308 elems->fils_req_params_len = elen;
309 break;
310 case WLAN_EID_EXT_FILS_KEY_CONFIRM:
311 elems->fils_key_confirm = pos;
312 elems->fils_key_confirm_len = elen;
313 break;
314 case WLAN_EID_EXT_FILS_SESSION:
315 if (elen != FILS_SESSION_LEN)
316 break;
317 elems->fils_session = pos;
318 break;
319 case WLAN_EID_EXT_FILS_HLP_CONTAINER:
320 if (elen < 2 * ETH_ALEN)
321 break;
322 elems->fils_hlp = pos;
323 elems->fils_hlp_len = elen;
324 #ifdef CONFIG_MLD_PATCH
325 total_len = &elems->fils_hlp_len;
326 #endif
327 break;
328 case WLAN_EID_EXT_FILS_IP_ADDR_ASSIGN:
329 if (elen < 1)
330 break;
331 elems->fils_ip_addr_assign = pos;
332 elems->fils_ip_addr_assign_len = elen;
333 break;
334 case WLAN_EID_EXT_KEY_DELIVERY:
335 if (elen < WPA_KEY_RSC_LEN)
336 break;
337 elems->key_delivery = pos;
338 elems->key_delivery_len = elen;
339 break;
340 case WLAN_EID_EXT_WRAPPED_DATA:
341 elems->wrapped_data = pos;
342 elems->wrapped_data_len = elen;
343 #ifdef CONFIG_MLD_PATCH
344 total_len = &elems->wrapped_data_len;
345 #endif
346 break;
347 case WLAN_EID_EXT_FILS_PUBLIC_KEY:
348 if (elen < 1)
349 break;
350 elems->fils_pk = pos;
351 elems->fils_pk_len = elen;
352 break;
353 case WLAN_EID_EXT_FILS_NONCE:
354 if (elen != FILS_NONCE_LEN)
355 break;
356 elems->fils_nonce = pos;
357 break;
358 case WLAN_EID_EXT_OWE_DH_PARAM:
359 if (elen < 2)
360 break;
361 elems->owe_dh = pos;
362 elems->owe_dh_len = elen;
363 break;
364 case WLAN_EID_EXT_PASSWORD_IDENTIFIER:
365 elems->password_id = pos;
366 elems->password_id_len = elen;
367 break;
368 case WLAN_EID_EXT_HE_CAPABILITIES:
369 elems->he_capabilities = pos;
370 elems->he_capabilities_len = elen;
371 break;
372 case WLAN_EID_EXT_HE_OPERATION:
373 elems->he_operation = pos;
374 elems->he_operation_len = elen;
375 break;
376 case WLAN_EID_EXT_OCV_OCI:
377 elems->oci = pos;
378 elems->oci_len = elen;
379 break;
380 case WLAN_EID_EXT_SHORT_SSID_LIST:
381 elems->short_ssid_list = pos;
382 elems->short_ssid_list_len = elen;
383 break;
384 case WLAN_EID_EXT_HE_6GHZ_BAND_CAP:
385 if (elen < sizeof(struct ieee80211_he_6ghz_band_cap))
386 break;
387 elems->he_6ghz_band_cap = pos;
388 break;
389 case WLAN_EID_EXT_PASN_PARAMS:
390 elems->pasn_params = pos;
391 elems->pasn_params_len = elen;
392 break;
393 #ifdef CONFIG_MLD_PATCH
394 case WLAN_EID_EXT_EHT_CAPABILITIES:
395 if (elen < EHT_CAPABILITIES_IE_MIN_LEN)
396 break;
397 elems->eht_capabilities = pos;
398 elems->eht_capabilities_len = elen;
399 break;
400 case WLAN_EID_EXT_EHT_OPERATION:
401 if (elen < EHT_OPERATION_IE_MIN_LEN)
402 break;
403 elems->eht_operation = pos;
404 elems->eht_operation_len = elen;
405 break;
406 case WLAN_EID_EXT_MULTI_LINK:
407 if (elen < 2)
408 break;
409 if (ieee802_11_parse_mle(pos, elen, &total_len, elems,
410 show_errors))
411 return -1;
412 break;
413 case WLAN_EID_EXT_KNOWN_BSSID:
414 elems->mbssid_known_bss = pos;
415 elems->mbssid_known_bss_len = elen;
416 break;
417 case WLAN_EID_EXT_AKM_SUITE_SELECTOR:
418 // MLD AKM24 Ap auth frame contains AKM_SUITE_SELECTOR IE
419 break;
420 #endif
421 default:
422 if (show_errors) {
423 wpa_printf(MSG_MSGDUMP,
424 "IEEE 802.11 element parsing ignored unknown element extension (ext_id=%u elen=%u)",
425 ext_id, (unsigned int) elen);
426 }
427 return -1;
428 }
429 #ifdef CONFIG_MLD_PATCH
430 if (elen == 254 && total_len)
431 *total_len += ieee802_11_fragments_length(
432 elems, pos + elen, (start + len) - (pos + elen));
433 #else
434 if (elen == 254)
435 elems->frag_ies.last_eid_ext = ext_id;
436 #endif
437 return 0;
438 }
439
440 #ifndef CONFIG_MLD_PATCH
ieee802_11_parse_fragment(struct frag_ies_info * frag_ies,const u8 * pos,u8 elen)441 static void ieee802_11_parse_fragment(struct frag_ies_info *frag_ies,
442 const u8 *pos, u8 elen)
443 {
444 if (frag_ies->n_frags >= MAX_NUM_FRAG_IES_SUPPORTED) {
445 wpa_printf(MSG_MSGDUMP, "Too many element fragments - skip");
446 return;
447 }
448
449 /*
450 * Note: while EID == 0 is a valid ID (SSID IE), it should not be
451 * fragmented.
452 */
453 if (!frag_ies->last_eid) {
454 wpa_printf(MSG_MSGDUMP,
455 "Fragment without a valid last element - skip");
456 return;
457 }
458
459 frag_ies->frags[frag_ies->n_frags].ie = pos;
460 frag_ies->frags[frag_ies->n_frags].ie_len = elen;
461 frag_ies->frags[frag_ies->n_frags].eid = frag_ies->last_eid;
462 frag_ies->frags[frag_ies->n_frags].eid_ext = frag_ies->last_eid_ext;
463 frag_ies->n_frags++;
464 }
465 #endif
466
467 /**
468 * ieee802_11_parse_elems - Parse information elements in management frames
469 * @start: Pointer to the start of IEs
470 * @len: Length of IE buffer in octets
471 * @elems: Data structure for parsed elements
472 * @show_errors: Whether to show parsing errors in debug log
473 * Returns: Parsing result
474 */
ieee802_11_parse_elems(const u8 * start,size_t len,struct ieee802_11_elems * elems,int show_errors)475 ParseRes ieee802_11_parse_elems(const u8 *start, size_t len,
476 struct ieee802_11_elems *elems,
477 int show_errors)
478 {
479 const struct element *elem;
480 int unknown = 0;
481
482 os_memset(elems, 0, sizeof(*elems));
483
484 if (!start)
485 return ParseOK;
486
487 for_each_element(elem, start, len) {
488 u8 id = elem->id, elen = elem->datalen;
489 const u8 *pos = elem->data;
490 #ifdef CONFIG_MLD_PATCH
491 size_t *total_len = NULL;
492
493 if (id == WLAN_EID_FRAGMENT && elems->num_frag_elems > 0) {
494 elems->num_frag_elems--;
495 continue;
496 }
497 elems->num_frag_elems = 0;
498 #endif
499 switch (id) {
500 case WLAN_EID_SSID:
501 if (elen > SSID_MAX_LEN) {
502 wpa_printf(MSG_DEBUG,
503 "Ignored too long SSID element (elen=%u)",
504 elen);
505 break;
506 }
507 if (elems->ssid) {
508 wpa_printf(MSG_MSGDUMP,
509 "Ignored duplicated SSID element");
510 break;
511 }
512 elems->ssid = pos;
513 elems->ssid_len = elen;
514 break;
515 case WLAN_EID_SUPP_RATES:
516 elems->supp_rates = pos;
517 elems->supp_rates_len = elen;
518 break;
519 case WLAN_EID_DS_PARAMS:
520 if (elen < 1)
521 break;
522 elems->ds_params = pos;
523 break;
524 case WLAN_EID_CF_PARAMS:
525 case WLAN_EID_TIM:
526 break;
527 case WLAN_EID_CHALLENGE:
528 elems->challenge = pos;
529 elems->challenge_len = elen;
530 break;
531 case WLAN_EID_ERP_INFO:
532 if (elen < 1)
533 break;
534 elems->erp_info = pos;
535 break;
536 case WLAN_EID_EXT_SUPP_RATES:
537 elems->ext_supp_rates = pos;
538 elems->ext_supp_rates_len = elen;
539 break;
540 case WLAN_EID_VENDOR_SPECIFIC:
541 if (ieee802_11_parse_vendor_specific(pos, elen,
542 elems,
543 show_errors))
544 unknown++;
545 break;
546 case WLAN_EID_RSN:
547 elems->rsn_ie = pos;
548 elems->rsn_ie_len = elen;
549 break;
550 case WLAN_EID_RSNX:
551 elems->rsnxe = pos;
552 elems->rsnxe_len = elen;
553 break;
554 case WLAN_EID_PWR_CAPABILITY:
555 if (elen < 2)
556 break;
557 elems->power_capab = pos;
558 elems->power_capab_len = elen;
559 break;
560 case WLAN_EID_SUPPORTED_CHANNELS:
561 elems->supp_channels = pos;
562 elems->supp_channels_len = elen;
563 break;
564 case WLAN_EID_MOBILITY_DOMAIN:
565 if (elen < sizeof(struct rsn_mdie))
566 break;
567 elems->mdie = pos;
568 elems->mdie_len = elen;
569 break;
570 case WLAN_EID_FAST_BSS_TRANSITION:
571 if (elen < sizeof(struct rsn_ftie))
572 break;
573 elems->ftie = pos;
574 elems->ftie_len = elen;
575 #ifdef CONFIG_MLD_PATCH
576 elems->fte_defrag_len = elen;
577 total_len = &elems->fte_defrag_len;
578 #endif
579 break;
580 case WLAN_EID_TIMEOUT_INTERVAL:
581 if (elen != 5)
582 break;
583 elems->timeout_int = pos;
584 break;
585 case WLAN_EID_HT_CAP:
586 if (elen < sizeof(struct ieee80211_ht_capabilities))
587 break;
588 elems->ht_capabilities = pos;
589 break;
590 case WLAN_EID_HT_OPERATION:
591 if (elen < sizeof(struct ieee80211_ht_operation))
592 break;
593 elems->ht_operation = pos;
594 break;
595 case WLAN_EID_MESH_CONFIG:
596 elems->mesh_config = pos;
597 elems->mesh_config_len = elen;
598 break;
599 case WLAN_EID_MESH_ID:
600 elems->mesh_id = pos;
601 elems->mesh_id_len = elen;
602 break;
603 case WLAN_EID_PEER_MGMT:
604 elems->peer_mgmt = pos;
605 elems->peer_mgmt_len = elen;
606 break;
607 case WLAN_EID_VHT_CAP:
608 if (elen < sizeof(struct ieee80211_vht_capabilities))
609 break;
610 elems->vht_capabilities = pos;
611 break;
612 case WLAN_EID_VHT_OPERATION:
613 if (elen < sizeof(struct ieee80211_vht_operation))
614 break;
615 elems->vht_operation = pos;
616 break;
617 case WLAN_EID_VHT_OPERATING_MODE_NOTIFICATION:
618 if (elen != 1)
619 break;
620 elems->vht_opmode_notif = pos;
621 break;
622 case WLAN_EID_LINK_ID:
623 if (elen < 18)
624 break;
625 elems->link_id = pos;
626 break;
627 case WLAN_EID_INTERWORKING:
628 elems->interworking = pos;
629 elems->interworking_len = elen;
630 break;
631 case WLAN_EID_QOS_MAP_SET:
632 if (elen < 16)
633 break;
634 elems->qos_map_set = pos;
635 elems->qos_map_set_len = elen;
636 break;
637 case WLAN_EID_EXT_CAPAB:
638 elems->ext_capab = pos;
639 elems->ext_capab_len = elen;
640 break;
641 case WLAN_EID_BSS_MAX_IDLE_PERIOD:
642 if (elen < 3)
643 break;
644 elems->bss_max_idle_period = pos;
645 break;
646 case WLAN_EID_SSID_LIST:
647 elems->ssid_list = pos;
648 elems->ssid_list_len = elen;
649 break;
650 case WLAN_EID_AMPE:
651 elems->ampe = pos;
652 elems->ampe_len = elen;
653 break;
654 case WLAN_EID_MIC:
655 elems->mic = pos;
656 elems->mic_len = elen;
657 /* after mic everything is encrypted, so stop. */
658 goto done;
659 case WLAN_EID_MULTI_BAND:
660 if (elems->mb_ies.nof_ies >= MAX_NOF_MB_IES_SUPPORTED) {
661 wpa_printf(MSG_MSGDUMP,
662 "IEEE 802.11 element parse ignored MB IE (id=%d elen=%d)",
663 id, elen);
664 break;
665 }
666
667 elems->mb_ies.ies[elems->mb_ies.nof_ies].ie = pos;
668 elems->mb_ies.ies[elems->mb_ies.nof_ies].ie_len = elen;
669 elems->mb_ies.nof_ies++;
670 break;
671 case WLAN_EID_SUPPORTED_OPERATING_CLASSES:
672 elems->supp_op_classes = pos;
673 elems->supp_op_classes_len = elen;
674 break;
675 case WLAN_EID_RRM_ENABLED_CAPABILITIES:
676 elems->rrm_enabled = pos;
677 elems->rrm_enabled_len = elen;
678 break;
679 case WLAN_EID_CAG_NUMBER:
680 elems->cag_number = pos;
681 elems->cag_number_len = elen;
682 break;
683 case WLAN_EID_AP_CSN:
684 if (elen < 1)
685 break;
686 elems->ap_csn = pos;
687 break;
688 case WLAN_EID_FILS_INDICATION:
689 if (elen < 2)
690 break;
691 elems->fils_indic = pos;
692 elems->fils_indic_len = elen;
693 break;
694 case WLAN_EID_DILS:
695 if (elen < 2)
696 break;
697 elems->dils = pos;
698 elems->dils_len = elen;
699 break;
700 case WLAN_EID_S1G_CAPABILITIES:
701 if (elen < 15)
702 break;
703 elems->s1g_capab = pos;
704 break;
705 case WLAN_EID_FRAGMENT:
706 #ifdef CONFIG_MLD_PATCH
707 wpa_printf(MSG_MSGDUMP,
708 "Fragment without a valid last element - skip");
709 #else
710 ieee802_11_parse_fragment(&elems->frag_ies, pos, elen);
711 #endif
712 break;
713 case WLAN_EID_EXTENSION:
714 if (ieee802_11_parse_extension(pos, elen, elems,
715 #ifdef CONFIG_MLD_PATCH
716 start, len,
717 #endif
718 show_errors))
719 unknown++;
720 break;
721 default:
722 unknown++;
723 if (!show_errors)
724 break;
725 wpa_printf(MSG_MSGDUMP, "IEEE 802.11 element parse "
726 "ignored unknown element (id=%d elen=%d)",
727 id, elen);
728 break;
729 }
730 #ifdef CONFIG_MLD_PATCH
731 if (elen == 255 && total_len)
732 *total_len += ieee802_11_fragments_length(
733 elems, pos + elen,
734 (start + len) - (pos + elen));
735 #else
736 if (id != WLAN_EID_FRAGMENT && elen == 255)
737 elems->frag_ies.last_eid = id;
738
739 if (id == WLAN_EID_EXTENSION && !elems->frag_ies.last_eid_ext)
740 elems->frag_ies.last_eid = 0;
741 #endif
742 }
743
744 if (!for_each_element_completed(elem, start, len)) {
745 if (show_errors) {
746 wpa_printf(MSG_DEBUG,
747 "IEEE 802.11 element parse failed @%d",
748 (int) (start + len - (const u8 *) elem));
749 wpa_hexdump(MSG_MSGDUMP, "IEs", start, len);
750 }
751 return ParseFailed;
752 }
753
754 done:
755 return unknown ? ParseUnknown : ParseOK;
756 }
757
758
ieee802_11_ie_count(const u8 * ies,size_t ies_len)759 int ieee802_11_ie_count(const u8 *ies, size_t ies_len)
760 {
761 const struct element *elem;
762 int count = 0;
763
764 if (ies == NULL)
765 return 0;
766
767 for_each_element(elem, ies, ies_len)
768 count++;
769
770 return count;
771 }
772
773
ieee802_11_vendor_ie_concat(const u8 * ies,size_t ies_len,u32 oui_type)774 struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len,
775 u32 oui_type)
776 {
777 struct wpabuf *buf;
778 const struct element *elem, *found = NULL;
779
780 for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, ies_len) {
781 if (elem->datalen >= 4 &&
782 WPA_GET_BE32(elem->data) == oui_type) {
783 found = elem;
784 break;
785 }
786 }
787
788 if (!found)
789 return NULL; /* No specified vendor IE found */
790
791 buf = wpabuf_alloc(ies_len);
792 if (buf == NULL)
793 return NULL;
794
795 /*
796 * There may be multiple vendor IEs in the message, so need to
797 * concatenate their data fields.
798 */
799 for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, ies_len) {
800 if (elem->datalen >= 4 && WPA_GET_BE32(elem->data) == oui_type)
801 wpabuf_put_data(buf, elem->data + 4, elem->datalen - 4);
802 }
803
804 return buf;
805 }
806
807
get_hdr_bssid(const struct ieee80211_hdr * hdr,size_t len)808 const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len)
809 {
810 u16 fc, type, stype;
811
812 /*
813 * PS-Poll frames are 16 bytes. All other frames are
814 * 24 bytes or longer.
815 */
816 if (len < 16)
817 return NULL;
818
819 fc = le_to_host16(hdr->frame_control);
820 type = WLAN_FC_GET_TYPE(fc);
821 stype = WLAN_FC_GET_STYPE(fc);
822
823 switch (type) {
824 case WLAN_FC_TYPE_DATA:
825 if (len < 24)
826 return NULL;
827 switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
828 case WLAN_FC_FROMDS | WLAN_FC_TODS:
829 case WLAN_FC_TODS:
830 return hdr->addr1;
831 case WLAN_FC_FROMDS:
832 return hdr->addr2;
833 default:
834 return NULL;
835 }
836 case WLAN_FC_TYPE_CTRL:
837 if (stype != WLAN_FC_STYPE_PSPOLL)
838 return NULL;
839 return hdr->addr1;
840 case WLAN_FC_TYPE_MGMT:
841 return hdr->addr3;
842 default:
843 return NULL;
844 }
845 }
846
847
hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[],const char * name,const char * val)848 int hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[],
849 const char *name, const char *val)
850 {
851 int num, v;
852 const char *pos;
853 struct hostapd_wmm_ac_params *ac;
854
855 /* skip 'wme_ac_' or 'wmm_ac_' prefix */
856 pos = name + 7;
857 if (os_strncmp(pos, "be_", 3) == 0) {
858 num = 0;
859 pos += 3;
860 } else if (os_strncmp(pos, "bk_", 3) == 0) {
861 num = 1;
862 pos += 3;
863 } else if (os_strncmp(pos, "vi_", 3) == 0) {
864 num = 2;
865 pos += 3;
866 } else if (os_strncmp(pos, "vo_", 3) == 0) {
867 num = 3;
868 pos += 3;
869 } else {
870 wpa_printf(MSG_ERROR, "Unknown WMM name '%s'", pos);
871 return -1;
872 }
873
874 ac = &wmm_ac_params[num];
875
876 if (os_strcmp(pos, "aifs") == 0) {
877 v = atoi(val);
878 if (v < 1 || v > 255) {
879 wpa_printf(MSG_ERROR, "Invalid AIFS value %d", v);
880 return -1;
881 }
882 ac->aifs = v;
883 } else if (os_strcmp(pos, "cwmin") == 0) {
884 v = atoi(val);
885 if (v < 0 || v > 15) {
886 wpa_printf(MSG_ERROR, "Invalid cwMin value %d", v);
887 return -1;
888 }
889 ac->cwmin = v;
890 } else if (os_strcmp(pos, "cwmax") == 0) {
891 v = atoi(val);
892 if (v < 0 || v > 15) {
893 wpa_printf(MSG_ERROR, "Invalid cwMax value %d", v);
894 return -1;
895 }
896 ac->cwmax = v;
897 } else if (os_strcmp(pos, "txop_limit") == 0) {
898 v = atoi(val);
899 if (v < 0 || v > 0xffff) {
900 wpa_printf(MSG_ERROR, "Invalid txop value %d", v);
901 return -1;
902 }
903 ac->txop_limit = v;
904 } else if (os_strcmp(pos, "acm") == 0) {
905 v = atoi(val);
906 if (v < 0 || v > 1) {
907 wpa_printf(MSG_ERROR, "Invalid acm value %d", v);
908 return -1;
909 }
910 ac->admission_control_mandatory = v;
911 } else {
912 wpa_printf(MSG_ERROR, "Unknown wmm_ac_ field '%s'", pos);
913 return -1;
914 }
915
916 return 0;
917 }
918
919
920 /* convert floats with one decimal place to value*10 int, i.e.,
921 * "1.5" will return 15
922 */
hostapd_config_read_int10(const char * value)923 static int hostapd_config_read_int10(const char *value)
924 {
925 int i, d;
926 char *pos;
927
928 i = atoi(value);
929 pos = os_strchr(value, '.');
930 d = 0;
931 if (pos) {
932 pos++;
933 if (*pos >= '0' && *pos <= '9')
934 d = *pos - '0';
935 }
936
937 return i * 10 + d;
938 }
939
940
valid_cw(int cw)941 static int valid_cw(int cw)
942 {
943 return (cw == 1 || cw == 3 || cw == 7 || cw == 15 || cw == 31 ||
944 cw == 63 || cw == 127 || cw == 255 || cw == 511 || cw == 1023 ||
945 cw == 2047 || cw == 4095 || cw == 8191 || cw == 16383 ||
946 cw == 32767);
947 }
948
949
hostapd_config_tx_queue(struct hostapd_tx_queue_params tx_queue[],const char * name,const char * val)950 int hostapd_config_tx_queue(struct hostapd_tx_queue_params tx_queue[],
951 const char *name, const char *val)
952 {
953 int num;
954 const char *pos;
955 struct hostapd_tx_queue_params *queue;
956
957 /* skip 'tx_queue_' prefix */
958 pos = name + 9;
959 if (os_strncmp(pos, "data", 4) == 0 &&
960 pos[4] >= '0' && pos[4] <= '9' && pos[5] == '_') {
961 num = pos[4] - '0';
962 pos += 6;
963 } else if (os_strncmp(pos, "after_beacon_", 13) == 0 ||
964 os_strncmp(pos, "beacon_", 7) == 0) {
965 wpa_printf(MSG_INFO, "DEPRECATED: '%s' not used", name);
966 return 0;
967 } else {
968 wpa_printf(MSG_ERROR, "Unknown tx_queue name '%s'", pos);
969 return -1;
970 }
971
972 if (num >= NUM_TX_QUEUES) {
973 /* for backwards compatibility, do not trigger failure */
974 wpa_printf(MSG_INFO, "DEPRECATED: '%s' not used", name);
975 return 0;
976 }
977
978 queue = &tx_queue[num];
979
980 if (os_strcmp(pos, "aifs") == 0) {
981 queue->aifs = atoi(val);
982 if (queue->aifs < 0 || queue->aifs > 255) {
983 wpa_printf(MSG_ERROR, "Invalid AIFS value %d",
984 queue->aifs);
985 return -1;
986 }
987 } else if (os_strcmp(pos, "cwmin") == 0) {
988 queue->cwmin = atoi(val);
989 if (!valid_cw(queue->cwmin)) {
990 wpa_printf(MSG_ERROR, "Invalid cwMin value %d",
991 queue->cwmin);
992 return -1;
993 }
994 } else if (os_strcmp(pos, "cwmax") == 0) {
995 queue->cwmax = atoi(val);
996 if (!valid_cw(queue->cwmax)) {
997 wpa_printf(MSG_ERROR, "Invalid cwMax value %d",
998 queue->cwmax);
999 return -1;
1000 }
1001 } else if (os_strcmp(pos, "burst") == 0) {
1002 queue->burst = hostapd_config_read_int10(val);
1003 } else {
1004 wpa_printf(MSG_ERROR, "Unknown queue field '%s'", pos);
1005 return -1;
1006 }
1007
1008 return 0;
1009 }
1010
1011
ieee80211_freq_to_chan(int freq,u8 * channel)1012 enum hostapd_hw_mode ieee80211_freq_to_chan(int freq, u8 *channel)
1013 {
1014 u8 op_class;
1015
1016 return ieee80211_freq_to_channel_ext(freq, 0, CHANWIDTH_USE_HT,
1017 &op_class, channel);
1018 }
1019
1020
1021 /**
1022 * ieee80211_freq_to_channel_ext - Convert frequency into channel info
1023 * for HT40, VHT, and HE. DFS channels are not covered.
1024 * @freq: Frequency (MHz) to convert
1025 * @sec_channel: 0 = non-HT40, 1 = sec. channel above, -1 = sec. channel below
1026 * @chanwidth: VHT/EDMG channel width (CHANWIDTH_*)
1027 * @op_class: Buffer for returning operating class
1028 * @channel: Buffer for returning channel number
1029 * Returns: hw_mode on success, NUM_HOSTAPD_MODES on failure
1030 */
ieee80211_freq_to_channel_ext(unsigned int freq,int sec_channel,int chanwidth,u8 * op_class,u8 * channel)1031 enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
1032 int sec_channel,
1033 int chanwidth,
1034 u8 *op_class, u8 *channel)
1035 {
1036 u8 vht_opclass;
1037
1038 /* TODO: more operating classes */
1039
1040 if (sec_channel > 1 || sec_channel < -1)
1041 return NUM_HOSTAPD_MODES;
1042
1043 if (freq >= 2412 && freq <= 2472) {
1044 if ((freq - 2407) % 5)
1045 return NUM_HOSTAPD_MODES;
1046
1047 if (chanwidth)
1048 return NUM_HOSTAPD_MODES;
1049
1050 /* 2.407 GHz, channels 1..13 */
1051 if (sec_channel == 1)
1052 *op_class = 83;
1053 else if (sec_channel == -1)
1054 *op_class = 84;
1055 else
1056 *op_class = 81;
1057
1058 *channel = (freq - 2407) / 5;
1059
1060 return HOSTAPD_MODE_IEEE80211G;
1061 }
1062
1063 if (freq == 2484) {
1064 if (sec_channel || chanwidth)
1065 return NUM_HOSTAPD_MODES;
1066
1067 *op_class = 82; /* channel 14 */
1068 *channel = 14;
1069
1070 return HOSTAPD_MODE_IEEE80211B;
1071 }
1072
1073 if (freq >= 4900 && freq < 5000) {
1074 if ((freq - 4000) % 5)
1075 return NUM_HOSTAPD_MODES;
1076 *channel = (freq - 4000) / 5;
1077 *op_class = 0; /* TODO */
1078 return HOSTAPD_MODE_IEEE80211A;
1079 }
1080
1081 switch (chanwidth) {
1082 case CHANWIDTH_80MHZ:
1083 vht_opclass = 128;
1084 break;
1085 case CHANWIDTH_160MHZ:
1086 vht_opclass = 129;
1087 break;
1088 case CHANWIDTH_80P80MHZ:
1089 vht_opclass = 130;
1090 break;
1091 default:
1092 vht_opclass = 0;
1093 break;
1094 }
1095
1096 /* 5 GHz, channels 36..48 */
1097 if (freq >= 5180 && freq <= 5240) {
1098 if ((freq - 5000) % 5)
1099 return NUM_HOSTAPD_MODES;
1100
1101 if (vht_opclass)
1102 *op_class = vht_opclass;
1103 else if (sec_channel == 1)
1104 *op_class = 116;
1105 else if (sec_channel == -1)
1106 *op_class = 117;
1107 else
1108 *op_class = 115;
1109
1110 *channel = (freq - 5000) / 5;
1111
1112 return HOSTAPD_MODE_IEEE80211A;
1113 }
1114
1115 /* 5 GHz, channels 52..64 */
1116 if (freq >= 5260 && freq <= 5320) {
1117 if ((freq - 5000) % 5)
1118 return NUM_HOSTAPD_MODES;
1119
1120 if (vht_opclass)
1121 *op_class = vht_opclass;
1122 else if (sec_channel == 1)
1123 *op_class = 119;
1124 else if (sec_channel == -1)
1125 *op_class = 120;
1126 else
1127 *op_class = 118;
1128
1129 *channel = (freq - 5000) / 5;
1130
1131 return HOSTAPD_MODE_IEEE80211A;
1132 }
1133
1134 /* 5 GHz, channels 149..177 */
1135 if (freq >= 5745 && freq <= 5885) {
1136 if ((freq - 5000) % 5)
1137 return NUM_HOSTAPD_MODES;
1138
1139 if (vht_opclass)
1140 *op_class = vht_opclass;
1141 else if (sec_channel == 1)
1142 *op_class = 126;
1143 else if (sec_channel == -1)
1144 *op_class = 127;
1145 else if (freq <= 5805)
1146 *op_class = 124;
1147 else
1148 *op_class = 125;
1149
1150 *channel = (freq - 5000) / 5;
1151
1152 return HOSTAPD_MODE_IEEE80211A;
1153 }
1154
1155 /* 5 GHz, channels 100..144 */
1156 if (freq >= 5500 && freq <= 5720) {
1157 if ((freq - 5000) % 5)
1158 return NUM_HOSTAPD_MODES;
1159
1160 if (vht_opclass)
1161 *op_class = vht_opclass;
1162 else if (sec_channel == 1)
1163 *op_class = 122;
1164 else if (sec_channel == -1)
1165 *op_class = 123;
1166 else
1167 *op_class = 121;
1168
1169 *channel = (freq - 5000) / 5;
1170
1171 return HOSTAPD_MODE_IEEE80211A;
1172 }
1173
1174 if (freq >= 5000 && freq < 5900) {
1175 if ((freq - 5000) % 5)
1176 return NUM_HOSTAPD_MODES;
1177 *channel = (freq - 5000) / 5;
1178 *op_class = 0; /* TODO */
1179 return HOSTAPD_MODE_IEEE80211A;
1180 }
1181
1182 if (freq > 5950 && freq <= 7115) {
1183 if ((freq - 5950) % 5)
1184 return NUM_HOSTAPD_MODES;
1185
1186 switch (chanwidth) {
1187 case CHANWIDTH_80MHZ:
1188 *op_class = 133;
1189 break;
1190 case CHANWIDTH_160MHZ:
1191 *op_class = 134;
1192 break;
1193 case CHANWIDTH_80P80MHZ:
1194 *op_class = 135;
1195 break;
1196 default:
1197 if (sec_channel)
1198 *op_class = 132;
1199 else
1200 *op_class = 131;
1201 break;
1202 }
1203
1204 *channel = (freq - 5950) / 5;
1205 return HOSTAPD_MODE_IEEE80211A;
1206 }
1207
1208 if (freq == 5935) {
1209 *op_class = 136;
1210 *channel = (freq - 5925) / 5;
1211 return HOSTAPD_MODE_IEEE80211A;
1212 }
1213
1214 /* 56.16 GHz, channel 1..6 */
1215 if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 6) {
1216 if (sec_channel)
1217 return NUM_HOSTAPD_MODES;
1218
1219 switch (chanwidth) {
1220 case CHANWIDTH_USE_HT:
1221 case CHANWIDTH_2160MHZ:
1222 *channel = (freq - 56160) / 2160;
1223 *op_class = 180;
1224 break;
1225 case CHANWIDTH_4320MHZ:
1226 /* EDMG channels 9 - 13 */
1227 if (freq > 56160 + 2160 * 5)
1228 return NUM_HOSTAPD_MODES;
1229
1230 *channel = (freq - 56160) / 2160 + 8;
1231 *op_class = 181;
1232 break;
1233 case CHANWIDTH_6480MHZ:
1234 /* EDMG channels 17 - 20 */
1235 if (freq > 56160 + 2160 * 4)
1236 return NUM_HOSTAPD_MODES;
1237
1238 *channel = (freq - 56160) / 2160 + 16;
1239 *op_class = 182;
1240 break;
1241 case CHANWIDTH_8640MHZ:
1242 /* EDMG channels 25 - 27 */
1243 if (freq > 56160 + 2160 * 3)
1244 return NUM_HOSTAPD_MODES;
1245
1246 *channel = (freq - 56160) / 2160 + 24;
1247 *op_class = 183;
1248 break;
1249 default:
1250 return NUM_HOSTAPD_MODES;
1251 }
1252
1253 return HOSTAPD_MODE_IEEE80211AD;
1254 }
1255
1256 return NUM_HOSTAPD_MODES;
1257 }
1258
1259
ieee80211_chaninfo_to_channel(unsigned int freq,enum chan_width chanwidth,int sec_channel,u8 * op_class,u8 * channel)1260 int ieee80211_chaninfo_to_channel(unsigned int freq, enum chan_width chanwidth,
1261 int sec_channel, u8 *op_class, u8 *channel)
1262 {
1263 int cw = CHAN_WIDTH_UNKNOWN;
1264
1265 switch (chanwidth) {
1266 case CHAN_WIDTH_UNKNOWN:
1267 case CHAN_WIDTH_20_NOHT:
1268 case CHAN_WIDTH_20:
1269 case CHAN_WIDTH_40:
1270 cw = CHANWIDTH_USE_HT;
1271 break;
1272 case CHAN_WIDTH_80:
1273 cw = CHANWIDTH_80MHZ;
1274 break;
1275 case CHAN_WIDTH_80P80:
1276 cw = CHANWIDTH_80P80MHZ;
1277 break;
1278 case CHAN_WIDTH_160:
1279 cw = CHANWIDTH_160MHZ;
1280 break;
1281 case CHAN_WIDTH_2160:
1282 cw = CHANWIDTH_2160MHZ;
1283 break;
1284 case CHAN_WIDTH_4320:
1285 cw = CHANWIDTH_4320MHZ;
1286 break;
1287 case CHAN_WIDTH_6480:
1288 cw = CHANWIDTH_6480MHZ;
1289 break;
1290 case CHAN_WIDTH_8640:
1291 cw = CHANWIDTH_8640MHZ;
1292 break;
1293 }
1294
1295 if (ieee80211_freq_to_channel_ext(freq, sec_channel, cw, op_class,
1296 channel) == NUM_HOSTAPD_MODES) {
1297 wpa_printf(MSG_WARNING,
1298 "Cannot determine operating class and channel (freq=%u chanwidth=%d sec_channel=%d)",
1299 freq, chanwidth, sec_channel);
1300 return -1;
1301 }
1302
1303 return 0;
1304 }
1305
1306
1307 static const char *const us_op_class_cc[] = {
1308 "US", "CA", NULL
1309 };
1310
1311 static const char *const eu_op_class_cc[] = {
1312 "AL", "AM", "AT", "AZ", "BA", "BE", "BG", "BY", "CH", "CY", "CZ", "DE",
1313 "DK", "EE", "EL", "ES", "FI", "FR", "GE", "HR", "HU", "IE", "IS", "IT",
1314 "LI", "LT", "LU", "LV", "MD", "ME", "MK", "MT", "NL", "NO", "PL", "PT",
1315 "RO", "RS", "RU", "SE", "SI", "SK", "TR", "UA", "UK", NULL
1316 };
1317
1318 static const char *const jp_op_class_cc[] = {
1319 "JP", NULL
1320 };
1321
1322 static const char *const cn_op_class_cc[] = {
1323 "CN", NULL
1324 };
1325
1326
country_match(const char * const cc[],const char * const country)1327 static int country_match(const char *const cc[], const char *const country)
1328 {
1329 int i;
1330
1331 if (country == NULL)
1332 return 0;
1333 for (i = 0; cc[i]; i++) {
1334 if (cc[i][0] == country[0] && cc[i][1] == country[1])
1335 return 1;
1336 }
1337
1338 return 0;
1339 }
1340
1341
ieee80211_chan_to_freq_us(u8 op_class,u8 chan)1342 static int ieee80211_chan_to_freq_us(u8 op_class, u8 chan)
1343 {
1344 switch (op_class) {
1345 case 12: /* channels 1..11 */
1346 case 32: /* channels 1..7; 40 MHz */
1347 case 33: /* channels 5..11; 40 MHz */
1348 if (chan < 1 || chan > 11)
1349 return -1;
1350 return 2407 + 5 * chan;
1351 case 1: /* channels 36,40,44,48 */
1352 case 2: /* channels 52,56,60,64; dfs */
1353 case 22: /* channels 36,44; 40 MHz */
1354 case 23: /* channels 52,60; 40 MHz */
1355 case 27: /* channels 40,48; 40 MHz */
1356 case 28: /* channels 56,64; 40 MHz */
1357 if (chan < 36 || chan > 64)
1358 return -1;
1359 return 5000 + 5 * chan;
1360 case 4: /* channels 100-144 */
1361 case 24: /* channels 100-140; 40 MHz */
1362 if (chan < 100 || chan > 144)
1363 return -1;
1364 return 5000 + 5 * chan;
1365 case 3: /* channels 149,153,157,161 */
1366 case 25: /* channels 149,157; 40 MHz */
1367 case 26: /* channels 149,157; 40 MHz */
1368 case 30: /* channels 153,161; 40 MHz */
1369 case 31: /* channels 153,161; 40 MHz */
1370 if (chan < 149 || chan > 161)
1371 return -1;
1372 return 5000 + 5 * chan;
1373 case 5: /* channels 149,153,157,161,165 */
1374 if (chan < 149 || chan > 165)
1375 return -1;
1376 return 5000 + 5 * chan;
1377 case 34: /* 60 GHz band, channels 1..8 */
1378 if (chan < 1 || chan > 8)
1379 return -1;
1380 return 56160 + 2160 * chan;
1381 case 37: /* 60 GHz band, EDMG CB2, channels 9..15 */
1382 if (chan < 9 || chan > 15)
1383 return -1;
1384 return 56160 + 2160 * (chan - 8);
1385 case 38: /* 60 GHz band, EDMG CB3, channels 17..22 */
1386 if (chan < 17 || chan > 22)
1387 return -1;
1388 return 56160 + 2160 * (chan - 16);
1389 case 39: /* 60 GHz band, EDMG CB4, channels 25..29 */
1390 if (chan < 25 || chan > 29)
1391 return -1;
1392 return 56160 + 2160 * (chan - 24);
1393 }
1394 return -1;
1395 }
1396
1397
ieee80211_chan_to_freq_eu(u8 op_class,u8 chan)1398 static int ieee80211_chan_to_freq_eu(u8 op_class, u8 chan)
1399 {
1400 switch (op_class) {
1401 case 4: /* channels 1..13 */
1402 case 11: /* channels 1..9; 40 MHz */
1403 case 12: /* channels 5..13; 40 MHz */
1404 if (chan < 1 || chan > 13)
1405 return -1;
1406 return 2407 + 5 * chan;
1407 case 1: /* channels 36,40,44,48 */
1408 case 2: /* channels 52,56,60,64; dfs */
1409 case 5: /* channels 36,44; 40 MHz */
1410 case 6: /* channels 52,60; 40 MHz */
1411 case 8: /* channels 40,48; 40 MHz */
1412 case 9: /* channels 56,64; 40 MHz */
1413 if (chan < 36 || chan > 64)
1414 return -1;
1415 return 5000 + 5 * chan;
1416 case 3: /* channels 100-140 */
1417 case 7: /* channels 100-132; 40 MHz */
1418 case 10: /* channels 104-136; 40 MHz */
1419 case 16: /* channels 100-140 */
1420 if (chan < 100 || chan > 140)
1421 return -1;
1422 return 5000 + 5 * chan;
1423 case 17: /* channels 149,153,157,161,165,169 */
1424 if (chan < 149 || chan > 169)
1425 return -1;
1426 return 5000 + 5 * chan;
1427 case 18: /* 60 GHz band, channels 1..6 */
1428 if (chan < 1 || chan > 6)
1429 return -1;
1430 return 56160 + 2160 * chan;
1431 case 21: /* 60 GHz band, EDMG CB2, channels 9..11 */
1432 if (chan < 9 || chan > 11)
1433 return -1;
1434 return 56160 + 2160 * (chan - 8);
1435 case 22: /* 60 GHz band, EDMG CB3, channels 17..18 */
1436 if (chan < 17 || chan > 18)
1437 return -1;
1438 return 56160 + 2160 * (chan - 16);
1439 case 23: /* 60 GHz band, EDMG CB4, channels 25 */
1440 if (chan != 25)
1441 return -1;
1442 return 56160 + 2160 * (chan - 24);
1443 }
1444 return -1;
1445 }
1446
1447
ieee80211_chan_to_freq_jp(u8 op_class,u8 chan)1448 static int ieee80211_chan_to_freq_jp(u8 op_class, u8 chan)
1449 {
1450 switch (op_class) {
1451 case 30: /* channels 1..13 */
1452 case 56: /* channels 1..9; 40 MHz */
1453 case 57: /* channels 5..13; 40 MHz */
1454 if (chan < 1 || chan > 13)
1455 return -1;
1456 return 2407 + 5 * chan;
1457 case 31: /* channel 14 */
1458 if (chan != 14)
1459 return -1;
1460 return 2414 + 5 * chan;
1461 case 1: /* channels 34,38,42,46(old) or 36,40,44,48 */
1462 case 32: /* channels 52,56,60,64 */
1463 case 33: /* channels 52,56,60,64 */
1464 case 36: /* channels 36,44; 40 MHz */
1465 case 37: /* channels 52,60; 40 MHz */
1466 case 38: /* channels 52,60; 40 MHz */
1467 case 41: /* channels 40,48; 40 MHz */
1468 case 42: /* channels 56,64; 40 MHz */
1469 case 43: /* channels 56,64; 40 MHz */
1470 if (chan < 34 || chan > 64)
1471 return -1;
1472 return 5000 + 5 * chan;
1473 case 34: /* channels 100-140 */
1474 case 35: /* channels 100-140 */
1475 case 39: /* channels 100-132; 40 MHz */
1476 case 40: /* channels 100-132; 40 MHz */
1477 case 44: /* channels 104-136; 40 MHz */
1478 case 45: /* channels 104-136; 40 MHz */
1479 case 58: /* channels 100-140 */
1480 if (chan < 100 || chan > 140)
1481 return -1;
1482 return 5000 + 5 * chan;
1483 case 59: /* 60 GHz band, channels 1..6 */
1484 if (chan < 1 || chan > 6)
1485 return -1;
1486 return 56160 + 2160 * chan;
1487 case 62: /* 60 GHz band, EDMG CB2, channels 9..11 */
1488 if (chan < 9 || chan > 11)
1489 return -1;
1490 return 56160 + 2160 * (chan - 8);
1491 case 63: /* 60 GHz band, EDMG CB3, channels 17..18 */
1492 if (chan < 17 || chan > 18)
1493 return -1;
1494 return 56160 + 2160 * (chan - 16);
1495 case 64: /* 60 GHz band, EDMG CB4, channel 25 */
1496 if (chan != 25)
1497 return -1;
1498 return 56160 + 2160 * (chan - 24);
1499 }
1500 return -1;
1501 }
1502
1503
ieee80211_chan_to_freq_cn(u8 op_class,u8 chan)1504 static int ieee80211_chan_to_freq_cn(u8 op_class, u8 chan)
1505 {
1506 switch (op_class) {
1507 case 7: /* channels 1..13 */
1508 case 8: /* channels 1..9; 40 MHz */
1509 case 9: /* channels 5..13; 40 MHz */
1510 if (chan < 1 || chan > 13)
1511 return -1;
1512 return 2407 + 5 * chan;
1513 case 1: /* channels 36,40,44,48 */
1514 case 2: /* channels 52,56,60,64; dfs */
1515 case 4: /* channels 36,44; 40 MHz */
1516 case 5: /* channels 52,60; 40 MHz */
1517 if (chan < 36 || chan > 64)
1518 return -1;
1519 return 5000 + 5 * chan;
1520 case 3: /* channels 149,153,157,161,165 */
1521 case 6: /* channels 149,157; 40 MHz */
1522 if (chan < 149 || chan > 165)
1523 return -1;
1524 return 5000 + 5 * chan;
1525 }
1526 return -1;
1527 }
1528
1529
ieee80211_chan_to_freq_global(u8 op_class,u8 chan)1530 static int ieee80211_chan_to_freq_global(u8 op_class, u8 chan)
1531 {
1532 /* Table E-4 in IEEE Std 802.11-2012 - Global operating classes */
1533 switch (op_class) {
1534 case 81:
1535 /* channels 1..13 */
1536 if (chan < 1 || chan > 13)
1537 return -1;
1538 return 2407 + 5 * chan;
1539 case 82:
1540 /* channel 14 */
1541 if (chan != 14)
1542 return -1;
1543 return 2414 + 5 * chan;
1544 case 83: /* channels 1..9; 40 MHz */
1545 case 84: /* channels 5..13; 40 MHz */
1546 if (chan < 1 || chan > 13)
1547 return -1;
1548 return 2407 + 5 * chan;
1549 case 115: /* channels 36,40,44,48; indoor only */
1550 case 116: /* channels 36,44; 40 MHz; indoor only */
1551 case 117: /* channels 40,48; 40 MHz; indoor only */
1552 case 118: /* channels 52,56,60,64; dfs */
1553 case 119: /* channels 52,60; 40 MHz; dfs */
1554 case 120: /* channels 56,64; 40 MHz; dfs */
1555 if (chan < 36 || chan > 64)
1556 return -1;
1557 return 5000 + 5 * chan;
1558 case 121: /* channels 100-140 */
1559 case 122: /* channels 100-142; 40 MHz */
1560 case 123: /* channels 104-136; 40 MHz */
1561 if (chan < 100 || chan > 140)
1562 return -1;
1563 return 5000 + 5 * chan;
1564 case 124: /* channels 149,153,157,161 */
1565 if (chan < 149 || chan > 161)
1566 return -1;
1567 return 5000 + 5 * chan;
1568 case 125: /* channels 149,153,157,161,165,169,173,177 */
1569 case 126: /* channels 149,157,165,173; 40 MHz */
1570 case 127: /* channels 153,161,169,177; 40 MHz */
1571 if (chan < 149 || chan > 177)
1572 return -1;
1573 return 5000 + 5 * chan;
1574 case 128: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80 MHz */
1575 case 130: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80 MHz */
1576 if (chan < 36 || chan > 177)
1577 return -1;
1578 return 5000 + 5 * chan;
1579 case 129: /* center freqs 50, 114, 163; 160 MHz */
1580 if (chan < 36 || chan > 177)
1581 return -1;
1582 return 5000 + 5 * chan;
1583 case 131: /* UHB channels, 20 MHz: 1, 5, 9.. */
1584 case 132: /* UHB channels, 40 MHz: 3, 11, 19.. */
1585 case 133: /* UHB channels, 80 MHz: 7, 23, 39.. */
1586 case 134: /* UHB channels, 160 MHz: 15, 47, 79.. */
1587 case 135: /* UHB channels, 80+80 MHz: 7, 23, 39.. */
1588 if (chan < 1 || chan > 233)
1589 return -1;
1590 return 5950 + chan * 5;
1591 case 136: /* UHB channels, 20 MHz: 2 */
1592 if (chan == 2)
1593 return 5935;
1594 return -1;
1595 case 180: /* 60 GHz band, channels 1..8 */
1596 if (chan < 1 || chan > 8)
1597 return -1;
1598 return 56160 + 2160 * chan;
1599 case 181: /* 60 GHz band, EDMG CB2, channels 9..15 */
1600 if (chan < 9 || chan > 15)
1601 return -1;
1602 return 56160 + 2160 * (chan - 8);
1603 case 182: /* 60 GHz band, EDMG CB3, channels 17..22 */
1604 if (chan < 17 || chan > 22)
1605 return -1;
1606 return 56160 + 2160 * (chan - 16);
1607 case 183: /* 60 GHz band, EDMG CB4, channel 25..29 */
1608 if (chan < 25 || chan > 29)
1609 return -1;
1610 return 56160 + 2160 * (chan - 24);
1611 }
1612 return -1;
1613 }
1614
1615 /**
1616 * ieee80211_chan_to_freq - Convert channel info to frequency
1617 * @country: Country code, if known; otherwise, global operating class is used
1618 * @op_class: Operating class
1619 * @chan: Channel number
1620 * Returns: Frequency in MHz or -1 if the specified channel is unknown
1621 */
ieee80211_chan_to_freq(const char * country,u8 op_class,u8 chan)1622 int ieee80211_chan_to_freq(const char *country, u8 op_class, u8 chan)
1623 {
1624 int freq;
1625
1626 if (country_match(us_op_class_cc, country)) {
1627 freq = ieee80211_chan_to_freq_us(op_class, chan);
1628 if (freq > 0)
1629 return freq;
1630 }
1631
1632 if (country_match(eu_op_class_cc, country)) {
1633 freq = ieee80211_chan_to_freq_eu(op_class, chan);
1634 if (freq > 0)
1635 return freq;
1636 }
1637
1638 if (country_match(jp_op_class_cc, country)) {
1639 freq = ieee80211_chan_to_freq_jp(op_class, chan);
1640 if (freq > 0)
1641 return freq;
1642 }
1643
1644 if (country_match(cn_op_class_cc, country)) {
1645 freq = ieee80211_chan_to_freq_cn(op_class, chan);
1646 if (freq > 0)
1647 return freq;
1648 }
1649
1650 return ieee80211_chan_to_freq_global(op_class, chan);
1651 }
1652
1653
ieee80211_is_dfs(int freq,const struct hostapd_hw_modes * modes,u16 num_modes)1654 int ieee80211_is_dfs(int freq, const struct hostapd_hw_modes *modes,
1655 u16 num_modes)
1656 {
1657 int i, j;
1658
1659 if (!modes || !num_modes)
1660 return (freq >= 5260 && freq <= 5320) ||
1661 (freq >= 5500 && freq <= 5700);
1662
1663 for (i = 0; i < num_modes; i++) {
1664 for (j = 0; j < modes[i].num_channels; j++) {
1665 if (modes[i].channels[j].freq == freq &&
1666 (modes[i].channels[j].flag & HOSTAPD_CHAN_RADAR))
1667 return 1;
1668 }
1669 }
1670
1671 return 0;
1672 }
1673
1674
1675 /*
1676 * 802.11-2020: Table E-4 - Global operating classes
1677 * DFS_50_100_Behavior: 118, 119, 120, 121, 122, 123
1678 */
is_dfs_global_op_class(u8 op_class)1679 int is_dfs_global_op_class(u8 op_class)
1680 {
1681 return (op_class >= 118) && (op_class <= 123);
1682 }
1683
1684
is_11b(u8 rate)1685 static int is_11b(u8 rate)
1686 {
1687 return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16;
1688 }
1689
1690
supp_rates_11b_only(struct ieee802_11_elems * elems)1691 int supp_rates_11b_only(struct ieee802_11_elems *elems)
1692 {
1693 int num_11b = 0, num_others = 0;
1694 int i;
1695
1696 if (elems->supp_rates == NULL && elems->ext_supp_rates == NULL)
1697 return 0;
1698
1699 for (i = 0; elems->supp_rates && i < elems->supp_rates_len; i++) {
1700 if (is_11b(elems->supp_rates[i]))
1701 num_11b++;
1702 else
1703 num_others++;
1704 }
1705
1706 for (i = 0; elems->ext_supp_rates && i < elems->ext_supp_rates_len;
1707 i++) {
1708 if (is_11b(elems->ext_supp_rates[i]))
1709 num_11b++;
1710 else
1711 num_others++;
1712 }
1713
1714 return num_11b > 0 && num_others == 0;
1715 }
1716
1717
fc2str(u16 fc)1718 const char * fc2str(u16 fc)
1719 {
1720 u16 stype = WLAN_FC_GET_STYPE(fc);
1721 #define C2S(x) case x: return #x;
1722
1723 switch (WLAN_FC_GET_TYPE(fc)) {
1724 case WLAN_FC_TYPE_MGMT:
1725 switch (stype) {
1726 C2S(WLAN_FC_STYPE_ASSOC_REQ)
1727 C2S(WLAN_FC_STYPE_ASSOC_RESP)
1728 C2S(WLAN_FC_STYPE_REASSOC_REQ)
1729 C2S(WLAN_FC_STYPE_REASSOC_RESP)
1730 C2S(WLAN_FC_STYPE_PROBE_REQ)
1731 C2S(WLAN_FC_STYPE_PROBE_RESP)
1732 C2S(WLAN_FC_STYPE_BEACON)
1733 C2S(WLAN_FC_STYPE_ATIM)
1734 C2S(WLAN_FC_STYPE_DISASSOC)
1735 C2S(WLAN_FC_STYPE_AUTH)
1736 C2S(WLAN_FC_STYPE_DEAUTH)
1737 C2S(WLAN_FC_STYPE_ACTION)
1738 }
1739 break;
1740 case WLAN_FC_TYPE_CTRL:
1741 switch (stype) {
1742 C2S(WLAN_FC_STYPE_PSPOLL)
1743 C2S(WLAN_FC_STYPE_RTS)
1744 C2S(WLAN_FC_STYPE_CTS)
1745 C2S(WLAN_FC_STYPE_ACK)
1746 C2S(WLAN_FC_STYPE_CFEND)
1747 C2S(WLAN_FC_STYPE_CFENDACK)
1748 }
1749 break;
1750 case WLAN_FC_TYPE_DATA:
1751 switch (stype) {
1752 C2S(WLAN_FC_STYPE_DATA)
1753 C2S(WLAN_FC_STYPE_DATA_CFACK)
1754 C2S(WLAN_FC_STYPE_DATA_CFPOLL)
1755 C2S(WLAN_FC_STYPE_DATA_CFACKPOLL)
1756 C2S(WLAN_FC_STYPE_NULLFUNC)
1757 C2S(WLAN_FC_STYPE_CFACK)
1758 C2S(WLAN_FC_STYPE_CFPOLL)
1759 C2S(WLAN_FC_STYPE_CFACKPOLL)
1760 C2S(WLAN_FC_STYPE_QOS_DATA)
1761 C2S(WLAN_FC_STYPE_QOS_DATA_CFACK)
1762 C2S(WLAN_FC_STYPE_QOS_DATA_CFPOLL)
1763 C2S(WLAN_FC_STYPE_QOS_DATA_CFACKPOLL)
1764 C2S(WLAN_FC_STYPE_QOS_NULL)
1765 C2S(WLAN_FC_STYPE_QOS_CFPOLL)
1766 C2S(WLAN_FC_STYPE_QOS_CFACKPOLL)
1767 }
1768 break;
1769 }
1770 return "WLAN_FC_TYPE_UNKNOWN";
1771 #undef C2S
1772 }
1773
1774
reason2str(u16 reason)1775 const char * reason2str(u16 reason)
1776 {
1777 #define R2S(r) case WLAN_REASON_ ## r: return #r;
1778 switch (reason) {
1779 R2S(UNSPECIFIED)
1780 R2S(PREV_AUTH_NOT_VALID)
1781 R2S(DEAUTH_LEAVING)
1782 R2S(DISASSOC_DUE_TO_INACTIVITY)
1783 R2S(DISASSOC_AP_BUSY)
1784 R2S(CLASS2_FRAME_FROM_NONAUTH_STA)
1785 R2S(CLASS3_FRAME_FROM_NONASSOC_STA)
1786 R2S(DISASSOC_STA_HAS_LEFT)
1787 R2S(STA_REQ_ASSOC_WITHOUT_AUTH)
1788 R2S(PWR_CAPABILITY_NOT_VALID)
1789 R2S(SUPPORTED_CHANNEL_NOT_VALID)
1790 R2S(BSS_TRANSITION_DISASSOC)
1791 R2S(INVALID_IE)
1792 R2S(MICHAEL_MIC_FAILURE)
1793 R2S(4WAY_HANDSHAKE_TIMEOUT)
1794 R2S(GROUP_KEY_UPDATE_TIMEOUT)
1795 R2S(IE_IN_4WAY_DIFFERS)
1796 R2S(GROUP_CIPHER_NOT_VALID)
1797 R2S(PAIRWISE_CIPHER_NOT_VALID)
1798 R2S(AKMP_NOT_VALID)
1799 R2S(UNSUPPORTED_RSN_IE_VERSION)
1800 R2S(INVALID_RSN_IE_CAPAB)
1801 R2S(IEEE_802_1X_AUTH_FAILED)
1802 R2S(CIPHER_SUITE_REJECTED)
1803 R2S(TDLS_TEARDOWN_UNREACHABLE)
1804 R2S(TDLS_TEARDOWN_UNSPECIFIED)
1805 R2S(SSP_REQUESTED_DISASSOC)
1806 R2S(NO_SSP_ROAMING_AGREEMENT)
1807 R2S(BAD_CIPHER_OR_AKM)
1808 R2S(NOT_AUTHORIZED_THIS_LOCATION)
1809 R2S(SERVICE_CHANGE_PRECLUDES_TS)
1810 R2S(UNSPECIFIED_QOS_REASON)
1811 R2S(NOT_ENOUGH_BANDWIDTH)
1812 R2S(DISASSOC_LOW_ACK)
1813 R2S(EXCEEDED_TXOP)
1814 R2S(STA_LEAVING)
1815 R2S(END_TS_BA_DLS)
1816 R2S(UNKNOWN_TS_BA)
1817 R2S(TIMEOUT)
1818 R2S(PEERKEY_MISMATCH)
1819 R2S(AUTHORIZED_ACCESS_LIMIT_REACHED)
1820 R2S(EXTERNAL_SERVICE_REQUIREMENTS)
1821 R2S(INVALID_FT_ACTION_FRAME_COUNT)
1822 R2S(INVALID_PMKID)
1823 R2S(INVALID_MDE)
1824 R2S(INVALID_FTE)
1825 R2S(MESH_PEERING_CANCELLED)
1826 R2S(MESH_MAX_PEERS)
1827 R2S(MESH_CONFIG_POLICY_VIOLATION)
1828 R2S(MESH_CLOSE_RCVD)
1829 R2S(MESH_MAX_RETRIES)
1830 R2S(MESH_CONFIRM_TIMEOUT)
1831 R2S(MESH_INVALID_GTK)
1832 R2S(MESH_INCONSISTENT_PARAMS)
1833 R2S(MESH_INVALID_SECURITY_CAP)
1834 R2S(MESH_PATH_ERROR_NO_PROXY_INFO)
1835 R2S(MESH_PATH_ERROR_NO_FORWARDING_INFO)
1836 R2S(MESH_PATH_ERROR_DEST_UNREACHABLE)
1837 R2S(MAC_ADDRESS_ALREADY_EXISTS_IN_MBSS)
1838 R2S(MESH_CHANNEL_SWITCH_REGULATORY_REQ)
1839 R2S(MESH_CHANNEL_SWITCH_UNSPECIFIED)
1840 }
1841 return "UNKNOWN";
1842 #undef R2S
1843 }
1844
1845
status2str(u16 status)1846 const char * status2str(u16 status)
1847 {
1848 #define S2S(s) case WLAN_STATUS_ ## s: return #s;
1849 switch (status) {
1850 S2S(SUCCESS)
1851 S2S(UNSPECIFIED_FAILURE)
1852 S2S(TDLS_WAKEUP_ALTERNATE)
1853 S2S(TDLS_WAKEUP_REJECT)
1854 S2S(SECURITY_DISABLED)
1855 S2S(UNACCEPTABLE_LIFETIME)
1856 S2S(NOT_IN_SAME_BSS)
1857 S2S(CAPS_UNSUPPORTED)
1858 S2S(REASSOC_NO_ASSOC)
1859 S2S(ASSOC_DENIED_UNSPEC)
1860 S2S(NOT_SUPPORTED_AUTH_ALG)
1861 S2S(UNKNOWN_AUTH_TRANSACTION)
1862 S2S(CHALLENGE_FAIL)
1863 S2S(AUTH_TIMEOUT)
1864 S2S(AP_UNABLE_TO_HANDLE_NEW_STA)
1865 S2S(ASSOC_DENIED_RATES)
1866 S2S(ASSOC_DENIED_NOSHORT)
1867 S2S(SPEC_MGMT_REQUIRED)
1868 S2S(PWR_CAPABILITY_NOT_VALID)
1869 S2S(SUPPORTED_CHANNEL_NOT_VALID)
1870 S2S(ASSOC_DENIED_NO_SHORT_SLOT_TIME)
1871 S2S(ASSOC_DENIED_NO_HT)
1872 S2S(R0KH_UNREACHABLE)
1873 S2S(ASSOC_DENIED_NO_PCO)
1874 S2S(ASSOC_REJECTED_TEMPORARILY)
1875 S2S(ROBUST_MGMT_FRAME_POLICY_VIOLATION)
1876 S2S(UNSPECIFIED_QOS_FAILURE)
1877 S2S(DENIED_INSUFFICIENT_BANDWIDTH)
1878 S2S(DENIED_POOR_CHANNEL_CONDITIONS)
1879 S2S(DENIED_QOS_NOT_SUPPORTED)
1880 S2S(REQUEST_DECLINED)
1881 S2S(INVALID_PARAMETERS)
1882 S2S(REJECTED_WITH_SUGGESTED_CHANGES)
1883 S2S(INVALID_IE)
1884 S2S(GROUP_CIPHER_NOT_VALID)
1885 S2S(PAIRWISE_CIPHER_NOT_VALID)
1886 S2S(AKMP_NOT_VALID)
1887 S2S(UNSUPPORTED_RSN_IE_VERSION)
1888 S2S(INVALID_RSN_IE_CAPAB)
1889 S2S(CIPHER_REJECTED_PER_POLICY)
1890 S2S(TS_NOT_CREATED)
1891 S2S(DIRECT_LINK_NOT_ALLOWED)
1892 S2S(DEST_STA_NOT_PRESENT)
1893 S2S(DEST_STA_NOT_QOS_STA)
1894 S2S(ASSOC_DENIED_LISTEN_INT_TOO_LARGE)
1895 S2S(INVALID_FT_ACTION_FRAME_COUNT)
1896 S2S(INVALID_PMKID)
1897 S2S(INVALID_MDIE)
1898 S2S(INVALID_FTIE)
1899 S2S(REQUESTED_TCLAS_NOT_SUPPORTED)
1900 S2S(INSUFFICIENT_TCLAS_PROCESSING_RESOURCES)
1901 S2S(TRY_ANOTHER_BSS)
1902 S2S(GAS_ADV_PROTO_NOT_SUPPORTED)
1903 S2S(NO_OUTSTANDING_GAS_REQ)
1904 S2S(GAS_RESP_NOT_RECEIVED)
1905 S2S(STA_TIMED_OUT_WAITING_FOR_GAS_RESP)
1906 S2S(GAS_RESP_LARGER_THAN_LIMIT)
1907 S2S(REQ_REFUSED_HOME)
1908 S2S(ADV_SRV_UNREACHABLE)
1909 S2S(REQ_REFUSED_SSPN)
1910 S2S(REQ_REFUSED_UNAUTH_ACCESS)
1911 S2S(INVALID_RSNIE)
1912 S2S(U_APSD_COEX_NOT_SUPPORTED)
1913 S2S(U_APSD_COEX_MODE_NOT_SUPPORTED)
1914 S2S(BAD_INTERVAL_WITH_U_APSD_COEX)
1915 S2S(ANTI_CLOGGING_TOKEN_REQ)
1916 S2S(FINITE_CYCLIC_GROUP_NOT_SUPPORTED)
1917 S2S(CANNOT_FIND_ALT_TBTT)
1918 S2S(TRANSMISSION_FAILURE)
1919 S2S(REQ_TCLAS_NOT_SUPPORTED)
1920 S2S(TCLAS_RESOURCES_EXCHAUSTED)
1921 S2S(REJECTED_WITH_SUGGESTED_BSS_TRANSITION)
1922 S2S(REJECT_WITH_SCHEDULE)
1923 S2S(REJECT_NO_WAKEUP_SPECIFIED)
1924 S2S(SUCCESS_POWER_SAVE_MODE)
1925 S2S(PENDING_ADMITTING_FST_SESSION)
1926 S2S(PERFORMING_FST_NOW)
1927 S2S(PENDING_GAP_IN_BA_WINDOW)
1928 S2S(REJECT_U_PID_SETTING)
1929 S2S(REFUSED_EXTERNAL_REASON)
1930 S2S(REFUSED_AP_OUT_OF_MEMORY)
1931 S2S(REJECTED_EMERGENCY_SERVICE_NOT_SUPPORTED)
1932 S2S(QUERY_RESP_OUTSTANDING)
1933 S2S(REJECT_DSE_BAND)
1934 S2S(TCLAS_PROCESSING_TERMINATED)
1935 S2S(TS_SCHEDULE_CONFLICT)
1936 S2S(DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL)
1937 S2S(MCCAOP_RESERVATION_CONFLICT)
1938 S2S(MAF_LIMIT_EXCEEDED)
1939 S2S(MCCA_TRACK_LIMIT_EXCEEDED)
1940 S2S(DENIED_DUE_TO_SPECTRUM_MANAGEMENT)
1941 S2S(ASSOC_DENIED_NO_VHT)
1942 S2S(ENABLEMENT_DENIED)
1943 S2S(RESTRICTION_FROM_AUTHORIZED_GDB)
1944 S2S(AUTHORIZATION_DEENABLED)
1945 S2S(FILS_AUTHENTICATION_FAILURE)
1946 S2S(UNKNOWN_AUTHENTICATION_SERVER)
1947 S2S(UNKNOWN_PASSWORD_IDENTIFIER)
1948 S2S(DENIED_HE_NOT_SUPPORTED)
1949 S2S(SAE_HASH_TO_ELEMENT)
1950 S2S(SAE_PK)
1951 }
1952 return "UNKNOWN";
1953 #undef S2S
1954 }
1955
1956
mb_ies_info_by_ies(struct mb_ies_info * info,const u8 * ies_buf,size_t ies_len)1957 int mb_ies_info_by_ies(struct mb_ies_info *info, const u8 *ies_buf,
1958 size_t ies_len)
1959 {
1960 const struct element *elem;
1961
1962 os_memset(info, 0, sizeof(*info));
1963
1964 if (!ies_buf)
1965 return 0;
1966
1967 for_each_element_id(elem, WLAN_EID_MULTI_BAND, ies_buf, ies_len) {
1968 if (info->nof_ies >= MAX_NOF_MB_IES_SUPPORTED)
1969 return 0;
1970
1971 wpa_printf(MSG_DEBUG, "MB IE of %u bytes found",
1972 elem->datalen + 2);
1973 info->ies[info->nof_ies].ie = elem->data;
1974 info->ies[info->nof_ies].ie_len = elem->datalen;
1975 info->nof_ies++;
1976 }
1977
1978 if (!for_each_element_completed(elem, ies_buf, ies_len)) {
1979 wpa_hexdump(MSG_DEBUG, "Truncated IEs", ies_buf, ies_len);
1980 return -1;
1981 }
1982
1983 return 0;
1984 }
1985
1986
mb_ies_by_info(struct mb_ies_info * info)1987 struct wpabuf * mb_ies_by_info(struct mb_ies_info *info)
1988 {
1989 struct wpabuf *mb_ies = NULL;
1990
1991 WPA_ASSERT(info != NULL);
1992
1993 if (info->nof_ies) {
1994 u8 i;
1995 size_t mb_ies_size = 0;
1996
1997 for (i = 0; i < info->nof_ies; i++)
1998 mb_ies_size += 2 + info->ies[i].ie_len;
1999
2000 mb_ies = wpabuf_alloc(mb_ies_size);
2001 if (mb_ies) {
2002 for (i = 0; i < info->nof_ies; i++) {
2003 wpabuf_put_u8(mb_ies, WLAN_EID_MULTI_BAND);
2004 wpabuf_put_u8(mb_ies, info->ies[i].ie_len);
2005 wpabuf_put_data(mb_ies,
2006 info->ies[i].ie,
2007 info->ies[i].ie_len);
2008 }
2009 }
2010 }
2011
2012 return mb_ies;
2013 }
2014
2015 #ifdef CONFIG_P2P_160M
2016 const struct oper_class_map *global_op_class = global_op_class_data;
2017 const struct oper_class_map global_op_class_data[] = {
2018 #else
2019 const struct oper_class_map global_op_class[] = {
2020 #endif
2021 { HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20, P2P_SUPP },
2022 { HOSTAPD_MODE_IEEE80211G, 82, 14, 14, 1, BW20, NO_P2P_SUPP },
2023
2024 /* Do not enable HT40 on 2.4 GHz for P2P use for now */
2025 { HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS, NO_P2P_SUPP },
2026 { HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS, NO_P2P_SUPP },
2027
2028 { HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20, P2P_SUPP },
2029 { HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS, P2P_SUPP },
2030 { HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS, P2P_SUPP },
2031 { HOSTAPD_MODE_IEEE80211A, 118, 52, 64, 4, BW20, NO_P2P_SUPP },
2032 { HOSTAPD_MODE_IEEE80211A, 119, 52, 60, 8, BW40PLUS, NO_P2P_SUPP },
2033 { HOSTAPD_MODE_IEEE80211A, 120, 56, 64, 8, BW40MINUS, NO_P2P_SUPP },
2034 { HOSTAPD_MODE_IEEE80211A, 121, 100, 140, 4, BW20, NO_P2P_SUPP },
2035 { HOSTAPD_MODE_IEEE80211A, 122, 100, 132, 8, BW40PLUS, NO_P2P_SUPP },
2036 { HOSTAPD_MODE_IEEE80211A, 123, 104, 136, 8, BW40MINUS, NO_P2P_SUPP },
2037 { HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20, P2P_SUPP },
2038 { HOSTAPD_MODE_IEEE80211A, 125, 149, 177, 4, BW20, P2P_SUPP },
2039 { HOSTAPD_MODE_IEEE80211A, 126, 149, 173, 8, BW40PLUS, P2P_SUPP },
2040 { HOSTAPD_MODE_IEEE80211A, 127, 153, 177, 8, BW40MINUS, P2P_SUPP },
2041
2042 /*
2043 * IEEE P802.11ax/D8.0 Table E-4 actually talks about channel center
2044 * frequency index 42, 58, 106, 122, 138, 155, 171 with channel spacing
2045 * of 80 MHz, but currently use the following definition for simplicity
2046 * (these center frequencies are not actual channels, which makes
2047 * wpas_p2p_verify_channel() fail). wpas_p2p_verify_80mhz() should take
2048 * care of removing invalid channels.
2049 */
2050 { HOSTAPD_MODE_IEEE80211A, 128, 36, 177, 4, BW80, P2P_SUPP },
2051 { HOSTAPD_MODE_IEEE80211A, 129, 36, 177, 4, BW160, P2P_SUPP },
2052 { HOSTAPD_MODE_IEEE80211A, 131, 1, 233, 4, BW20, P2P_SUPP },
2053 { HOSTAPD_MODE_IEEE80211A, 132, 1, 233, 8, BW40, P2P_SUPP },
2054 { HOSTAPD_MODE_IEEE80211A, 133, 1, 233, 16, BW80, P2P_SUPP },
2055 { HOSTAPD_MODE_IEEE80211A, 134, 1, 233, 32, BW160, P2P_SUPP },
2056 { HOSTAPD_MODE_IEEE80211A, 135, 1, 233, 16, BW80P80, NO_P2P_SUPP },
2057 { HOSTAPD_MODE_IEEE80211A, 136, 2, 2, 4, BW20, NO_P2P_SUPP },
2058
2059 /*
2060 * IEEE Std 802.11ad-2012 and P802.ay/D5.0 60 GHz operating classes.
2061 * Class 180 has the legacy channels 1-6. Classes 181-183 include
2062 * channels which implement channel bonding features.
2063 */
2064 { HOSTAPD_MODE_IEEE80211AD, 180, 1, 6, 1, BW2160, P2P_SUPP },
2065 { HOSTAPD_MODE_IEEE80211AD, 181, 9, 13, 1, BW4320, P2P_SUPP },
2066 { HOSTAPD_MODE_IEEE80211AD, 182, 17, 20, 1, BW6480, P2P_SUPP },
2067 { HOSTAPD_MODE_IEEE80211AD, 183, 25, 27, 1, BW8640, P2P_SUPP },
2068
2069 /* Keep the operating class 130 as the last entry as a workaround for
2070 * the OneHundredAndThirty Delimiter value used in the Supported
2071 * Operating Classes element to indicate the end of the Operating
2072 * Classes field. */
2073 { HOSTAPD_MODE_IEEE80211A, 130, 36, 177, 4, BW80P80, P2P_SUPP },
2074 { -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP }
2075 };
2076
2077 #ifdef CONFIG_P2P_160M
2078 const struct oper_class_map global_op_class_for_dfs[] = {
2079 { HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20, P2P_SUPP },
2080 { HOSTAPD_MODE_IEEE80211G, 82, 14, 14, 1, BW20, NO_P2P_SUPP },
2081
2082 /* Do not enable HT40 on 2.4 GHz for P2P use for now */
2083 { HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS, NO_P2P_SUPP },
2084 { HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS, NO_P2P_SUPP },
2085
2086 { HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20, P2P_SUPP },
2087 { HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS, P2P_SUPP },
2088 { HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS, P2P_SUPP },
2089
2090 /*Enable p2p 160M in DFS 52~64 channel*/
2091 { HOSTAPD_MODE_IEEE80211A, 118, 52, 64, 4, BW20, P2P_SUPP },
2092 { HOSTAPD_MODE_IEEE80211A, 119, 52, 60, 8, BW40PLUS, P2P_SUPP },
2093 { HOSTAPD_MODE_IEEE80211A, 120, 56, 64, 8, BW40MINUS, P2P_SUPP },
2094
2095 { HOSTAPD_MODE_IEEE80211A, 121, 100, 140, 4, BW20, NO_P2P_SUPP },
2096 { HOSTAPD_MODE_IEEE80211A, 122, 100, 132, 8, BW40PLUS, NO_P2P_SUPP },
2097 { HOSTAPD_MODE_IEEE80211A, 123, 104, 136, 8, BW40MINUS, NO_P2P_SUPP },
2098 { HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20, P2P_SUPP },
2099 { HOSTAPD_MODE_IEEE80211A, 125, 149, 169, 4, BW20, P2P_SUPP },
2100 { HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8, BW40PLUS, P2P_SUPP },
2101 { HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8, BW40MINUS, P2P_SUPP },
2102
2103 /*
2104 * IEEE P802.11ax/D8.0 Table E-4 actually talks about channel center
2105 * frequency index 42, 58, 106, 122, 138, 155 with channel spacing
2106 * of 80 MHz, but currently use the following definition for simplicity
2107 * (these center frequencies are not actual channels, which makes
2108 * wpas_p2p_allow_channel() fail). wpas_p2p_verify_80mhz() should take
2109 * care of removing invalid channels.
2110 */
2111 { HOSTAPD_MODE_IEEE80211A, 128, 36, 161, 4, BW80, P2P_SUPP },
2112 { HOSTAPD_MODE_IEEE80211A, 129, 50, 114, 16, BW160, P2P_SUPP },
2113 { HOSTAPD_MODE_IEEE80211A, 130, 36, 161, 4, BW80P80, P2P_SUPP },
2114 { HOSTAPD_MODE_IEEE80211AD, 180, 1, 4, 1, BW2160, P2P_SUPP },
2115 { -1, 0, 0, 0, 0, BW20, NO_P2P_SUPP }
2116 };
2117 #endif
2118
ieee80211_phy_type_by_freq(int freq)2119 static enum phy_type ieee80211_phy_type_by_freq(int freq)
2120 {
2121 enum hostapd_hw_mode hw_mode;
2122 u8 channel;
2123
2124 hw_mode = ieee80211_freq_to_chan(freq, &channel);
2125
2126 switch (hw_mode) {
2127 case HOSTAPD_MODE_IEEE80211A:
2128 return PHY_TYPE_OFDM;
2129 case HOSTAPD_MODE_IEEE80211B:
2130 return PHY_TYPE_HRDSSS;
2131 case HOSTAPD_MODE_IEEE80211G:
2132 return PHY_TYPE_ERP;
2133 case HOSTAPD_MODE_IEEE80211AD:
2134 return PHY_TYPE_DMG;
2135 default:
2136 return PHY_TYPE_UNSPECIFIED;
2137 };
2138 }
2139
2140
2141 /* ieee80211_get_phy_type - Derive the phy type by freq and bandwidth */
ieee80211_get_phy_type(int freq,int ht,int vht)2142 enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht)
2143 {
2144 if (vht)
2145 return PHY_TYPE_VHT;
2146 if (ht)
2147 return PHY_TYPE_HT;
2148
2149 return ieee80211_phy_type_by_freq(freq);
2150 }
2151
2152 #ifdef CONFIG_P2P_160M
2153 size_t global_op_class_size = ARRAY_SIZE(global_op_class_data);
2154 #else
2155 size_t global_op_class_size = ARRAY_SIZE(global_op_class);
2156 #endif
2157
2158
2159 /**
2160 * get_ie - Fetch a specified information element from IEs buffer
2161 * @ies: Information elements buffer
2162 * @len: Information elements buffer length
2163 * @eid: Information element identifier (WLAN_EID_*)
2164 * Returns: Pointer to the information element (id field) or %NULL if not found
2165 *
2166 * This function returns the first matching information element in the IEs
2167 * buffer or %NULL in case the element is not found.
2168 */
get_ie(const u8 * ies,size_t len,u8 eid)2169 const u8 * get_ie(const u8 *ies, size_t len, u8 eid)
2170 {
2171 const struct element *elem;
2172
2173 if (!ies)
2174 return NULL;
2175
2176 for_each_element_id(elem, eid, ies, len)
2177 return &elem->id;
2178
2179 return NULL;
2180 }
2181
2182
2183 /**
2184 * get_ie_ext - Fetch a specified extended information element from IEs buffer
2185 * @ies: Information elements buffer
2186 * @len: Information elements buffer length
2187 * @ext: Information element extension identifier (WLAN_EID_EXT_*)
2188 * Returns: Pointer to the information element (id field) or %NULL if not found
2189 *
2190 * This function returns the first matching information element in the IEs
2191 * buffer or %NULL in case the element is not found.
2192 */
get_ie_ext(const u8 * ies,size_t len,u8 ext)2193 const u8 * get_ie_ext(const u8 *ies, size_t len, u8 ext)
2194 {
2195 const struct element *elem;
2196
2197 if (!ies)
2198 return NULL;
2199
2200 for_each_element_extid(elem, ext, ies, len)
2201 return &elem->id;
2202
2203 return NULL;
2204 }
2205
2206
get_vendor_ie(const u8 * ies,size_t len,u32 vendor_type)2207 const u8 * get_vendor_ie(const u8 *ies, size_t len, u32 vendor_type)
2208 {
2209 const struct element *elem;
2210
2211 for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, len) {
2212 if (elem->datalen >= 4 &&
2213 vendor_type == WPA_GET_BE32(elem->data))
2214 return &elem->id;
2215 }
2216
2217 return NULL;
2218 }
2219
2220
mbo_add_ie(u8 * buf,size_t len,const u8 * attr,size_t attr_len)2221 size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len)
2222 {
2223 /*
2224 * MBO IE requires 6 bytes without the attributes: EID (1), length (1),
2225 * OUI (3), OUI type (1).
2226 */
2227 if (len < 6 + attr_len) {
2228 wpa_printf(MSG_DEBUG,
2229 "MBO: Not enough room in buffer for MBO IE: buf len = %zu, attr_len = %zu",
2230 len, attr_len);
2231 return 0;
2232 }
2233
2234 *buf++ = WLAN_EID_VENDOR_SPECIFIC;
2235 *buf++ = attr_len + 4;
2236 WPA_PUT_BE24(buf, OUI_WFA);
2237 buf += 3;
2238 *buf++ = MBO_OUI_TYPE;
2239 os_memcpy(buf, attr, attr_len);
2240
2241 return 6 + attr_len;
2242 }
2243
2244
add_multi_ap_ie(u8 * buf,size_t len,u8 value)2245 size_t add_multi_ap_ie(u8 *buf, size_t len, u8 value)
2246 {
2247 u8 *pos = buf;
2248
2249 if (len < 9)
2250 return 0;
2251
2252 *pos++ = WLAN_EID_VENDOR_SPECIFIC;
2253 *pos++ = 7; /* len */
2254 WPA_PUT_BE24(pos, OUI_WFA);
2255 pos += 3;
2256 *pos++ = MULTI_AP_OUI_TYPE;
2257 *pos++ = MULTI_AP_SUB_ELEM_TYPE;
2258 *pos++ = 1; /* len */
2259 *pos++ = value;
2260
2261 return pos - buf;
2262 }
2263
2264
2265 static const struct country_op_class us_op_class[] = {
2266 { 1, 115 },
2267 { 2, 118 },
2268 { 3, 124 },
2269 { 4, 121 },
2270 { 5, 125 },
2271 { 12, 81 },
2272 { 22, 116 },
2273 { 23, 119 },
2274 { 24, 122 },
2275 { 25, 126 },
2276 { 26, 126 },
2277 { 27, 117 },
2278 { 28, 120 },
2279 { 29, 123 },
2280 { 30, 127 },
2281 { 31, 127 },
2282 { 32, 83 },
2283 { 33, 84 },
2284 { 34, 180 },
2285 };
2286
2287 static const struct country_op_class eu_op_class[] = {
2288 { 1, 115 },
2289 { 2, 118 },
2290 { 3, 121 },
2291 { 4, 81 },
2292 { 5, 116 },
2293 { 6, 119 },
2294 { 7, 122 },
2295 { 8, 117 },
2296 { 9, 120 },
2297 { 10, 123 },
2298 { 11, 83 },
2299 { 12, 84 },
2300 { 17, 125 },
2301 { 18, 180 },
2302 };
2303
2304 static const struct country_op_class jp_op_class[] = {
2305 { 1, 115 },
2306 { 30, 81 },
2307 { 31, 82 },
2308 { 32, 118 },
2309 { 33, 118 },
2310 { 34, 121 },
2311 { 35, 121 },
2312 { 36, 116 },
2313 { 37, 119 },
2314 { 38, 119 },
2315 { 39, 122 },
2316 { 40, 122 },
2317 { 41, 117 },
2318 { 42, 120 },
2319 { 43, 120 },
2320 { 44, 123 },
2321 { 45, 123 },
2322 { 56, 83 },
2323 { 57, 84 },
2324 { 58, 121 },
2325 { 59, 180 },
2326 };
2327
2328 static const struct country_op_class cn_op_class[] = {
2329 { 1, 115 },
2330 { 2, 118 },
2331 { 3, 125 },
2332 { 4, 116 },
2333 { 5, 119 },
2334 { 6, 126 },
2335 { 7, 81 },
2336 { 8, 83 },
2337 { 9, 84 },
2338 };
2339
2340 static u8
global_op_class_from_country_array(u8 op_class,size_t array_size,const struct country_op_class * country_array)2341 global_op_class_from_country_array(u8 op_class, size_t array_size,
2342 const struct country_op_class *country_array)
2343 {
2344 size_t i;
2345
2346 for (i = 0; i < array_size; i++) {
2347 if (country_array[i].country_op_class == op_class)
2348 return country_array[i].global_op_class;
2349 }
2350
2351 return 0;
2352 }
2353
2354
country_to_global_op_class(const char * country,u8 op_class)2355 u8 country_to_global_op_class(const char *country, u8 op_class)
2356 {
2357 const struct country_op_class *country_array;
2358 size_t size;
2359 u8 g_op_class;
2360
2361 if (country_match(us_op_class_cc, country)) {
2362 country_array = us_op_class;
2363 size = ARRAY_SIZE(us_op_class);
2364 } else if (country_match(eu_op_class_cc, country)) {
2365 country_array = eu_op_class;
2366 size = ARRAY_SIZE(eu_op_class);
2367 } else if (country_match(jp_op_class_cc, country)) {
2368 country_array = jp_op_class;
2369 size = ARRAY_SIZE(jp_op_class);
2370 } else if (country_match(cn_op_class_cc, country)) {
2371 country_array = cn_op_class;
2372 size = ARRAY_SIZE(cn_op_class);
2373 } else {
2374 /*
2375 * Countries that do not match any of the above countries use
2376 * global operating classes
2377 */
2378 return op_class;
2379 }
2380
2381 g_op_class = global_op_class_from_country_array(op_class, size,
2382 country_array);
2383
2384 /*
2385 * If the given operating class did not match any of the country's
2386 * operating classes, assume that global operating class is used.
2387 */
2388 return g_op_class ? g_op_class : op_class;
2389 }
2390
2391
get_oper_class(const char * country,u8 op_class)2392 const struct oper_class_map * get_oper_class(const char *country, u8 op_class)
2393 {
2394 const struct oper_class_map *op;
2395
2396 if (country)
2397 op_class = country_to_global_op_class(country, op_class);
2398
2399 op = &global_op_class[0];
2400 while (op->op_class && op->op_class != op_class)
2401 op++;
2402
2403 if (!op->op_class)
2404 return NULL;
2405
2406 return op;
2407 }
2408
2409
oper_class_bw_to_int(const struct oper_class_map * map)2410 int oper_class_bw_to_int(const struct oper_class_map *map)
2411 {
2412 switch (map->bw) {
2413 case BW20:
2414 return 20;
2415 case BW40:
2416 case BW40PLUS:
2417 case BW40MINUS:
2418 return 40;
2419 case BW80:
2420 return 80;
2421 case BW80P80:
2422 case BW160:
2423 return 160;
2424 case BW2160:
2425 return 2160;
2426 default:
2427 return 0;
2428 }
2429 }
2430
2431
center_idx_to_bw_6ghz(u8 idx)2432 int center_idx_to_bw_6ghz(u8 idx)
2433 {
2434 /* Channel: 2 */
2435 if (idx == 2)
2436 return 0; /* 20 MHz */
2437 /* channels: 1, 5, 9, 13... */
2438 if ((idx & 0x3) == 0x1)
2439 return 0; /* 20 MHz */
2440 /* channels 3, 11, 19... */
2441 if ((idx & 0x7) == 0x3)
2442 return 1; /* 40 MHz */
2443 /* channels 7, 23, 39.. */
2444 if ((idx & 0xf) == 0x7)
2445 return 2; /* 80 MHz */
2446 /* channels 15, 47, 79...*/
2447 if ((idx & 0x1f) == 0xf)
2448 return 3; /* 160 MHz */
2449
2450 return -1;
2451 }
2452
2453
is_6ghz_freq(int freq)2454 bool is_6ghz_freq(int freq)
2455 {
2456 if (freq < 5935 || freq > 7115)
2457 return false;
2458
2459 if (freq == 5935)
2460 return true;
2461
2462 if (center_idx_to_bw_6ghz((freq - 5950) / 5) < 0)
2463 return false;
2464
2465 return true;
2466 }
2467
2468
is_6ghz_op_class(u8 op_class)2469 bool is_6ghz_op_class(u8 op_class)
2470 {
2471 return op_class >= 131 && op_class <= 136;
2472 }
2473
2474
is_6ghz_psc_frequency(int freq)2475 bool is_6ghz_psc_frequency(int freq)
2476 {
2477 int i;
2478
2479 if (!is_6ghz_freq(freq) || freq == 5935)
2480 return false;
2481 if ((((freq - 5950) / 5) & 0x3) != 0x1)
2482 return false;
2483
2484 i = (freq - 5950 + 55) % 80;
2485 if (i == 0)
2486 i = (freq - 5950 + 55) / 80;
2487
2488 if (i >= 1 && i <= 15)
2489 return true;
2490
2491 return false;
2492 }
2493
2494
2495 /**
2496 * get_6ghz_sec_channel - Get the relative position of the secondary channel
2497 * to the primary channel in 6 GHz
2498 * @channel: Primary channel to be checked for (in global op class 131)
2499 * Returns: 1 = secondary channel above, -1 = secondary channel below
2500 */
2501
get_6ghz_sec_channel(int channel)2502 int get_6ghz_sec_channel(int channel)
2503 {
2504 /*
2505 * In the 6 GHz band, primary channels are numbered as 1, 5, 9, 13.., so
2506 * the 40 MHz channels are formed with the channel pairs as (1,5),
2507 * (9,13), (17,21)..
2508 * The secondary channel for a given primary channel is below the
2509 * primary channel for the channels 5, 13, 21.. and it is above the
2510 * primary channel for the channels 1, 9, 17..
2511 */
2512
2513 if (((channel - 1) / 4) % 2)
2514 return -1;
2515 return 1;
2516 }
2517
2518
ieee802_11_parse_candidate_list(const char * pos,u8 * nei_rep,size_t nei_rep_len)2519 int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
2520 size_t nei_rep_len)
2521 {
2522 u8 *nei_pos = nei_rep;
2523 const char *end;
2524
2525 /*
2526 * BSS Transition Candidate List Entries - Neighbor Report elements
2527 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
2528 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
2529 */
2530 while (pos) {
2531 u8 *nei_start;
2532 long int val;
2533 char *endptr, *tmp;
2534
2535 pos = os_strstr(pos, " neighbor=");
2536 if (!pos)
2537 break;
2538 if (nei_pos + 15 > nei_rep + nei_rep_len) {
2539 wpa_printf(MSG_DEBUG,
2540 "Not enough room for additional neighbor");
2541 return -1;
2542 }
2543 pos += 10;
2544
2545 nei_start = nei_pos;
2546 *nei_pos++ = WLAN_EID_NEIGHBOR_REPORT;
2547 nei_pos++; /* length to be filled in */
2548
2549 if (hwaddr_aton(pos, nei_pos)) {
2550 wpa_printf(MSG_DEBUG, "Invalid BSSID");
2551 return -1;
2552 }
2553 nei_pos += ETH_ALEN;
2554 pos += 17;
2555 if (*pos != ',') {
2556 wpa_printf(MSG_DEBUG, "Missing BSSID Information");
2557 return -1;
2558 }
2559 pos++;
2560
2561 val = strtol(pos, &endptr, 0);
2562 WPA_PUT_LE32(nei_pos, val);
2563 nei_pos += 4;
2564 if (*endptr != ',') {
2565 wpa_printf(MSG_DEBUG, "Missing Operating Class");
2566 return -1;
2567 }
2568 pos = endptr + 1;
2569
2570 *nei_pos++ = atoi(pos); /* Operating Class */
2571 pos = os_strchr(pos, ',');
2572 if (pos == NULL) {
2573 wpa_printf(MSG_DEBUG, "Missing Channel Number");
2574 return -1;
2575 }
2576 pos++;
2577
2578 *nei_pos++ = atoi(pos); /* Channel Number */
2579 pos = os_strchr(pos, ',');
2580 if (pos == NULL) {
2581 wpa_printf(MSG_DEBUG, "Missing PHY Type");
2582 return -1;
2583 }
2584 pos++;
2585
2586 *nei_pos++ = atoi(pos); /* PHY Type */
2587 end = os_strchr(pos, ' ');
2588 tmp = os_strchr(pos, ',');
2589 if (tmp && (!end || tmp < end)) {
2590 /* Optional Subelements (hexdump) */
2591 size_t len;
2592
2593 pos = tmp + 1;
2594 end = os_strchr(pos, ' ');
2595 if (end)
2596 len = end - pos;
2597 else
2598 len = os_strlen(pos);
2599 if (nei_pos + len / 2 > nei_rep + nei_rep_len) {
2600 wpa_printf(MSG_DEBUG,
2601 "Not enough room for neighbor subelements");
2602 return -1;
2603 }
2604 if (len & 0x01 ||
2605 hexstr2bin(pos, nei_pos, len / 2) < 0) {
2606 wpa_printf(MSG_DEBUG,
2607 "Invalid neighbor subelement info");
2608 return -1;
2609 }
2610 nei_pos += len / 2;
2611 pos = end;
2612 }
2613
2614 nei_start[1] = nei_pos - nei_start - 2;
2615 }
2616
2617 return nei_pos - nei_rep;
2618 }
2619
2620
ieee802_11_ext_capab(const u8 * ie,unsigned int capab)2621 int ieee802_11_ext_capab(const u8 *ie, unsigned int capab)
2622 {
2623 if (!ie || ie[1] <= capab / 8)
2624 return 0;
2625 return !!(ie[2 + capab / 8] & BIT(capab % 8));
2626 }
2627
2628
ieee802_11_rsnx_capab_len(const u8 * rsnxe,size_t rsnxe_len,unsigned int capab)2629 bool ieee802_11_rsnx_capab_len(const u8 *rsnxe, size_t rsnxe_len,
2630 unsigned int capab)
2631 {
2632 const u8 *end;
2633 size_t flen, i;
2634 u32 capabs = 0;
2635
2636 if (!rsnxe || rsnxe_len == 0)
2637 return false;
2638 end = rsnxe + rsnxe_len;
2639 flen = (rsnxe[0] & 0x0f) + 1;
2640 if (rsnxe + flen > end)
2641 return false;
2642 if (flen > 4)
2643 flen = 4;
2644 for (i = 0; i < flen; i++)
2645 capabs |= rsnxe[i] << (8 * i);
2646
2647 return capabs & BIT(capab);
2648 }
2649
2650
ieee802_11_rsnx_capab(const u8 * rsnxe,unsigned int capab)2651 bool ieee802_11_rsnx_capab(const u8 *rsnxe, unsigned int capab)
2652 {
2653 return ieee802_11_rsnx_capab_len(rsnxe ? rsnxe + 2 : NULL,
2654 rsnxe ? rsnxe[1] : 0, capab);
2655 }
2656
2657
hostapd_encode_edmg_chan(int edmg_enable,u8 edmg_channel,int primary_channel,struct ieee80211_edmg_config * edmg)2658 void hostapd_encode_edmg_chan(int edmg_enable, u8 edmg_channel,
2659 int primary_channel,
2660 struct ieee80211_edmg_config *edmg)
2661 {
2662 if (!edmg_enable) {
2663 edmg->channels = 0;
2664 edmg->bw_config = 0;
2665 return;
2666 }
2667
2668 /* Only EDMG CB1 and EDMG CB2 contiguous channels supported for now */
2669 switch (edmg_channel) {
2670 case EDMG_CHANNEL_9:
2671 edmg->channels = EDMG_CHANNEL_9_SUBCHANNELS;
2672 edmg->bw_config = EDMG_BW_CONFIG_5;
2673 return;
2674 case EDMG_CHANNEL_10:
2675 edmg->channels = EDMG_CHANNEL_10_SUBCHANNELS;
2676 edmg->bw_config = EDMG_BW_CONFIG_5;
2677 return;
2678 case EDMG_CHANNEL_11:
2679 edmg->channels = EDMG_CHANNEL_11_SUBCHANNELS;
2680 edmg->bw_config = EDMG_BW_CONFIG_5;
2681 return;
2682 case EDMG_CHANNEL_12:
2683 edmg->channels = EDMG_CHANNEL_12_SUBCHANNELS;
2684 edmg->bw_config = EDMG_BW_CONFIG_5;
2685 return;
2686 case EDMG_CHANNEL_13:
2687 edmg->channels = EDMG_CHANNEL_13_SUBCHANNELS;
2688 edmg->bw_config = EDMG_BW_CONFIG_5;
2689 return;
2690 default:
2691 if (primary_channel > 0 && primary_channel < 7) {
2692 edmg->channels = BIT(primary_channel - 1);
2693 edmg->bw_config = EDMG_BW_CONFIG_4;
2694 } else {
2695 edmg->channels = 0;
2696 edmg->bw_config = 0;
2697 }
2698 break;
2699 }
2700 }
2701
2702
2703 /* Check if the requested EDMG configuration is a subset of the allowed
2704 * EDMG configuration. */
ieee802_edmg_is_allowed(struct ieee80211_edmg_config allowed,struct ieee80211_edmg_config requested)2705 int ieee802_edmg_is_allowed(struct ieee80211_edmg_config allowed,
2706 struct ieee80211_edmg_config requested)
2707 {
2708 /*
2709 * The validation check if the requested EDMG configuration
2710 * is a subset of the allowed EDMG configuration:
2711 * 1. Check that the requested channels are part (set) of the allowed
2712 * channels.
2713 * 2. P802.11ay defines the values of bw_config between 4 and 15.
2714 * (bw config % 4) will give us 4 groups inside bw_config definition,
2715 * inside each group we can check the subset just by comparing the
2716 * bw_config value.
2717 * Between this 4 groups, there is no subset relation - as a result of
2718 * the P802.11ay definition.
2719 * bw_config defined by IEEE P802.11ay/D4.0, 9.4.2.251, Table 13.
2720 */
2721 if (((requested.channels & allowed.channels) != requested.channels) ||
2722 ((requested.bw_config % 4) > (allowed.bw_config % 4)) ||
2723 requested.bw_config > allowed.bw_config)
2724 return 0;
2725
2726 return 1;
2727 }
2728
2729
op_class_to_bandwidth(u8 op_class)2730 int op_class_to_bandwidth(u8 op_class)
2731 {
2732 switch (op_class) {
2733 case 81:
2734 case 82:
2735 return 20;
2736 case 83: /* channels 1..9; 40 MHz */
2737 case 84: /* channels 5..13; 40 MHz */
2738 return 40;
2739 case 115: /* channels 36,40,44,48; indoor only */
2740 return 20;
2741 case 116: /* channels 36,44; 40 MHz; indoor only */
2742 case 117: /* channels 40,48; 40 MHz; indoor only */
2743 return 40;
2744 case 118: /* channels 52,56,60,64; dfs */
2745 return 20;
2746 case 119: /* channels 52,60; 40 MHz; dfs */
2747 case 120: /* channels 56,64; 40 MHz; dfs */
2748 return 40;
2749 case 121: /* channels 100-140 */
2750 return 20;
2751 case 122: /* channels 100-142; 40 MHz */
2752 case 123: /* channels 104-136; 40 MHz */
2753 return 40;
2754 case 124: /* channels 149,153,157,161 */
2755 case 125: /* channels 149,153,157,161,165,169,173,177 */
2756 return 20;
2757 case 126: /* channels 149,157,161,165,169,173; 40 MHz */
2758 case 127: /* channels 153..177; 40 MHz */
2759 return 40;
2760 case 128: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80 MHz */
2761 return 80;
2762 case 129: /* center freqs 50, 114, 163; 160 MHz */
2763 return 160;
2764 case 130: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80+80 MHz */
2765 return 80;
2766 case 131: /* UHB channels, 20 MHz: 1, 5, 9.. */
2767 return 20;
2768 case 132: /* UHB channels, 40 MHz: 3, 11, 19.. */
2769 return 40;
2770 case 133: /* UHB channels, 80 MHz: 7, 23, 39.. */
2771 return 80;
2772 case 134: /* UHB channels, 160 MHz: 15, 47, 79.. */
2773 case 135: /* UHB channels, 80+80 MHz: 7, 23, 39.. */
2774 return 160;
2775 case 136: /* UHB channels, 20 MHz: 2 */
2776 return 20;
2777 case 180: /* 60 GHz band, channels 1..8 */
2778 return 2160;
2779 case 181: /* 60 GHz band, EDMG CB2, channels 9..15 */
2780 return 4320;
2781 case 182: /* 60 GHz band, EDMG CB3, channels 17..22 */
2782 return 6480;
2783 case 183: /* 60 GHz band, EDMG CB4, channel 25..29 */
2784 return 8640;
2785 }
2786
2787 return 20;
2788 }
2789
2790
op_class_to_ch_width(u8 op_class)2791 int op_class_to_ch_width(u8 op_class)
2792 {
2793 switch (op_class) {
2794 case 81:
2795 case 82:
2796 return CHANWIDTH_USE_HT;
2797 case 83: /* channels 1..9; 40 MHz */
2798 case 84: /* channels 5..13; 40 MHz */
2799 return CHANWIDTH_USE_HT;
2800 case 115: /* channels 36,40,44,48; indoor only */
2801 return CHANWIDTH_USE_HT;
2802 case 116: /* channels 36,44; 40 MHz; indoor only */
2803 case 117: /* channels 40,48; 40 MHz; indoor only */
2804 return CHANWIDTH_USE_HT;
2805 case 118: /* channels 52,56,60,64; dfs */
2806 return CHANWIDTH_USE_HT;
2807 case 119: /* channels 52,60; 40 MHz; dfs */
2808 case 120: /* channels 56,64; 40 MHz; dfs */
2809 return CHANWIDTH_USE_HT;
2810 case 121: /* channels 100-140 */
2811 return CHANWIDTH_USE_HT;
2812 case 122: /* channels 100-142; 40 MHz */
2813 case 123: /* channels 104-136; 40 MHz */
2814 return CHANWIDTH_USE_HT;
2815 case 124: /* channels 149,153,157,161 */
2816 case 125: /* channels 149,153,157,161,165,169,171 */
2817 return CHANWIDTH_USE_HT;
2818 case 126: /* channels 149,157,165, 173; 40 MHz */
2819 case 127: /* channels 153,161,169,177; 40 MHz */
2820 return CHANWIDTH_USE_HT;
2821 case 128: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80 MHz */
2822 return CHANWIDTH_80MHZ;
2823 case 129: /* center freqs 50, 114, 163; 160 MHz */
2824 return CHANWIDTH_160MHZ;
2825 case 130: /* center freqs 42, 58, 106, 122, 138, 155, 171; 80+80 MHz */
2826 return CHANWIDTH_80P80MHZ;
2827 case 131: /* UHB channels, 20 MHz: 1, 5, 9.. */
2828 return CHANWIDTH_USE_HT;
2829 case 132: /* UHB channels, 40 MHz: 3, 11, 19.. */
2830 return CHANWIDTH_USE_HT;
2831 case 133: /* UHB channels, 80 MHz: 7, 23, 39.. */
2832 return CHANWIDTH_80MHZ;
2833 case 134: /* UHB channels, 160 MHz: 15, 47, 79.. */
2834 return CHANWIDTH_160MHZ;
2835 case 135: /* UHB channels, 80+80 MHz: 7, 23, 39.. */
2836 return CHANWIDTH_80P80MHZ;
2837 case 136: /* UHB channels, 20 MHz: 2 */
2838 return CHANWIDTH_USE_HT;
2839 case 180: /* 60 GHz band, channels 1..8 */
2840 return CHANWIDTH_2160MHZ;
2841 case 181: /* 60 GHz band, EDMG CB2, channels 9..15 */
2842 return CHANWIDTH_4320MHZ;
2843 case 182: /* 60 GHz band, EDMG CB3, channels 17..22 */
2844 return CHANWIDTH_6480MHZ;
2845 case 183: /* 60 GHz band, EDMG CB4, channel 25..29 */
2846 return CHANWIDTH_8640MHZ;
2847 }
2848 return CHANWIDTH_USE_HT;
2849 }
2850 #ifdef CONFIG_MLD_PATCH
ieee802_11_defrag_data(const u8 * data,size_t len,bool ext_elem)2851 struct wpabuf * ieee802_11_defrag_data(const u8 *data, size_t len, bool ext_elem)
2852 {
2853 struct wpabuf *buf;
2854 const u8 *pos, *end = data + len;
2855 size_t min_defrag_len = ext_elem ? 255 : 256;
2856
2857 if (!data || !len)
2858 return NULL;
2859
2860 if (len < min_defrag_len)
2861 return wpabuf_alloc_copy(data, len);
2862
2863 buf = wpabuf_alloc_copy(data, min_defrag_len - 1);
2864 if (!buf)
2865 return NULL;
2866
2867 pos = &data[min_defrag_len - 1];
2868 len -= min_defrag_len - 1;
2869 while (len > 2 && pos[0] == WLAN_EID_FRAGMENT && pos[1]) {
2870 int ret;
2871 size_t elen = 2 + pos[1];
2872
2873 if (elen > (size_t) (end - pos) || elen > len)
2874 break;
2875 ret = wpabuf_resize(&buf, pos[1]);
2876 if (ret < 0) {
2877 wpabuf_free(buf);
2878 return NULL;
2879 }
2880
2881 /* Copy only the fragment data (without the EID and length) */
2882 wpabuf_put_data(buf, &pos[2], pos[1]);
2883 pos += elen;
2884 len -= elen;
2885 }
2886
2887 return buf;
2888 }
2889 #else
ieee802_11_defrag_data(const struct ieee802_11_elems * elems,u8 eid,u8 eid_ext,const u8 * data,u8 len)2890 struct wpabuf * ieee802_11_defrag_data(const struct ieee802_11_elems *elems,
2891 u8 eid, u8 eid_ext,
2892 const u8 *data, u8 len)
2893 {
2894 const struct frag_ies_info *frag_ies = &elems->frag_ies;
2895 struct wpabuf *buf;
2896 unsigned int i;
2897
2898 if (!elems || !data || !len)
2899 return NULL;
2900
2901 buf = wpabuf_alloc_copy(data, len);
2902 if (!buf)
2903 return NULL;
2904
2905 for (i = 0; i < frag_ies->n_frags; i++) {
2906 int ret;
2907
2908 if (frag_ies->frags[i].eid != eid ||
2909 frag_ies->frags[i].eid_ext != eid_ext)
2910 continue;
2911
2912 ret = wpabuf_resize(&buf, frag_ies->frags[i].ie_len);
2913 if (ret < 0) {
2914 wpabuf_free(buf);
2915 return NULL;
2916 }
2917
2918 /* Copy only the fragment data (without the EID and length) */
2919 wpabuf_put_data(buf, frag_ies->frags[i].ie,
2920 frag_ies->frags[i].ie_len);
2921 }
2922
2923 return buf;
2924 }
2925 #endif
2926
ieee802_11_defrag(const struct ieee802_11_elems * elems,u8 eid,u8 eid_ext)2927 struct wpabuf * ieee802_11_defrag(const struct ieee802_11_elems *elems,
2928 u8 eid, u8 eid_ext)
2929 {
2930 const u8 *data;
2931 u8 len;
2932
2933 /*
2934 * TODO: Defragmentation mechanism can be supported for all IEs. For now
2935 * handle only those that are used (or use ieee802_11_defrag_data()).
2936 */
2937 switch (eid) {
2938 case WLAN_EID_EXTENSION:
2939 switch (eid_ext) {
2940 case WLAN_EID_EXT_FILS_HLP_CONTAINER:
2941 data = elems->fils_hlp;
2942 len = elems->fils_hlp_len;
2943 break;
2944 case WLAN_EID_EXT_WRAPPED_DATA:
2945 data = elems->wrapped_data;
2946 len = elems->wrapped_data_len;
2947 break;
2948 default:
2949 wpa_printf(MSG_DEBUG,
2950 "Defragmentation not supported. eid_ext=%u",
2951 eid_ext);
2952 return NULL;
2953 }
2954 break;
2955 default:
2956 wpa_printf(MSG_DEBUG,
2957 "Defragmentation not supported. eid=%u", eid);
2958 return NULL;
2959 }
2960 #ifdef CONFIG_MLD_PATCH
2961 return ieee802_11_defrag_data(data, len, true);
2962 #else
2963 return ieee802_11_defrag_data(elems, eid, eid_ext, data, len);
2964 #endif
2965 }
2966
parse_oh_ht_mcs_for_max_noss(struct ieee80211_ht_capabilities * ht_caps,u8 parse_rx)2967 static int parse_oh_ht_mcs_for_max_noss(
2968 struct ieee80211_ht_capabilities *ht_caps,
2969 u8 parse_rx)
2970 {
2971 int max_noss_rx = 1;
2972 if (ht_caps == NULL) {
2973 return max_noss_rx;
2974 }
2975 int index;
2976 for (index = MAX_NOSS_RX_LENGTH; index >= 1; index--) {
2977 if (ht_caps->supported_mcs_set[index - 1] > 0) {
2978 max_noss_rx = index;
2979 break;
2980 }
2981 }
2982 if (parse_rx) {
2983 return max_noss_rx;
2984 }
2985 u8 supp_tx_macs_set = ht_caps->supported_mcs_set[12];
2986 u8 tx_macs_set_def = supp_tx_macs_set & 0x1;
2987 u8 tx_rx_macs_not_equal = (supp_tx_macs_set >> 1) & 0x1;
2988 if (tx_macs_set_def && tx_rx_macs_not_equal) {
2989 int max_noss_tx_field = (supp_tx_macs_set >> 2) & 0x3;
2990 // The maximum number of Tx streams is 1 more than the field value.
2991 return max_noss_tx_field + 1;
2992 }
2993 return max_noss_rx;
2994 }
2995
parse_oh_macs_for_max_noss(u16 macs_map,int max_stream_allow)2996 static int parse_oh_macs_for_max_noss(u16 macs_map, int max_stream_allow)
2997 {
2998 int max_noss = 1;
2999 int index;
3000 for (index = max_stream_allow; index >= 1; index--) {
3001 int stream_map = (macs_map >> ((index - 1) * 2)) & 0x3;
3002 // 3 means unsupported
3003 if (stream_map != 3) {
3004 max_noss = index;
3005 break;
3006 }
3007 }
3008 return max_noss;
3009 }
3010
get_oh_max_noss_capa(struct ieee802_11_elems * elements,int parse_rx)3011 int get_oh_max_noss_capa(struct ieee802_11_elems *elements, int parse_rx)
3012 {
3013 int max_noss = 1;
3014 struct ieee80211_ht_capabilities *ht_cap =
3015 (struct ieee80211_ht_capabilities *) elements->ht_capabilities;
3016 struct ieee80211_vht_capabilities *vht_cap =
3017 (struct ieee80211_vht_capabilities *) elements->vht_capabilities;
3018 struct ieee80211_he_capabilities *he_cap =
3019 (struct ieee80211_he_capabilities *) elements->he_capabilities;
3020 if (ht_cap) {
3021 int max_noss_ht = parse_oh_ht_mcs_for_max_noss(ht_cap, parse_rx);
3022 if (max_noss_ht > max_noss) {
3023 max_noss = max_noss_ht;
3024 }
3025 }
3026 le16 macs_map;
3027 if (vht_cap) {
3028 macs_map = (parse_rx) ? vht_cap->vht_supported_mcs_set.rx_map:
3029 vht_cap->vht_supported_mcs_set.tx_map;
3030 int max_noss_vht = parse_oh_macs_for_max_noss(
3031 le_to_host16(macs_map), VHT_RX_NSS_MAX_STREAMS);
3032 if (max_noss_vht > max_noss) {
3033 max_noss = max_noss_vht;
3034 }
3035 }
3036 if (he_cap) {
3037 macs_map = (parse_rx) ? he_cap->he_basic_supported_mcs_set.rx_map:
3038 he_cap->he_basic_supported_mcs_set.tx_map;
3039 int max_nss_he = parse_oh_macs_for_max_noss(
3040 le_to_host16(macs_map), HE_NSS_MAX_STREAMS);
3041 if (max_nss_he > max_noss) {
3042 max_noss = max_nss_he;
3043 }
3044 }
3045 return max_noss;
3046 }
3047
get_oh_support_channel_width(struct ieee802_11_elems * elements)3048 struct supp_channel_width get_oh_support_channel_width(
3049 struct ieee802_11_elems *elements)
3050 {
3051 struct supp_channel_width support_width;
3052 support_width.is_160_supp = 0;
3053 support_width.is_80p80_supp = 0;
3054 if (elements == NULL) {
3055 return support_width;
3056 }
3057
3058 struct ieee80211_vht_capabilities *vht_cap =
3059 (struct ieee80211_vht_capabilities *) elements->vht_capabilities;
3060 struct ieee80211_he_capabilities *he_cap =
3061 (struct ieee80211_he_capabilities *) elements->he_capabilities;
3062
3063 if (vht_cap) {
3064 le32 vht_cap_info =
3065 le_to_host32(vht_cap->vht_capabilities_info);
3066 if (vht_cap_info & VHT_CAP_SUPP_CHAN_WIDTH_160MHZ) {
3067 support_width.is_160_supp = 1;
3068 }
3069 if (vht_cap_info & VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) {
3070 support_width.is_80p80_supp = 1;
3071 }
3072 }
3073 if (he_cap) {
3074 u8 channels_width_info =
3075 he_cap->he_phy_capab_info[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX];
3076 if (channels_width_info & HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G) {
3077 support_width.is_160_supp = 1;
3078 }
3079 if (channels_width_info & HE_PHYCAP_CHANNEL_WIDTH_SET_80PLUS80MHZ_IN_5G) {
3080 support_width.is_80p80_supp = 1;
3081 }
3082 }
3083 wpa_printf(MSG_DEBUG, " IE indicate 160 supported: %u, 80+80 supported: %u",
3084 support_width.is_160_supp, support_width.is_80p80_supp);
3085 return support_width;
3086 }
3087
get_oh_vht_oper_channel_width(struct ieee80211_vht_operation_info * vht_operation_info)3088 static enum chan_width get_oh_vht_oper_channel_width(
3089 struct ieee80211_vht_operation_info *vht_operation_info)
3090 {
3091 enum chan_width ch_width = CHAN_WIDTH_UNKNOWN;
3092 u8 tmp_seg0, tmp_seg1;
3093 switch (vht_operation_info->vht_op_info_chwidth) {
3094 case VHT_CHAN_WIDTH_TYPE_1:
3095 tmp_seg0 = vht_operation_info->vht_op_info_chan_center_freq_seg0_idx;
3096 tmp_seg1 = vht_operation_info->vht_op_info_chan_center_freq_seg1_idx;
3097 if (tmp_seg1 && abs(tmp_seg1 - tmp_seg0) == CHAN_CENTER_FREQ_VALUE) {
3098 ch_width = CHAN_WIDTH_160;
3099 } else if (tmp_seg1) {
3100 ch_width = CHAN_WIDTH_80P80;
3101 } else {
3102 ch_width = CHAN_WIDTH_80;
3103 }
3104 break;
3105 case VHT_CHAN_WIDTH_TYPE_2:
3106 ch_width = CHAN_WIDTH_160;
3107 break;
3108 case VHT_CHAN_WIDTH_TYPE_3:
3109 ch_width = CHAN_WIDTH_80P80;
3110 break;
3111 default:
3112 break;
3113 }
3114 wpa_printf(MSG_DEBUG, " VHT operation CBW: %u", ch_width);
3115 return ch_width;
3116 }
3117
get_oh_6ghz_operation_channel_width(struct ieee80211_6ghz_oper_information * six_ghz_operation_info)3118 static enum chan_width get_oh_6ghz_operation_channel_width(
3119 struct ieee80211_6ghz_oper_information * six_ghz_operation_info)
3120 {
3121 enum chan_width ch_width = CHAN_WIDTH_UNKNOWN;
3122 u8 tmp_seg0, tmp_seg1;
3123 switch (six_ghz_operation_info->control & SIX_GHZ_CONTROL_CHANNEL_WIDTH_MASK) {
3124 case 0:
3125 ch_width = CHAN_WIDTH_20;
3126 break;
3127 case SIX_GHZ_CHANN_WIDTH_TYPE_1:
3128 ch_width = CHAN_WIDTH_40;
3129 break;
3130 case SIX_GHZ_CHANN_WIDTH_TYPE_2:
3131 ch_width = CHAN_WIDTH_80;
3132 break;
3133 case SIX_GHZ_CHANN_WIDTH_TYPE_3:
3134 tmp_seg0 = six_ghz_operation_info->center_freq_seg0_index;
3135 tmp_seg1 = six_ghz_operation_info->center_freq_seg1_index;
3136 if (abs(tmp_seg1 - tmp_seg0) == CHAN_CENTER_FREQ_VALUE) {
3137 ch_width = CHAN_WIDTH_160;
3138 } else {
3139 ch_width = CHAN_WIDTH_80P80;
3140 }
3141 break;
3142 default:
3143 break;
3144 }
3145 wpa_printf(MSG_DEBUG, " 6GHz operation CBW: %u", ch_width);
3146 return ch_width;
3147 }
3148
get_oh_he_oper_channel_width(struct ieee80211_he_operation * he_operation,int he_operation_len)3149 static enum chan_width get_oh_he_oper_channel_width(
3150 struct ieee80211_he_operation *he_operation,
3151 int he_operation_len)
3152 {
3153 enum chan_width ch_width = CHAN_WIDTH_UNKNOWN;
3154 u8 is_6ghz_present =
3155 (he_operation->he_oper_params & HE_OPERATION_6GHZ_OPER_INFO) ? 1 : 0;
3156 u8 is_vht_present =
3157 (he_operation->he_oper_params & HE_OPERATION_VHT_OPER_INFO) ? 1 : 0;
3158 u8 is_cohosted_present =
3159 (he_operation->he_oper_params & HE_OPERATION_COHOSTED_BSS) ? 1 : 0;
3160 int expect_len = HE_OPERATION_IE_MIN_LEN
3161 + (is_6ghz_present ? HE_OPERATION_6GHZ_OPER_INFO_LEN : 0)
3162 + (is_vht_present ? HE_OPERATION_VHT_OPER_INFO_LEN : 0)
3163 + (is_cohosted_present
3164 ? HE_OPERATION_COHOSTED_BSSID_INDICATOR_LEN : 0);
3165 if (he_operation_len < expect_len) {
3166 return ch_width;
3167 }
3168
3169 const u8 *he_operation_u8 = (const u8 *) he_operation;
3170 if (is_6ghz_present) {
3171 struct ieee80211_6ghz_oper_information *six_ghz_operation_info =
3172 (struct ieee80211_6ghz_oper_information *)
3173 (he_operation_u8 + HE_OPERATION_IE_MIN_LEN
3174 + (is_vht_present ? HE_OPERATION_VHT_OPER_INFO_LEN : 0)
3175 + (is_cohosted_present
3176 ? HE_OPERATION_COHOSTED_BSSID_INDICATOR_LEN : 0));
3177 ch_width = get_oh_6ghz_operation_channel_width(six_ghz_operation_info);
3178 }
3179 if (ch_width == CHAN_WIDTH_UNKNOWN && is_vht_present) {
3180 struct ieee80211_vht_operation_info *vht_operation_info =
3181 (struct ieee80211_vht_operation_info *)
3182 (he_operation_u8 + HE_OPERATION_IE_MIN_LEN);
3183 ch_width = get_oh_vht_oper_channel_width(vht_operation_info);
3184 }
3185 wpa_printf(MSG_DEBUG, " HE operation CBW: %u", ch_width);
3186 return ch_width;
3187 }
3188
get_oh_oper_channel_width(struct ieee802_11_elems * elements)3189 enum chan_width get_oh_oper_channel_width(struct ieee802_11_elems *elements)
3190 {
3191 enum chan_width ch_width = CHAN_WIDTH_UNKNOWN;
3192 if (elements == NULL) {
3193 return ch_width;
3194 }
3195
3196 struct ieee80211_ht_operation *ht_operation =
3197 (struct ieee80211_ht_operation *) elements->ht_operation;
3198 struct ieee80211_vht_operation_info *vht_operation_info =
3199 (struct ieee80211_vht_operation_info *) elements->vht_operation;
3200 struct ieee80211_he_operation *he_oper =
3201 (struct ieee80211_he_operation *) elements->he_operation;
3202 if (he_oper) {
3203 ch_width = get_oh_he_oper_channel_width(
3204 he_oper, elements->he_operation_len);
3205 }
3206
3207 if (ch_width == CHAN_WIDTH_UNKNOWN && vht_operation_info) {
3208 ch_width = get_oh_vht_oper_channel_width(vht_operation_info);
3209 }
3210
3211 if (ch_width == CHAN_WIDTH_UNKNOWN && ht_operation) {
3212 u8 sec_chan_offset =
3213 ht_operation->ht_param & HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;
3214 ch_width = (sec_chan_offset == 0) ? CHAN_WIDTH_20 : CHAN_WIDTH_40;
3215 }
3216 wpa_printf(MSG_DEBUG, " overall operation CBW: %u", ch_width);
3217 return ch_width;
3218 }
3219
get_oh_sta_oper_chan_width(enum chan_width ap_oper_chan_width,struct supp_channel_width sta_supp_chan_width)3220 enum chan_width get_oh_sta_oper_chan_width(
3221 enum chan_width ap_oper_chan_width,
3222 struct supp_channel_width sta_supp_chan_width)
3223 {
3224 if (ap_oper_chan_width == CHAN_WIDTH_160) {
3225 return (sta_supp_chan_width.is_160_supp)
3226 ? CHAN_WIDTH_160 : CHAN_WIDTH_80;
3227 }
3228 if (ap_oper_chan_width == CHAN_WIDTH_80P80) {
3229 return (sta_supp_chan_width.is_80p80_supp)
3230 ? CHAN_WIDTH_80P80 : CHAN_WIDTH_80;
3231 }
3232 return ap_oper_chan_width;
3233 }
3234 #ifdef CONFIG_MLD_PATCH
get_ml_ie(const u8 * ies,size_t len,u8 type)3235 const u8 * get_ml_ie(const u8 *ies, size_t len, u8 type)
3236 {
3237 const struct element *elem;
3238
3239 if (!ies)
3240 return NULL;
3241
3242 for_each_element_extid(elem, WLAN_EID_EXT_MULTI_LINK, ies, len) {
3243 if (elem->datalen >= 2 &&
3244 (elem->data[1] & MULTI_LINK_CONTROL_TYPE_MASK) == type)
3245 return &elem->id;
3246 }
3247
3248 return NULL;
3249 }
3250
get_basic_mle_mld_addr(const u8 * buf,size_t len)3251 const u8 * get_basic_mle_mld_addr(const u8 *buf, size_t len)
3252 {
3253 const size_t mld_addr_pos =
3254 2 /* Control field */ +
3255 1 /* Common Info Length field */;
3256 const size_t fixed_len = mld_addr_pos +
3257 ETH_ALEN /* MLD MAC Address field */;
3258
3259 if (len < fixed_len)
3260 return NULL;
3261
3262 if ((buf[0] & MULTI_LINK_CONTROL_TYPE_MASK) !=
3263 MULTI_LINK_CONTROL_TYPE_BASIC)
3264 return NULL;
3265
3266 return &buf[mld_addr_pos];
3267 }
3268
ieee802_11_defrag_mle(struct ieee802_11_elems * elems,u8 type)3269 struct wpabuf * ieee802_11_defrag_mle(struct ieee802_11_elems *elems, u8 type)
3270 {
3271 const u8 *data;
3272 size_t len;
3273
3274 switch (type) {
3275 case MULTI_LINK_CONTROL_TYPE_BASIC:
3276 data = elems->basic_mle;
3277 len = elems->basic_mle_len;
3278 break;
3279 case MULTI_LINK_CONTROL_TYPE_PROBE_REQ:
3280 data = elems->probe_req_mle;
3281 len = elems->probe_req_mle_len;
3282 break;
3283 case MULTI_LINK_CONTROL_TYPE_RECONF:
3284 data = elems->reconf_mle;
3285 len = elems->reconf_mle_len;
3286 break;
3287 case MULTI_LINK_CONTROL_TYPE_TDLS:
3288 data = elems->tdls_mle;
3289 len = elems->tdls_mle_len;
3290 break;
3291 case MULTI_LINK_CONTROL_TYPE_PRIOR_ACCESS:
3292 data = elems->prior_access_mle;
3293 len = elems->prior_access_mle_len;
3294 break;
3295 default:
3296 wpa_printf(MSG_DEBUG, "Defragmentation not supported for multilink element type=%u", type);
3297 return NULL;
3298 }
3299
3300 return ieee802_11_defrag_data(data, len, true);
3301 }
3302 #endif