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