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