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