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