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