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