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