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