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