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