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