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