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