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