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