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