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