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