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