• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * hostapd / IEEE 802.11 Management: Beacon and Probe Request/Response
3  * Copyright (c) 2002-2004, Instant802 Networks, Inc.
4  * Copyright (c) 2005-2006, Devicescape Software, Inc.
5  * Copyright (c) 2008-2012, Jouni Malinen <j@w1.fi>
6  *
7  * This software may be distributed under the terms of the BSD license.
8  * See README for more details.
9  */
10 
11 #include "utils/includes.h"
12 
13 #ifndef CONFIG_NATIVE_WINDOWS
14 
15 #include "utils/common.h"
16 #include "common/ieee802_11_defs.h"
17 #include "common/ieee802_11_common.h"
18 #include "common/hw_features_common.h"
19 #include "common/wpa_ctrl.h"
20 #include "wps/wps_defs.h"
21 #include "p2p/p2p.h"
22 #include "hostapd.h"
23 #include "ieee802_11.h"
24 #include "wpa_auth.h"
25 #include "wmm.h"
26 #include "ap_config.h"
27 #include "sta_info.h"
28 #include "p2p_hostapd.h"
29 #include "ap_drv_ops.h"
30 #include "beacon.h"
31 #include "hs20.h"
32 #include "dfs.h"
33 #include "taxonomy.h"
34 #include "ieee802_11_auth.h"
35 #ifdef LOS_CONFIG_MESH
36 #include "soc_mesh.h"
37 #endif /* LOS_CONFIG_MESH */
38 
39 #ifdef NEED_AP_MLME
40 #ifndef EXT_CODE_CROP
41 
hostapd_eid_bss_load(struct hostapd_data * hapd,u8 * eid,size_t len)42 static u8 * hostapd_eid_bss_load(struct hostapd_data *hapd, u8 *eid, size_t len)
43 {
44 	if (len < 2 + 5)
45 		return eid;
46 
47 #ifdef CONFIG_TESTING_OPTIONS
48 	if (hapd->conf->bss_load_test_set) {
49 		*eid++ = WLAN_EID_BSS_LOAD;
50 		*eid++ = 5;
51 		os_memcpy(eid, hapd->conf->bss_load_test, 5);
52 		eid += 5;
53 		return eid;
54 	}
55 #endif /* CONFIG_TESTING_OPTIONS */
56 	if (hapd->conf->bss_load_update_period) {
57 		*eid++ = WLAN_EID_BSS_LOAD;
58 		*eid++ = 5;
59 		WPA_PUT_LE16(eid, hapd->num_sta);
60 		eid += 2;
61 		*eid++ = hapd->iface->channel_utilization;
62 		WPA_PUT_LE16(eid, 0); /* no available admission capabity */
63 		eid += 2;
64 	}
65 	return eid;
66 }
67 
68 
ieee802_11_erp_info(struct hostapd_data * hapd)69 static u8 ieee802_11_erp_info(struct hostapd_data *hapd)
70 {
71 	u8 erp = 0;
72 
73 	if (hapd->iface->current_mode == NULL ||
74 	    hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G)
75 		return 0;
76 
77 	if (hapd->iface->olbc)
78 		erp |= ERP_INFO_USE_PROTECTION;
79 	if (hapd->iface->num_sta_non_erp > 0) {
80 		erp |= ERP_INFO_NON_ERP_PRESENT |
81 			ERP_INFO_USE_PROTECTION;
82 	}
83 	if (hapd->iface->num_sta_no_short_preamble > 0 ||
84 	    hapd->iconf->preamble == LONG_PREAMBLE)
85 		erp |= ERP_INFO_BARKER_PREAMBLE_MODE;
86 
87 	return erp;
88 }
89 #endif /* EXT_CODE_CROP */
90 
hostapd_eid_ds_params(struct hostapd_data * hapd,u8 * eid)91 static u8 * hostapd_eid_ds_params(struct hostapd_data *hapd, u8 *eid)
92 {
93 	*eid++ = WLAN_EID_DS_PARAMS;
94 	*eid++ = 1;
95 	*eid++ = hapd->iconf->channel;
96 	return eid;
97 }
98 
99 #ifndef EXT_CODE_CROP
hostapd_eid_erp_info(struct hostapd_data * hapd,u8 * eid)100 static u8 * hostapd_eid_erp_info(struct hostapd_data *hapd, u8 *eid)
101 {
102 	if (hapd->iface->current_mode == NULL ||
103 	    hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G)
104 		return eid;
105 
106 	/* Set NonERP_present and use_protection bits if there
107 	 * are any associated NonERP stations. */
108 	/* TODO: use_protection bit can be set to zero even if
109 	 * there are NonERP stations present. This optimization
110 	 * might be useful if NonERP stations are "quiet".
111 	 * See 802.11g/D6 E-1 for recommended practice.
112 	 * In addition, Non ERP present might be set, if AP detects Non ERP
113 	 * operation on other APs. */
114 
115 	/* Add ERP Information element */
116 	*eid++ = WLAN_EID_ERP_INFO;
117 	*eid++ = 1;
118 	*eid++ = ieee802_11_erp_info(hapd);
119 
120 	return eid;
121 }
122 
123 
hostapd_eid_pwr_constraint(struct hostapd_data * hapd,u8 * eid)124 static u8 * hostapd_eid_pwr_constraint(struct hostapd_data *hapd, u8 *eid)
125 {
126 	u8 *pos = eid;
127 	u8 local_pwr_constraint = 0;
128 	int dfs;
129 
130 	if (hapd->iface->current_mode == NULL ||
131 	    hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211A)
132 		return eid;
133 
134 	/* Let host drivers add this IE if DFS support is offloaded */
135 	if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)
136 		return eid;
137 
138 	/*
139 	 * There is no DFS support and power constraint was not directly
140 	 * requested by config option.
141 	 */
142 	if (!hapd->iconf->ieee80211h &&
143 	    hapd->iconf->local_pwr_constraint == -1)
144 		return eid;
145 #ifndef EXT_CODE_CROP
146 	/* Check if DFS is required by regulatory. */
147 	dfs = hostapd_is_dfs_required(hapd->iface);
148 	if (dfs < 0) {
149 		wpa_printf(MSG_WARNING, "Failed to check if DFS is required; ret=%d",
150 			   dfs);
151 		dfs = 0;
152 	}
153 
154 	if (dfs == 0 && hapd->iconf->local_pwr_constraint == -1)
155 		return eid;
156 #endif /* EXT_CODE_CROP */
157 	/*
158 	 * ieee80211h (DFS) is enabled so Power Constraint element shall
159 	 * be added when running on DFS channel whenever local_pwr_constraint
160 	 * is configured or not. In order to meet regulations when TPC is not
161 	 * implemented using a transmit power that is below the legal maximum
162 	 * (including any mitigation factor) should help. In this case,
163 	 * indicate 3 dB below maximum allowed transmit power.
164 	 */
165 	if (hapd->iconf->local_pwr_constraint == -1)
166 		local_pwr_constraint = 3;
167 
168 	/*
169 	 * A STA that is not an AP shall use a transmit power less than or
170 	 * equal to the local maximum transmit power level for the channel.
171 	 * The local maximum transmit power can be calculated from the formula:
172 	 * local max TX pwr = max TX pwr - local pwr constraint
173 	 * Where max TX pwr is maximum transmit power level specified for
174 	 * channel in Country element and local pwr constraint is specified
175 	 * for channel in this Power Constraint element.
176 	 */
177 
178 	/* Element ID */
179 	*pos++ = WLAN_EID_PWR_CONSTRAINT;
180 	/* Length */
181 	*pos++ = 1;
182 	/* Local Power Constraint */
183 	if (local_pwr_constraint)
184 		*pos++ = local_pwr_constraint;
185 	else
186 		*pos++ = hapd->iconf->local_pwr_constraint;
187 
188 	return pos;
189 }
190 
191 
hostapd_eid_country_add(u8 * pos,u8 * end,int chan_spacing,struct hostapd_channel_data * start,struct hostapd_channel_data * prev)192 static u8 * hostapd_eid_country_add(u8 *pos, u8 *end, int chan_spacing,
193 				    struct hostapd_channel_data *start,
194 				    struct hostapd_channel_data *prev)
195 {
196 	if (end - pos < 3)
197 		return pos;
198 
199 	/* first channel number */
200 	*pos++ = start->chan;
201 	/* number of channels */
202 	*pos++ = (prev->chan - start->chan) / chan_spacing + 1;
203 	/* maximum transmit power level */
204 	*pos++ = start->max_tx_power;
205 
206 	return pos;
207 }
208 
209 
hostapd_eid_country(struct hostapd_data * hapd,u8 * eid,int max_len)210 static u8 * hostapd_eid_country(struct hostapd_data *hapd, u8 *eid,
211 				int max_len)
212 {
213 	u8 *pos = eid;
214 	u8 *end = eid + max_len;
215 	int i;
216 	struct hostapd_hw_modes *mode;
217 	struct hostapd_channel_data *start, *prev;
218 	int chan_spacing = 1;
219 
220 	if (!hapd->iconf->ieee80211d || max_len < 6 ||
221 	    hapd->iface->current_mode == NULL)
222 		return eid;
223 
224 	*pos++ = WLAN_EID_COUNTRY;
225 	pos++; /* length will be set later */
226 	os_memcpy(pos, hapd->iconf->country, 3); /* e.g., 'US ' */
227 	pos += 3;
228 
229 	mode = hapd->iface->current_mode;
230 	if (mode->mode == HOSTAPD_MODE_IEEE80211A)
231 		chan_spacing = 4;
232 
233 	start = prev = NULL;
234 	for (i = 0; i < mode->num_channels; i++) {
235 		struct hostapd_channel_data *chan = &mode->channels[i];
236 		if (chan->flag & HOSTAPD_CHAN_DISABLED)
237 			continue;
238 		if (start && prev &&
239 		    prev->chan + chan_spacing == chan->chan &&
240 		    start->max_tx_power == chan->max_tx_power) {
241 			prev = chan;
242 			continue; /* can use same entry */
243 		}
244 
245 		if (start && prev) {
246 			pos = hostapd_eid_country_add(pos, end, chan_spacing,
247 						      start, prev);
248 			start = NULL;
249 		}
250 
251 		/* Start new group */
252 		start = prev = chan;
253 	}
254 
255 	if (start) {
256 		pos = hostapd_eid_country_add(pos, end, chan_spacing,
257 					      start, prev);
258 	}
259 
260 	if ((pos - eid) & 1) {
261 		if (end - pos < 1)
262 			return eid;
263 		*pos++ = 0; /* pad for 16-bit alignment */
264 	}
265 
266 	eid[1] = (pos - eid) - 2;
267 
268 	return pos;
269 }
270 #endif /* EXT_CODE_CROP */
271 
hostapd_wpa_ie(struct hostapd_data * hapd,u8 eid)272 const u8 * hostapd_wpa_ie(struct hostapd_data *hapd, u8 eid)
273 {
274 	const u8 *ies;
275 	size_t ies_len;
276 
277 	ies = wpa_auth_get_wpa_ie(hapd->wpa_auth, &ies_len);
278 	if (!ies)
279 		return NULL;
280 
281 	return get_ie(ies, ies_len, eid);
282 }
283 
284 
hostapd_vendor_wpa_ie(struct hostapd_data * hapd,u32 vendor_type)285 static const u8 * hostapd_vendor_wpa_ie(struct hostapd_data *hapd,
286 					u32 vendor_type)
287 {
288 	const u8 *ies;
289 	size_t ies_len;
290 
291 	ies = wpa_auth_get_wpa_ie(hapd->wpa_auth, &ies_len);
292 	if (!ies)
293 		return NULL;
294 
295 	return get_vendor_ie(ies, ies_len, vendor_type);
296 }
297 
298 
hostapd_get_rsne(struct hostapd_data * hapd,u8 * pos,size_t len)299 static u8 * hostapd_get_rsne(struct hostapd_data *hapd, u8 *pos, size_t len)
300 {
301 	const u8 *ie;
302 
303 	ie = hostapd_wpa_ie(hapd, WLAN_EID_RSN);
304 	if (!ie || 2U + ie[1] > len)
305 		return pos;
306 
307 	os_memcpy(pos, ie, 2 + ie[1]);
308 	return pos + 2 + ie[1];
309 }
310 
311 
hostapd_get_mde(struct hostapd_data * hapd,u8 * pos,size_t len)312 static u8 * hostapd_get_mde(struct hostapd_data *hapd, u8 *pos, size_t len)
313 {
314 	const u8 *ie;
315 
316 	ie = hostapd_wpa_ie(hapd, WLAN_EID_MOBILITY_DOMAIN);
317 	if (!ie || 2U + ie[1] > len)
318 		return pos;
319 
320 	os_memcpy(pos, ie, 2 + ie[1]);
321 	return pos + 2 + ie[1];
322 }
323 
324 
hostapd_get_rsnxe(struct hostapd_data * hapd,u8 * pos,size_t len)325 static u8 * hostapd_get_rsnxe(struct hostapd_data *hapd, u8 *pos, size_t len)
326 {
327 	const u8 *ie;
328 
329 #ifdef CONFIG_TESTING_OPTIONS
330 	if (hapd->conf->no_beacon_rsnxe) {
331 		wpa_printf(MSG_INFO, "TESTING: Do not add RSNXE into Beacon");
332 		return pos;
333 	}
334 #endif /* CONFIG_TESTING_OPTIONS */
335 	ie = hostapd_wpa_ie(hapd, WLAN_EID_RSNX);
336 	if (!ie || 2U + ie[1] > len)
337 		return pos;
338 
339 	os_memcpy(pos, ie, 2 + ie[1]);
340 	return pos + 2 + ie[1];
341 }
342 
343 
hostapd_get_wpa_ie(struct hostapd_data * hapd,u8 * pos,size_t len)344 static u8 * hostapd_get_wpa_ie(struct hostapd_data *hapd, u8 *pos, size_t len)
345 {
346 	const u8 *ie;
347 
348 	ie = hostapd_vendor_wpa_ie(hapd, WPA_IE_VENDOR_TYPE);
349 	if (!ie || 2U + ie[1] > len)
350 		return pos;
351 
352 	os_memcpy(pos, ie, 2 + ie[1]);
353 	return pos + 2 + ie[1];
354 }
355 
356 
hostapd_get_osen_ie(struct hostapd_data * hapd,u8 * pos,size_t len)357 static u8 * hostapd_get_osen_ie(struct hostapd_data *hapd, u8 *pos, size_t len)
358 {
359 	const u8 *ie;
360 
361 	ie = hostapd_vendor_wpa_ie(hapd, OSEN_IE_VENDOR_TYPE);
362 	if (!ie || 2U + ie[1] > len)
363 		return pos;
364 
365 	os_memcpy(pos, ie, 2 + ie[1]);
366 	return pos + 2 + ie[1];
367 }
368 
369 #ifndef EXT_CODE_CROP
hostapd_eid_csa(struct hostapd_data * hapd,u8 * eid)370 static u8 * hostapd_eid_csa(struct hostapd_data *hapd, u8 *eid)
371 {
372 #ifdef CONFIG_TESTING_OPTIONS
373 	if (hapd->iface->cs_oper_class && hapd->iconf->ecsa_ie_only)
374 		return eid;
375 #endif /* CONFIG_TESTING_OPTIONS */
376 
377 	if (!hapd->cs_freq_params.channel)
378 		return eid;
379 
380 	*eid++ = WLAN_EID_CHANNEL_SWITCH;
381 	*eid++ = 3;
382 	*eid++ = hapd->cs_block_tx;
383 	*eid++ = hapd->cs_freq_params.channel;
384 	*eid++ = hapd->cs_count;
385 
386 	return eid;
387 }
388 
389 
hostapd_eid_ecsa(struct hostapd_data * hapd,u8 * eid)390 static u8 * hostapd_eid_ecsa(struct hostapd_data *hapd, u8 *eid)
391 {
392 	if (!hapd->cs_freq_params.channel || !hapd->iface->cs_oper_class)
393 		return eid;
394 
395 	*eid++ = WLAN_EID_EXT_CHANSWITCH_ANN;
396 	*eid++ = 4;
397 	*eid++ = hapd->cs_block_tx;
398 	*eid++ = hapd->iface->cs_oper_class;
399 	*eid++ = hapd->cs_freq_params.channel;
400 	*eid++ = hapd->cs_count;
401 
402 	return eid;
403 }
404 
405 
hostapd_eid_supported_op_classes(struct hostapd_data * hapd,u8 * eid)406 static u8 * hostapd_eid_supported_op_classes(struct hostapd_data *hapd, u8 *eid)
407 {
408 	u8 op_class, channel;
409 
410 	if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA) ||
411 	    !hapd->iface->freq)
412 		return eid;
413 
414 	if (ieee80211_freq_to_channel_ext(hapd->iface->freq,
415 					  hapd->iconf->secondary_channel,
416 					  hostapd_get_oper_chwidth(hapd->iconf),
417 					  &op_class, &channel) ==
418 	    NUM_HOSTAPD_MODES)
419 		return eid;
420 
421 	*eid++ = WLAN_EID_SUPPORTED_OPERATING_CLASSES;
422 	*eid++ = 2;
423 
424 	/* Current Operating Class */
425 	*eid++ = op_class;
426 
427 	/* TODO: Advertise all the supported operating classes */
428 	*eid++ = 0;
429 
430 	return eid;
431 }
432 #endif /* EXT_CODE_CROP */
433 
434 
435 #ifndef LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT
hostapd_gen_probe_resp(struct hostapd_data * hapd,const struct ieee80211_mgmt * req,int is_p2p,size_t * resp_len)436 static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
437 				   const struct ieee80211_mgmt *req,
438 				   int is_p2p, size_t *resp_len)
439 {
440 	struct ieee80211_mgmt *resp;
441 	u8 *pos, *epos, *csa_pos;
442 	size_t buflen;
443 
444 #define MAX_PROBERESP_LEN 768
445 	buflen = MAX_PROBERESP_LEN;
446 #ifdef CONFIG_WPS_AP
447 	if (hapd->wps_probe_resp_ie)
448 		buflen += wpabuf_len(hapd->wps_probe_resp_ie);
449 #endif /* CONFIG_WPS_AP */
450 #ifdef CONFIG_P2P
451 	if (hapd->p2p_probe_resp_ie)
452 		buflen += wpabuf_len(hapd->p2p_probe_resp_ie);
453 #endif /* CONFIG_P2P */
454 #ifdef CONFIG_FST
455 	if (hapd->iface->fst_ies)
456 		buflen += wpabuf_len(hapd->iface->fst_ies);
457 #endif /* CONFIG_FST */
458 	if (hapd->conf->vendor_elements)
459 		buflen += wpabuf_len(hapd->conf->vendor_elements);
460 	if (hapd->conf->vendor_vht) {
461 		buflen += 5 + 2 + sizeof(struct ieee80211_vht_capabilities) +
462 			2 + sizeof(struct ieee80211_vht_operation);
463 	}
464 
465 #ifdef CONFIG_IEEE80211AX
466 	if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
467 		buflen += 3 + sizeof(struct ieee80211_he_capabilities) +
468 			3 + sizeof(struct ieee80211_he_operation) +
469 			3 + sizeof(struct ieee80211_he_mu_edca_parameter_set) +
470 			3 + sizeof(struct ieee80211_spatial_reuse);
471 		if (is_6ghz_op_class(hapd->iconf->op_class))
472 			buflen += sizeof(struct ieee80211_he_6ghz_oper_info) +
473 				3 + sizeof(struct ieee80211_he_6ghz_band_cap);
474 	}
475 #endif /* CONFIG_IEEE80211AX */
476 
477 	buflen += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_PROBE_RESP);
478 	buflen += hostapd_mbo_ie_len(hapd);
479 	buflen += hostapd_eid_owe_trans_len(hapd);
480 	buflen += hostapd_eid_dpp_cc_len(hapd);
481 
482 	resp = os_zalloc(buflen);
483 	if (resp == NULL)
484 		return NULL;
485 
486 	epos = ((u8 *) resp) + MAX_PROBERESP_LEN;
487 
488 	resp->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
489 					   WLAN_FC_STYPE_PROBE_RESP);
490 	if (req)
491 		os_memcpy(resp->da, req->sa, ETH_ALEN);
492 	os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN);
493 
494 	os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN);
495 	resp->u.probe_resp.beacon_int =
496 		host_to_le16(hapd->iconf->beacon_int);
497 
498 	/* hardware or low-level driver will setup seq_ctrl and timestamp */
499 	resp->u.probe_resp.capab_info =
500 		host_to_le16(hostapd_own_capab_info(hapd));
501 
502 	pos = resp->u.probe_resp.variable;
503 	*pos++ = WLAN_EID_SSID;
504 	*pos++ = hapd->conf->ssid.ssid_len;
505 	os_memcpy(pos, hapd->conf->ssid.ssid, hapd->conf->ssid.ssid_len);
506 	pos += hapd->conf->ssid.ssid_len;
507 
508 	/* Supported rates */
509 	pos = hostapd_eid_supp_rates(hapd, pos);
510 
511 	/* DS Params */
512 	pos = hostapd_eid_ds_params(hapd, pos);
513 
514 	pos = hostapd_eid_country(hapd, pos, epos - pos);
515 
516 	/* Power Constraint element */
517 	pos = hostapd_eid_pwr_constraint(hapd, pos);
518 
519 	/* CSA IE */
520 	csa_pos = hostapd_eid_csa(hapd, pos);
521 	if (csa_pos != pos)
522 		hapd->cs_c_off_proberesp = csa_pos - (u8 *) resp - 1;
523 	pos = csa_pos;
524 
525 	/* ERP Information element */
526 	pos = hostapd_eid_erp_info(hapd, pos);
527 
528 	/* Extended supported rates */
529 	pos = hostapd_eid_ext_supp_rates(hapd, pos);
530 
531 	pos = hostapd_get_rsne(hapd, pos, epos - pos);
532 	pos = hostapd_eid_bss_load(hapd, pos, epos - pos);
533 	pos = hostapd_eid_rm_enabled_capab(hapd, pos, epos - pos);
534 	pos = hostapd_get_mde(hapd, pos, epos - pos);
535 
536 	/* eCSA IE */
537 	csa_pos = hostapd_eid_ecsa(hapd, pos);
538 	if (csa_pos != pos)
539 		hapd->cs_c_off_ecsa_proberesp = csa_pos - (u8 *) resp - 1;
540 	pos = csa_pos;
541 
542 	pos = hostapd_eid_supported_op_classes(hapd, pos);
543 	pos = hostapd_eid_ht_capabilities(hapd, pos);
544 	pos = hostapd_eid_ht_operation(hapd, pos);
545 
546 	pos = hostapd_eid_ext_capab(hapd, pos);
547 
548 	pos = hostapd_eid_time_adv(hapd, pos);
549 	pos = hostapd_eid_time_zone(hapd, pos);
550 
551 	pos = hostapd_eid_interworking(hapd, pos);
552 	pos = hostapd_eid_adv_proto(hapd, pos);
553 	pos = hostapd_eid_roaming_consortium(hapd, pos);
554 
555 #ifdef CONFIG_FST
556 	if (hapd->iface->fst_ies) {
557 		os_memcpy(pos, wpabuf_head(hapd->iface->fst_ies),
558 			  wpabuf_len(hapd->iface->fst_ies));
559 		pos += wpabuf_len(hapd->iface->fst_ies);
560 	}
561 #endif /* CONFIG_FST */
562 
563 #ifdef CONFIG_IEEE80211AC
564 	if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac &&
565 	    !is_6ghz_op_class(hapd->iconf->op_class)) {
566 		pos = hostapd_eid_vht_capabilities(hapd, pos, 0);
567 		pos = hostapd_eid_vht_operation(hapd, pos);
568 		pos = hostapd_eid_txpower_envelope(hapd, pos);
569 	}
570 #endif /* CONFIG_IEEE80211AC */
571 
572 #ifdef CONFIG_IEEE80211AX
573 	if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax &&
574 	    is_6ghz_op_class(hapd->iconf->op_class))
575 		pos = hostapd_eid_txpower_envelope(hapd, pos);
576 #endif /* CONFIG_IEEE80211AX */
577 
578 	pos = hostapd_eid_wb_chsw_wrapper(hapd, pos);
579 
580 	pos = hostapd_eid_rnr(hapd, pos, WLAN_FC_STYPE_PROBE_RESP);
581 	pos = hostapd_eid_fils_indic(hapd, pos, 0);
582 	pos = hostapd_get_rsnxe(hapd, pos, epos - pos);
583 
584 #ifdef CONFIG_IEEE80211AX
585 	if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
586 		pos = hostapd_eid_he_capab(hapd, pos, IEEE80211_MODE_AP);
587 		pos = hostapd_eid_he_operation(hapd, pos);
588 		pos = hostapd_eid_spatial_reuse(hapd, pos);
589 		pos = hostapd_eid_he_mu_edca_parameter_set(hapd, pos);
590 		pos = hostapd_eid_he_6ghz_band_cap(hapd, pos);
591 	}
592 #endif /* CONFIG_IEEE80211AX */
593 
594 #ifdef CONFIG_IEEE80211AC
595 	if (hapd->conf->vendor_vht)
596 		pos = hostapd_eid_vendor_vht(hapd, pos);
597 #endif /* CONFIG_IEEE80211AC */
598 
599 	/* WPA / OSEN */
600 	pos = hostapd_get_wpa_ie(hapd, pos, epos - pos);
601 	pos = hostapd_get_osen_ie(hapd, pos, epos - pos);
602 
603 	/* Wi-Fi Alliance WMM */
604 	pos = hostapd_eid_wmm(hapd, pos);
605 
606 #ifdef CONFIG_WPS_AP
607 	if (hapd->conf->wps_state && hapd->wps_probe_resp_ie) {
608 		os_memcpy(pos, wpabuf_head(hapd->wps_probe_resp_ie),
609 			  wpabuf_len(hapd->wps_probe_resp_ie));
610 		pos += wpabuf_len(hapd->wps_probe_resp_ie);
611 	}
612 #endif /* CONFIG_WPS_AP */
613 
614 #ifdef CONFIG_P2P
615 	if ((hapd->conf->p2p & P2P_ENABLED) && is_p2p &&
616 	    hapd->p2p_probe_resp_ie) {
617 		os_memcpy(pos, wpabuf_head(hapd->p2p_probe_resp_ie),
618 			  wpabuf_len(hapd->p2p_probe_resp_ie));
619 		pos += wpabuf_len(hapd->p2p_probe_resp_ie);
620 	}
621 #endif /* CONFIG_P2P */
622 #ifdef CONFIG_P2P_MANAGER
623 	if ((hapd->conf->p2p & (P2P_MANAGE | P2P_ENABLED | P2P_GROUP_OWNER)) ==
624 	    P2P_MANAGE)
625 		pos = hostapd_eid_p2p_manage(hapd, pos);
626 #endif /* CONFIG_P2P_MANAGER */
627 
628 #ifdef CONFIG_HS20
629 	pos = hostapd_eid_hs20_indication(hapd, pos);
630 #endif /* CONFIG_HS20 */
631 
632 	pos = hostapd_eid_mbo(hapd, pos, (u8 *) resp + buflen - pos);
633 	pos = hostapd_eid_owe_trans(hapd, pos, (u8 *) resp + buflen - pos);
634 	pos = hostapd_eid_dpp_cc(hapd, pos, (u8 *) resp + buflen - pos);
635 
636 	if (hapd->conf->vendor_elements) {
637 		os_memcpy(pos, wpabuf_head(hapd->conf->vendor_elements),
638 			  wpabuf_len(hapd->conf->vendor_elements));
639 		pos += wpabuf_len(hapd->conf->vendor_elements);
640 	}
641 
642 	*resp_len = pos - (u8 *) resp;
643 	return (u8 *) resp;
644 }
645 
646 
647 enum ssid_match_result {
648 	NO_SSID_MATCH,
649 	EXACT_SSID_MATCH,
650 	WILDCARD_SSID_MATCH,
651 	CO_LOCATED_SSID_MATCH,
652 };
653 
ssid_match(struct hostapd_data * hapd,const u8 * ssid,size_t ssid_len,const u8 * ssid_list,size_t ssid_list_len,const u8 * short_ssid_list,size_t short_ssid_list_len)654 static enum ssid_match_result ssid_match(struct hostapd_data *hapd,
655 					 const u8 *ssid, size_t ssid_len,
656 					 const u8 *ssid_list,
657 					 size_t ssid_list_len,
658 					 const u8 *short_ssid_list,
659 					 size_t short_ssid_list_len)
660 {
661 	const u8 *pos, *end;
662 	struct hostapd_iface *iface = hapd->iface;
663 	int wildcard = 0;
664 	size_t i, j;
665 
666 	if (ssid_len == 0)
667 		wildcard = 1;
668 	if (ssid_len == hapd->conf->ssid.ssid_len &&
669 	    os_memcmp(ssid, hapd->conf->ssid.ssid, ssid_len) == 0)
670 		return EXACT_SSID_MATCH;
671 
672 	if (ssid_list) {
673 		pos = ssid_list;
674 		end = ssid_list + ssid_list_len;
675 		while (end - pos >= 2) {
676 			if (2 + pos[1] > end - pos)
677 				break;
678 			if (pos[1] == 0)
679 				wildcard = 1;
680 			if (pos[1] == hapd->conf->ssid.ssid_len &&
681 			    os_memcmp(pos + 2, hapd->conf->ssid.ssid,
682 				      pos[1]) == 0)
683 				return EXACT_SSID_MATCH;
684 			pos += 2 + pos[1];
685 		}
686 	}
687 
688 	if (short_ssid_list) {
689 		pos = short_ssid_list;
690 		end = short_ssid_list + short_ssid_list_len;
691 		while (end - pos >= 4) {
692 			if (hapd->conf->ssid.short_ssid == WPA_GET_LE32(pos))
693 				return EXACT_SSID_MATCH;
694 			pos += 4;
695 		}
696 	}
697 
698 	if (wildcard)
699 		return WILDCARD_SSID_MATCH;
700 
701 	if (!iface->interfaces || iface->interfaces->count <= 1 ||
702 	    is_6ghz_op_class(hapd->iconf->op_class))
703 		return NO_SSID_MATCH;
704 
705 	for (i = 0; i < iface->interfaces->count; i++) {
706 		struct hostapd_iface *colocated;
707 
708 		colocated = iface->interfaces->iface[i];
709 
710 		if (colocated == iface ||
711 		    !is_6ghz_op_class(colocated->conf->op_class))
712 			continue;
713 
714 		for (j = 0; j < colocated->num_bss; j++) {
715 			struct hostapd_bss_config *conf;
716 
717 			conf = colocated->bss[j]->conf;
718 			if (ssid_len == conf->ssid.ssid_len &&
719 			    os_memcmp(ssid, conf->ssid.ssid, ssid_len) == 0)
720 				return CO_LOCATED_SSID_MATCH;
721 		}
722 	}
723 
724 	return NO_SSID_MATCH;
725 }
726 #endif /* LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT */
727 #ifndef EXT_CODE_CROP
sta_track_expire(struct hostapd_iface * iface,int force)728 void sta_track_expire(struct hostapd_iface *iface, int force)
729 {
730 	struct os_reltime now;
731 	struct hostapd_sta_info *info;
732 
733 	if (!iface->num_sta_seen)
734 		return;
735 
736 	os_get_reltime(&now);
737 	while ((info = dl_list_first(&iface->sta_seen, struct hostapd_sta_info,
738 				     list))) {
739 		if (!force &&
740 		    !os_reltime_expired(&now, &info->last_seen,
741 					iface->conf->track_sta_max_age))
742 			break;
743 		force = 0;
744 
745 		wpa_printf(MSG_MSGDUMP, "%s: Expire STA tracking entry for "
746 			   MACSTR, iface->bss[0]->conf->iface,
747 			   MAC2STR(info->addr));
748 		dl_list_del(&info->list);
749 		iface->num_sta_seen--;
750 		sta_track_del(info);
751 	}
752 }
753 
754 
sta_track_get(struct hostapd_iface * iface,const u8 * addr)755 static struct hostapd_sta_info * sta_track_get(struct hostapd_iface *iface,
756 					       const u8 *addr)
757 {
758 	struct hostapd_sta_info *info;
759 
760 	dl_list_for_each(info, &iface->sta_seen, struct hostapd_sta_info, list)
761 		if (os_memcmp(addr, info->addr, ETH_ALEN) == 0)
762 			return info;
763 
764 	return NULL;
765 }
766 
767 
sta_track_add(struct hostapd_iface * iface,const u8 * addr,int ssi_signal)768 void sta_track_add(struct hostapd_iface *iface, const u8 *addr, int ssi_signal)
769 {
770 	struct hostapd_sta_info *info;
771 
772 	info = sta_track_get(iface, addr);
773 	if (info) {
774 		/* Move the most recent entry to the end of the list */
775 		dl_list_del(&info->list);
776 		dl_list_add_tail(&iface->sta_seen, &info->list);
777 		os_get_reltime(&info->last_seen);
778 		info->ssi_signal = ssi_signal;
779 		return;
780 	}
781 
782 	/* Add a new entry */
783 	info = os_zalloc(sizeof(*info));
784 	if (info == NULL)
785 		return;
786 	os_memcpy(info->addr, addr, ETH_ALEN);
787 	os_get_reltime(&info->last_seen);
788 	info->ssi_signal = ssi_signal;
789 
790 	if (iface->num_sta_seen >= iface->conf->track_sta_max_num) {
791 		/* Expire oldest entry to make room for a new one */
792 		sta_track_expire(iface, 1);
793 	}
794 
795 	wpa_printf(MSG_MSGDUMP, "%s: Add STA tracking entry for "
796 		   MACSTR, iface->bss[0]->conf->iface, MAC2STR(addr));
797 	dl_list_add_tail(&iface->sta_seen, &info->list);
798 	iface->num_sta_seen++;
799 }
800 
801 
802 struct hostapd_data *
sta_track_seen_on(struct hostapd_iface * iface,const u8 * addr,const char * ifname)803 sta_track_seen_on(struct hostapd_iface *iface, const u8 *addr,
804 		  const char *ifname)
805 {
806 	struct hapd_interfaces *interfaces = iface->interfaces;
807 	size_t i, j;
808 
809 	for (i = 0; i < interfaces->count; i++) {
810 		struct hostapd_data *hapd = NULL;
811 
812 		iface = interfaces->iface[i];
813 		for (j = 0; j < iface->num_bss; j++) {
814 			hapd = iface->bss[j];
815 			if (os_strcmp(ifname, hapd->conf->iface) == 0)
816 				break;
817 			hapd = NULL;
818 		}
819 
820 		if (hapd && sta_track_get(iface, addr))
821 			return hapd;
822 	}
823 
824 	return NULL;
825 }
826 #endif /* EXT_CODE_CROP */
827 
828 #ifdef CONFIG_TAXONOMY
sta_track_claim_taxonomy_info(struct hostapd_iface * iface,const u8 * addr,struct wpabuf ** probe_ie_taxonomy)829 void sta_track_claim_taxonomy_info(struct hostapd_iface *iface, const u8 *addr,
830 				   struct wpabuf **probe_ie_taxonomy)
831 {
832 	struct hostapd_sta_info *info;
833 
834 	info = sta_track_get(iface, addr);
835 	if (!info)
836 		return;
837 
838 	wpabuf_free(*probe_ie_taxonomy);
839 	*probe_ie_taxonomy = info->probe_ie_taxonomy;
840 	info->probe_ie_taxonomy = NULL;
841 }
842 #endif /* CONFIG_TAXONOMY */
843 
844 
845 #ifndef LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT
handle_probe_req(struct hostapd_data * hapd,const struct ieee80211_mgmt * mgmt,size_t len,int ssi_signal)846 void handle_probe_req(struct hostapd_data *hapd,
847 		      const struct ieee80211_mgmt *mgmt, size_t len,
848 		      int ssi_signal)
849 {
850 	u8 *resp;
851 	struct ieee802_11_elems elems;
852 	const u8 *ie;
853 	size_t ie_len;
854 	size_t i, resp_len;
855 	int noack;
856 	enum ssid_match_result res;
857 	int ret;
858 	u16 csa_offs[2];
859 	size_t csa_offs_len;
860 	struct radius_sta rad_info;
861 
862 	if (hapd->iconf->rssi_ignore_probe_request && ssi_signal &&
863 	    ssi_signal < hapd->iconf->rssi_ignore_probe_request)
864 		return;
865 
866 	if (len < IEEE80211_HDRLEN)
867 		return;
868 	ie = ((const u8 *) mgmt) + IEEE80211_HDRLEN;
869 	if (hapd->iconf->track_sta_max_num)
870 		sta_track_add(hapd->iface, mgmt->sa, ssi_signal);
871 	ie_len = len - IEEE80211_HDRLEN;
872 
873 	ret = hostapd_allowed_address(hapd, mgmt->sa, (const u8 *) mgmt, len,
874 				      &rad_info, 1);
875 	if (ret == HOSTAPD_ACL_REJECT) {
876 		wpa_msg(hapd->msg_ctx, MSG_DEBUG,
877 			"Ignore Probe Request frame from " MACSTR
878 			" due to ACL reject ", MAC2STR(mgmt->sa));
879 		return;
880 	}
881 
882 	for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++)
883 		if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx,
884 					    mgmt->sa, mgmt->da, mgmt->bssid,
885 					    ie, ie_len, ssi_signal) > 0)
886 			return;
887 
888 	if (!hapd->conf->send_probe_response)
889 		return;
890 
891 	if (ieee802_11_parse_elems(ie, ie_len, &elems, 0) == ParseFailed) {
892 		wpa_printf(MSG_DEBUG, "Could not parse ProbeReq from " MACSTR,
893 			   MAC2STR(mgmt->sa));
894 		return;
895 	}
896 
897 	if ((!elems.ssid || !elems.supp_rates)) {
898 		wpa_printf(MSG_DEBUG, "STA " MACSTR " sent probe request "
899 			   "without SSID or supported rates element",
900 			   MAC2STR(mgmt->sa));
901 		return;
902 	}
903 
904 	/*
905 	 * No need to reply if the Probe Request frame was sent on an adjacent
906 	 * channel. IEEE Std 802.11-2012 describes this as a requirement for an
907 	 * AP with dot11RadioMeasurementActivated set to true, but strictly
908 	 * speaking does not allow such ignoring of Probe Request frames if
909 	 * dot11RadioMeasurementActivated is false. Anyway, this can help reduce
910 	 * number of unnecessary Probe Response frames for cases where the STA
911 	 * is less likely to see them (Probe Request frame sent on a
912 	 * neighboring, but partially overlapping, channel).
913 	 */
914 	if (elems.ds_params &&
915 	    hapd->iface->current_mode &&
916 	    (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G ||
917 	     hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211B) &&
918 	    hapd->iconf->channel != elems.ds_params[0]) {
919 		wpa_printf(MSG_DEBUG,
920 			   "Ignore Probe Request due to DS Params mismatch: chan=%u != ds.chan=%u",
921 			   hapd->iconf->channel, elems.ds_params[0]);
922 		return;
923 	}
924 
925 #ifdef CONFIG_P2P
926 	if (hapd->p2p && hapd->p2p_group && elems.wps_ie) {
927 		struct wpabuf *wps;
928 		wps = ieee802_11_vendor_ie_concat(ie, ie_len, WPS_DEV_OUI_WFA);
929 		if (wps && !p2p_group_match_dev_type(hapd->p2p_group, wps)) {
930 			wpa_printf(MSG_MSGDUMP, "P2P: Ignore Probe Request "
931 				   "due to mismatch with Requested Device "
932 				   "Type");
933 			wpabuf_free(wps);
934 			return;
935 		}
936 		wpabuf_free(wps);
937 	}
938 
939 	if (hapd->p2p && hapd->p2p_group && elems.p2p) {
940 		struct wpabuf *p2p;
941 		p2p = ieee802_11_vendor_ie_concat(ie, ie_len, P2P_IE_VENDOR_TYPE);
942 		if (p2p && !p2p_group_match_dev_id(hapd->p2p_group, p2p)) {
943 			wpa_printf(MSG_MSGDUMP, "P2P: Ignore Probe Request "
944 				   "due to mismatch with Device ID");
945 			wpabuf_free(p2p);
946 			return;
947 		}
948 		wpabuf_free(p2p);
949 	}
950 #endif /* CONFIG_P2P */
951 
952 	if (hapd->conf->ignore_broadcast_ssid && elems.ssid_len == 0 &&
953 	    elems.ssid_list_len == 0 && elems.short_ssid_list_len == 0) {
954 		wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR " for "
955 			   "broadcast SSID ignored", MAC2STR(mgmt->sa));
956 		return;
957 	}
958 
959 #ifdef CONFIG_P2P
960 	if ((hapd->conf->p2p & P2P_GROUP_OWNER) &&
961 	    elems.ssid_len == P2P_WILDCARD_SSID_LEN &&
962 	    os_memcmp(elems.ssid, P2P_WILDCARD_SSID,
963 		      P2P_WILDCARD_SSID_LEN) == 0) {
964 		/* Process P2P Wildcard SSID like Wildcard SSID */
965 		elems.ssid_len = 0;
966 	}
967 #endif /* CONFIG_P2P */
968 
969 #ifdef CONFIG_TAXONOMY
970 	{
971 		struct sta_info *sta;
972 		struct hostapd_sta_info *info;
973 
974 		if ((sta = ap_get_sta(hapd, mgmt->sa)) != NULL) {
975 			taxonomy_sta_info_probe_req(hapd, sta, ie, ie_len);
976 		} else if ((info = sta_track_get(hapd->iface,
977 						 mgmt->sa)) != NULL) {
978 			taxonomy_hostapd_sta_info_probe_req(hapd, info,
979 							    ie, ie_len);
980 		}
981 	}
982 #endif /* CONFIG_TAXONOMY */
983 
984 	res = ssid_match(hapd, elems.ssid, elems.ssid_len,
985 			 elems.ssid_list, elems.ssid_list_len,
986 			 elems.short_ssid_list, elems.short_ssid_list_len);
987 	if (res == NO_SSID_MATCH) {
988 		if (!(mgmt->da[0] & 0x01)) {
989 			wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
990 				   " for foreign SSID '%s' (DA " MACSTR ")%s",
991 				   MAC2STR(mgmt->sa),
992 				   wpa_ssid_txt(elems.ssid, elems.ssid_len),
993 				   MAC2STR(mgmt->da),
994 				   elems.ssid_list ? " (SSID list)" : "");
995 		}
996 		return;
997 	}
998 
999 	if (hapd->conf->ignore_broadcast_ssid && res == WILDCARD_SSID_MATCH) {
1000 		wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR " for "
1001 			   "broadcast SSID ignored", MAC2STR(mgmt->sa));
1002 		return;
1003 	}
1004 
1005 #ifdef CONFIG_INTERWORKING
1006 	if (hapd->conf->interworking &&
1007 	    elems.interworking && elems.interworking_len >= 1) {
1008 		u8 ant = elems.interworking[0] & 0x0f;
1009 		if (ant != INTERWORKING_ANT_WILDCARD &&
1010 		    ant != hapd->conf->access_network_type) {
1011 			wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
1012 				   " for mismatching ANT %u ignored",
1013 				   MAC2STR(mgmt->sa), ant);
1014 			return;
1015 		}
1016 	}
1017 
1018 	if (hapd->conf->interworking && elems.interworking &&
1019 	    (elems.interworking_len == 7 || elems.interworking_len == 9)) {
1020 		const u8 *hessid;
1021 		if (elems.interworking_len == 7)
1022 			hessid = elems.interworking + 1;
1023 		else
1024 			hessid = elems.interworking + 1 + 2;
1025 		if (!is_broadcast_ether_addr(hessid) &&
1026 		    os_memcmp(hessid, hapd->conf->hessid, ETH_ALEN) != 0) {
1027 			wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
1028 				   " for mismatching HESSID " MACSTR
1029 				   " ignored",
1030 				   MAC2STR(mgmt->sa), MAC2STR(hessid));
1031 			return;
1032 		}
1033 	}
1034 #endif /* CONFIG_INTERWORKING */
1035 
1036 #ifdef CONFIG_P2P
1037 	if ((hapd->conf->p2p & P2P_GROUP_OWNER) &&
1038 	    supp_rates_11b_only(&elems)) {
1039 		/* Indicates support for 11b rates only */
1040 		wpa_printf(MSG_EXCESSIVE, "P2P: Ignore Probe Request from "
1041 			   MACSTR " with only 802.11b rates",
1042 			   MAC2STR(mgmt->sa));
1043 		return;
1044 	}
1045 #endif /* CONFIG_P2P */
1046 
1047 	/* TODO: verify that supp_rates contains at least one matching rate
1048 	 * with AP configuration */
1049 
1050 	if (hapd->conf->no_probe_resp_if_seen_on &&
1051 	    is_multicast_ether_addr(mgmt->da) &&
1052 	    is_multicast_ether_addr(mgmt->bssid) &&
1053 	    sta_track_seen_on(hapd->iface, mgmt->sa,
1054 			      hapd->conf->no_probe_resp_if_seen_on)) {
1055 		wpa_printf(MSG_MSGDUMP, "%s: Ignore Probe Request from " MACSTR
1056 			   " since STA has been seen on %s",
1057 			   hapd->conf->iface, MAC2STR(mgmt->sa),
1058 			   hapd->conf->no_probe_resp_if_seen_on);
1059 		return;
1060 	}
1061 
1062 	if (hapd->conf->no_probe_resp_if_max_sta &&
1063 	    is_multicast_ether_addr(mgmt->da) &&
1064 	    is_multicast_ether_addr(mgmt->bssid) &&
1065 	    hapd->num_sta >= hapd->conf->max_num_sta &&
1066 	    !ap_get_sta(hapd, mgmt->sa)) {
1067 		wpa_printf(MSG_MSGDUMP, "%s: Ignore Probe Request from " MACSTR
1068 			   " since no room for additional STA",
1069 			   hapd->conf->iface, MAC2STR(mgmt->sa));
1070 		return;
1071 	}
1072 
1073 #ifdef CONFIG_TESTING_OPTIONS
1074 	if (hapd->iconf->ignore_probe_probability > 0.0 &&
1075 	    drand48() < hapd->iconf->ignore_probe_probability) {
1076 		wpa_printf(MSG_INFO,
1077 			   "TESTING: ignoring probe request from " MACSTR,
1078 			   MAC2STR(mgmt->sa));
1079 		return;
1080 	}
1081 #endif /* CONFIG_TESTING_OPTIONS */
1082 
1083 	wpa_msg_ctrl(hapd->msg_ctx, MSG_INFO, RX_PROBE_REQUEST "sa=" MACSTR
1084 		     " signal=%d", MAC2STR(mgmt->sa), ssi_signal);
1085 
1086 	resp = hostapd_gen_probe_resp(hapd, mgmt, elems.p2p != NULL,
1087 				      &resp_len);
1088 	if (resp == NULL)
1089 		return;
1090 
1091 	/*
1092 	 * If this is a broadcast probe request, apply no ack policy to avoid
1093 	 * excessive retries.
1094 	 */
1095 	noack = !!(res == WILDCARD_SSID_MATCH &&
1096 		   is_broadcast_ether_addr(mgmt->da));
1097 
1098 	csa_offs_len = 0;
1099 	if (hapd->csa_in_progress) {
1100 		if (hapd->cs_c_off_proberesp)
1101 			csa_offs[csa_offs_len++] =
1102 				hapd->cs_c_off_proberesp;
1103 
1104 		if (hapd->cs_c_off_ecsa_proberesp)
1105 			csa_offs[csa_offs_len++] =
1106 				hapd->cs_c_off_ecsa_proberesp;
1107 	}
1108 
1109 	ret = hostapd_drv_send_mlme(hapd, resp, resp_len, noack,
1110 				    csa_offs_len ? csa_offs : NULL,
1111 				    csa_offs_len, 0);
1112 
1113 	if (ret < 0)
1114 		wpa_printf(MSG_INFO, "handle_probe_req: send failed");
1115 
1116 	os_free(resp);
1117 
1118 	wpa_printf(MSG_EXCESSIVE, "STA " MACSTR " sent probe request for %s "
1119 		   "SSID", MAC2STR(mgmt->sa),
1120 		   elems.ssid_len == 0 ? "broadcast" : "our");
1121 }
1122 
1123 
hostapd_probe_resp_offloads(struct hostapd_data * hapd,size_t * resp_len)1124 static u8 * hostapd_probe_resp_offloads(struct hostapd_data *hapd,
1125 					size_t *resp_len)
1126 {
1127 	/* check probe response offloading caps and print warnings */
1128 	if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_PROBE_RESP_OFFLOAD))
1129 		return NULL;
1130 
1131 #ifdef CONFIG_WPS
1132 	if (hapd->conf->wps_state && hapd->wps_probe_resp_ie &&
1133 	    (!(hapd->iface->probe_resp_offloads &
1134 	       (WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS |
1135 		WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS2))))
1136 		wpa_printf(MSG_WARNING, "Device is trying to offload WPS "
1137 			   "Probe Response while not supporting this");
1138 #endif /* CONFIG_WPS */
1139 
1140 #ifdef CONFIG_P2P
1141 	if ((hapd->conf->p2p & P2P_ENABLED) && hapd->p2p_probe_resp_ie &&
1142 	    !(hapd->iface->probe_resp_offloads &
1143 	      WPA_DRIVER_PROBE_RESP_OFFLOAD_P2P))
1144 		wpa_printf(MSG_WARNING, "Device is trying to offload P2P "
1145 			   "Probe Response while not supporting this");
1146 #endif  /* CONFIG_P2P */
1147 
1148 	if (hapd->conf->interworking &&
1149 	    !(hapd->iface->probe_resp_offloads &
1150 	      WPA_DRIVER_PROBE_RESP_OFFLOAD_INTERWORKING))
1151 		wpa_printf(MSG_WARNING, "Device is trying to offload "
1152 			   "Interworking Probe Response while not supporting "
1153 			   "this");
1154 
1155 	/* Generate a Probe Response template for the non-P2P case */
1156 	return hostapd_gen_probe_resp(hapd, NULL, 0, resp_len);
1157 }
1158 #endif /* LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT */
1159 
1160 #endif /* NEED_AP_MLME */
1161 
1162 #ifndef EXT_CODE_CROP
1163 #ifdef CONFIG_IEEE80211AX
1164 /* Unsolicited broadcast Probe Response transmission, 6 GHz only */
hostapd_unsol_bcast_probe_resp(struct hostapd_data * hapd,struct wpa_driver_ap_params * params)1165 static u8 * hostapd_unsol_bcast_probe_resp(struct hostapd_data *hapd,
1166 					   struct wpa_driver_ap_params *params)
1167 {
1168 	if (!is_6ghz_op_class(hapd->iconf->op_class))
1169 		return NULL;
1170 
1171 	params->unsol_bcast_probe_resp_interval =
1172 		hapd->conf->unsol_bcast_probe_resp_interval;
1173 
1174 	return hostapd_gen_probe_resp(hapd, NULL, 0,
1175 				      &params->unsol_bcast_probe_resp_tmpl_len);
1176 }
1177 #endif /* CONFIG_IEEE80211AX */
1178 #endif /* EXT_CODE_CROP */
1179 
sta_track_del(struct hostapd_sta_info * info)1180 void sta_track_del(struct hostapd_sta_info *info)
1181 {
1182 #ifdef CONFIG_TAXONOMY
1183 	wpabuf_free(info->probe_ie_taxonomy);
1184 	info->probe_ie_taxonomy = NULL;
1185 #endif /* CONFIG_TAXONOMY */
1186 	os_free(info);
1187 }
1188 
1189 
1190 #ifdef CONFIG_FILS
1191 
hostapd_fils_discovery_cap(struct hostapd_data * hapd)1192 static u16 hostapd_fils_discovery_cap(struct hostapd_data *hapd)
1193 {
1194 	u16 cap_info, phy_index = 0;
1195 	u8 chwidth = FD_CAP_BSS_CHWIDTH_20, mcs_nss_size = 4;
1196 	struct hostapd_hw_modes *mode = hapd->iface->current_mode;
1197 
1198 	cap_info = FD_CAP_ESS;
1199 	if (hapd->conf->wpa)
1200 		cap_info |= FD_CAP_PRIVACY;
1201 
1202 	if (is_6ghz_op_class(hapd->iconf->op_class)) {
1203 		phy_index = FD_CAP_PHY_INDEX_HE;
1204 
1205 		switch (hapd->iconf->op_class) {
1206 		case 135:
1207 			mcs_nss_size += 4;
1208 			/* fallthrough */
1209 		case 134:
1210 			mcs_nss_size += 4;
1211 			chwidth = FD_CAP_BSS_CHWIDTH_160_80_80;
1212 			break;
1213 		case 133:
1214 			chwidth = FD_CAP_BSS_CHWIDTH_80;
1215 			break;
1216 		case 132:
1217 			chwidth = FD_CAP_BSS_CHWIDTH_40;
1218 			break;
1219 		}
1220 	} else {
1221 		switch (hostapd_get_oper_chwidth(hapd->iconf)) {
1222 		case CHANWIDTH_80P80MHZ:
1223 			mcs_nss_size += 4;
1224 			/* fallthrough */
1225 		case CHANWIDTH_160MHZ:
1226 			mcs_nss_size += 4;
1227 			chwidth = FD_CAP_BSS_CHWIDTH_160_80_80;
1228 			break;
1229 		case CHANWIDTH_80MHZ:
1230 			chwidth = FD_CAP_BSS_CHWIDTH_80;
1231 			break;
1232 		case CHANWIDTH_USE_HT:
1233 			if (hapd->iconf->secondary_channel)
1234 				chwidth = FD_CAP_BSS_CHWIDTH_40;
1235 			else
1236 				chwidth = FD_CAP_BSS_CHWIDTH_20;
1237 			break;
1238 		}
1239 
1240 #ifdef CONFIG_IEEE80211AX
1241 		if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax)
1242 			phy_index = FD_CAP_PHY_INDEX_HE;
1243 #endif /* CONFIG_IEEE80211AX */
1244 #ifdef CONFIG_IEEE80211AC
1245 		if (!phy_index &&
1246 		    hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac)
1247 			phy_index = FD_CAP_PHY_INDEX_VHT;
1248 #endif /* CONFIG_IEEE80211AC */
1249 		if (!phy_index &&
1250 		    hapd->iconf->ieee80211n && !hapd->conf->disable_11n)
1251 			phy_index = FD_CAP_PHY_INDEX_HT;
1252 	}
1253 
1254 	cap_info |= phy_index << FD_CAP_PHY_INDEX_SHIFT;
1255 	cap_info |= chwidth << FD_CAP_BSS_CHWIDTH_SHIFT;
1256 
1257 	if (mode) {
1258 		u16 *mcs = (u16 *) mode->he_capab[IEEE80211_MODE_AP].mcs;
1259 		int i;
1260 		u16 nss = 0;
1261 
1262 		for (i = 0; i < HE_NSS_MAX_STREAMS; i++) {
1263 			u16 nss_mask = 0x3 << (i * 2);
1264 
1265 			if (mcs_nss_size == 4 &&
1266 			    (((mcs[0] & nss_mask) == nss_mask) ||
1267 			     ((mcs[1] & nss_mask) == nss_mask)))
1268 				continue;
1269 
1270 			if (mcs_nss_size == 8 &&
1271 			    (((mcs[2] & nss_mask) == nss_mask) ||
1272 			     ((mcs[3] & nss_mask) == nss_mask)))
1273 				continue;
1274 
1275 			if (mcs_nss_size == 12 &&
1276 			    (((mcs[4] & nss_mask) == nss_mask) ||
1277 			     ((mcs[5] & nss_mask) == nss_mask)))
1278 				continue;
1279 
1280 			nss++;
1281 		}
1282 
1283 		if (nss > 4)
1284 			cap_info |= FD_CAP_NSS_5_8 << FD_CAP_NSS_SHIFT;
1285 		else if (nss)
1286 			cap_info |= (nss - 1) << FD_CAP_NSS_SHIFT;
1287 	}
1288 
1289 	return cap_info;
1290 }
1291 
1292 
hostapd_gen_fils_discovery(struct hostapd_data * hapd,size_t * len)1293 static u8 * hostapd_gen_fils_discovery(struct hostapd_data *hapd, size_t *len)
1294 {
1295 	struct ieee80211_mgmt *head;
1296 	const u8 *mobility_domain;
1297 	u8 *pos, *length_pos, buf[200];
1298 	u16 ctl = 0;
1299 	u8 fd_rsn_info[5];
1300 	size_t total_len, buf_len;
1301 
1302 	total_len = 24 + 2 + 12;
1303 
1304 	/* FILS Discovery Frame Control */
1305 	ctl = (sizeof(hapd->conf->ssid.short_ssid) - 1) |
1306 		FD_FRAME_CTL_SHORT_SSID_PRESENT |
1307 		FD_FRAME_CTL_LENGTH_PRESENT |
1308 		FD_FRAME_CTL_CAP_PRESENT;
1309 	total_len += 4 + 1 + 2;
1310 
1311 	/* Check for optional subfields and calculate length */
1312 	if (wpa_auth_write_fd_rsn_info(hapd->wpa_auth, fd_rsn_info)) {
1313 		ctl |= FD_FRAME_CTL_RSN_INFO_PRESENT;
1314 		total_len += sizeof(fd_rsn_info);
1315 	}
1316 
1317 	mobility_domain = hostapd_wpa_ie(hapd, WLAN_EID_MOBILITY_DOMAIN);
1318 	if (mobility_domain) {
1319 		ctl |= FD_FRAME_CTL_MD_PRESENT;
1320 		total_len += 3;
1321 	}
1322 
1323 	total_len += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_ACTION);
1324 
1325 	pos = hostapd_eid_fils_indic(hapd, buf, 0);
1326 	buf_len = pos - buf;
1327 	total_len += buf_len;
1328 
1329 	head = os_zalloc(total_len);
1330 	if (!head)
1331 		return NULL;
1332 
1333 	head->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
1334 					   WLAN_FC_STYPE_ACTION);
1335 	os_memset(head->da, 0xff, ETH_ALEN);
1336 	os_memcpy(head->sa, hapd->own_addr, ETH_ALEN);
1337 	os_memcpy(head->bssid, hapd->own_addr, ETH_ALEN);
1338 
1339 	head->u.action.category = WLAN_ACTION_PUBLIC;
1340 	head->u.action.u.public_action.action = WLAN_PA_FILS_DISCOVERY;
1341 
1342 	pos = &head->u.action.u.public_action.variable[0];
1343 
1344 	/* FILS Discovery Information field */
1345 
1346 	/* FILS Discovery Frame Control */
1347 	WPA_PUT_LE16(pos, ctl);
1348 	pos += 2;
1349 
1350 	/* Hardware or low-level driver will fill in the Timestamp value */
1351 	pos += 8;
1352 
1353 	/* Beacon Interval */
1354 	WPA_PUT_LE16(pos, hapd->iconf->beacon_int);
1355 	pos += 2;
1356 
1357 	/* Short SSID */
1358 	WPA_PUT_LE32(pos, hapd->conf->ssid.short_ssid);
1359 	pos += sizeof(hapd->conf->ssid.short_ssid);
1360 
1361 	/* Store position of FILS discovery information element Length field */
1362 	length_pos = pos++;
1363 
1364 	/* FD Capability */
1365 	WPA_PUT_LE16(pos, hostapd_fils_discovery_cap(hapd));
1366 	pos += 2;
1367 
1368 	/* Operating Class - not present */
1369 
1370 	/* Primary Channel - not present */
1371 
1372 	/* AP Configuration Sequence Number - not present */
1373 
1374 	/* Access Network Options - not present */
1375 
1376 	/* FD RSN Information */
1377 	if (ctl & FD_FRAME_CTL_RSN_INFO_PRESENT) {
1378 		os_memcpy(pos, fd_rsn_info, sizeof(fd_rsn_info));
1379 		pos += sizeof(fd_rsn_info);
1380 	}
1381 
1382 	/* Channel Center Frequency Segment 1 - not present */
1383 
1384 	/* Mobility Domain */
1385 	if (ctl & FD_FRAME_CTL_MD_PRESENT) {
1386 		os_memcpy(pos, &mobility_domain[2], 3);
1387 		pos += 3;
1388 	}
1389 
1390 	/* Fill in the Length field value */
1391 	*length_pos = pos - (length_pos + 1);
1392 
1393 	pos = hostapd_eid_rnr(hapd, pos, WLAN_FC_STYPE_ACTION);
1394 
1395 	/* FILS Indication element */
1396 	if (buf_len) {
1397 		os_memcpy(pos, buf, buf_len);
1398 		pos += buf_len;
1399 	}
1400 
1401 	*len = pos - (u8 *) head;
1402 	wpa_hexdump(MSG_DEBUG, "FILS Discovery frame template",
1403 		    head, pos - (u8 *) head);
1404 	return (u8 *) head;
1405 }
1406 
1407 
1408 /* Configure FILS Discovery frame transmission parameters */
hostapd_fils_discovery(struct hostapd_data * hapd,struct wpa_driver_ap_params * params)1409 static u8 * hostapd_fils_discovery(struct hostapd_data *hapd,
1410 				   struct wpa_driver_ap_params *params)
1411 {
1412 	params->fd_max_int = hapd->conf->fils_discovery_max_int;
1413 	if (is_6ghz_op_class(hapd->iconf->op_class) &&
1414 	    params->fd_max_int > FD_MAX_INTERVAL_6GHZ)
1415 		params->fd_max_int = FD_MAX_INTERVAL_6GHZ;
1416 
1417 	params->fd_min_int = hapd->conf->fils_discovery_min_int;
1418 	if (params->fd_min_int > params->fd_max_int)
1419 		params->fd_min_int = params->fd_max_int;
1420 
1421 	if (params->fd_max_int)
1422 		return hostapd_gen_fils_discovery(hapd,
1423 						  &params->fd_frame_tmpl_len);
1424 
1425 	return NULL;
1426 }
1427 
1428 #endif /* CONFIG_FILS */
1429 
1430 
ieee802_11_build_ap_params(struct hostapd_data * hapd,struct wpa_driver_ap_params * params)1431 int ieee802_11_build_ap_params(struct hostapd_data *hapd,
1432 			       struct wpa_driver_ap_params *params)
1433 {
1434 	struct ieee80211_mgmt *head = NULL;
1435 	u8 *tail = NULL;
1436 	size_t head_len = 0, tail_len = 0;
1437 	u8 *resp = NULL;
1438 	size_t resp_len = 0;
1439 #ifdef NEED_AP_MLME
1440 	u16 capab_info;
1441 	u8 *pos, *tailpos, *tailend, *csa_pos;
1442 
1443 #define BEACON_HEAD_BUF_SIZE 256
1444 #define BEACON_TAIL_BUF_SIZE 512
1445 	head = os_zalloc(BEACON_HEAD_BUF_SIZE);
1446 	tail_len = BEACON_TAIL_BUF_SIZE;
1447 #ifdef CONFIG_WPS_AP
1448 	if (hapd->conf->wps_state && hapd->wps_beacon_ie)
1449 		tail_len += wpabuf_len(hapd->wps_beacon_ie);
1450 #endif /* CONFIG_WPS_AP */
1451 #ifdef CONFIG_P2P
1452 	if (hapd->p2p_beacon_ie)
1453 		tail_len += wpabuf_len(hapd->p2p_beacon_ie);
1454 #endif /* CONFIG_P2P */
1455 #ifdef CONFIG_FST
1456 	if (hapd->iface->fst_ies)
1457 		tail_len += wpabuf_len(hapd->iface->fst_ies);
1458 #endif /* CONFIG_FST */
1459 #ifndef EXT_CODE_CROP
1460 	if (hapd->conf->vendor_elements)
1461 		tail_len += wpabuf_len(hapd->conf->vendor_elements);
1462 #endif /* EXT_CODE_CROP */
1463 
1464 #ifdef CONFIG_IEEE80211AC
1465 	if (hapd->conf->vendor_vht) {
1466 		tail_len += 5 + 2 + sizeof(struct ieee80211_vht_capabilities) +
1467 			2 + sizeof(struct ieee80211_vht_operation);
1468 	}
1469 #endif /* CONFIG_IEEE80211AC */
1470 
1471 #ifdef CONFIG_IEEE80211AX
1472 	if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
1473 		tail_len += 3 + sizeof(struct ieee80211_he_capabilities) +
1474 			3 + sizeof(struct ieee80211_he_operation) +
1475 			3 + sizeof(struct ieee80211_he_mu_edca_parameter_set) +
1476 			3 + sizeof(struct ieee80211_spatial_reuse);
1477 		if (is_6ghz_op_class(hapd->iconf->op_class))
1478 			tail_len += sizeof(struct ieee80211_he_6ghz_oper_info) +
1479 				3 + sizeof(struct ieee80211_he_6ghz_band_cap);
1480 	}
1481 #endif /* CONFIG_IEEE80211AX */
1482 
1483 	tail_len += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_BEACON);
1484 	tail_len += hostapd_mbo_ie_len(hapd);
1485 #ifndef EXT_CODE_CROP
1486 	tail_len += hostapd_eid_owe_trans_len(hapd);
1487 #endif /* EXT_CODE_CROP */
1488 	tail_len += hostapd_eid_dpp_cc_len(hapd);
1489 
1490 	tailpos = tail = os_malloc(tail_len);
1491 	if (head == NULL || tail == NULL) {
1492 		wpa_error_log0(MSG_ERROR, "Failed to set beacon data");
1493 		os_free(head);
1494 		os_free(tail);
1495 		return -1;
1496 	}
1497 	tailend = tail + tail_len;
1498 
1499 	head->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
1500 					   WLAN_FC_STYPE_BEACON);
1501 	head->duration = host_to_le16(0);
1502 	os_memset(head->da, 0xff, ETH_ALEN);
1503 
1504 	os_memcpy(head->sa, hapd->own_addr, ETH_ALEN);
1505 	os_memcpy(head->bssid, hapd->own_addr, ETH_ALEN);
1506 	head->u.beacon.beacon_int =
1507 		host_to_le16(hapd->iconf->beacon_int);
1508 
1509 	/* hardware or low-level driver will setup seq_ctrl and timestamp */
1510 	capab_info = hostapd_own_capab_info(hapd);
1511 	head->u.beacon.capab_info = host_to_le16(capab_info);
1512 	pos = &head->u.beacon.variable[0];
1513 
1514 	/* SSID */
1515 	*pos++ = WLAN_EID_SSID;
1516 	if (hapd->conf->ignore_broadcast_ssid == 2) {
1517 		/* clear the data, but keep the correct length of the SSID */
1518 		*pos++ = hapd->conf->ssid.ssid_len;
1519 		os_memset(pos, 0, hapd->conf->ssid.ssid_len);
1520 		pos += hapd->conf->ssid.ssid_len;
1521 	} else if (hapd->conf->ignore_broadcast_ssid) {
1522 		*pos++ = 0; /* empty SSID */
1523 	} else {
1524 		*pos++ = hapd->conf->ssid.ssid_len;
1525 		os_memcpy(pos, hapd->conf->ssid.ssid,
1526 			  hapd->conf->ssid.ssid_len);
1527 		pos += hapd->conf->ssid.ssid_len;
1528 	}
1529 
1530 	/* Supported rates */
1531 	pos = hostapd_eid_supp_rates(hapd, pos);
1532 
1533 #ifndef EXT_CODE_CROP
1534 	/* DS Params */
1535 	pos = hostapd_eid_ds_params(hapd, pos);
1536 #endif /* EXT_CODE_CROP */
1537 
1538 	head_len = pos - (u8 *) head;
1539 
1540 #ifndef EXT_CODE_CROP
1541 	tailpos = hostapd_eid_country(hapd, tailpos, tailend - tailpos);
1542 
1543 	/* Power Constraint element */
1544 	tailpos = hostapd_eid_pwr_constraint(hapd, tailpos);
1545 
1546 	/* CSA IE */
1547 	csa_pos = hostapd_eid_csa(hapd, tailpos);
1548 	if (csa_pos != tailpos)
1549 		hapd->cs_c_off_beacon = csa_pos - tail - 1;
1550 	tailpos = csa_pos;
1551 
1552 	/* ERP Information element */
1553 	tailpos = hostapd_eid_erp_info(hapd, tailpos);
1554 #endif /* EXT_CODE_CROP */
1555 
1556 	/* Extended supported rates */
1557 	tailpos = hostapd_eid_ext_supp_rates(hapd, tailpos);
1558 
1559 	tailpos = hostapd_get_rsne(hapd, tailpos, tailend - tailpos);
1560 #ifndef EXT_CODE_CROP
1561 	tailpos = hostapd_eid_bss_load(hapd, tailpos, tailend - tailpos);
1562 	tailpos = hostapd_eid_rm_enabled_capab(hapd, tailpos,
1563 					       tailend - tailpos);
1564 	tailpos = hostapd_get_mde(hapd, tailpos, tailend - tailpos);
1565 
1566 	/* eCSA IE */
1567 	csa_pos = hostapd_eid_ecsa(hapd, tailpos);
1568 	if (csa_pos != tailpos)
1569 		hapd->cs_c_off_ecsa_beacon = csa_pos - tail - 1;
1570 	tailpos = csa_pos;
1571 
1572 	tailpos = hostapd_eid_supported_op_classes(hapd, tailpos);
1573 #else
1574 	/* fill DS ies to beacon tail ,so that tail len will not be 0 in 11b open AP mode. */
1575 	/* DS Params */
1576 	tailpos = hostapd_eid_ds_params(hapd, tailpos);
1577 #endif /* EXT_CODE_CROP */
1578 	tailpos = hostapd_eid_ht_capabilities(hapd, tailpos);
1579 	tailpos = hostapd_eid_ht_operation(hapd, tailpos);
1580 
1581 #ifndef EXT_CODE_CROP
1582 	tailpos = hostapd_eid_ext_capab(hapd, tailpos);
1583 
1584 	/*
1585 	 * TODO: Time Advertisement element should only be included in some
1586 	 * DTIM Beacon frames.
1587 	 */
1588 	tailpos = hostapd_eid_time_adv(hapd, tailpos);
1589 
1590 	tailpos = hostapd_eid_interworking(hapd, tailpos);
1591 	tailpos = hostapd_eid_adv_proto(hapd, tailpos);
1592 	tailpos = hostapd_eid_roaming_consortium(hapd, tailpos);
1593 #endif /* EXT_CODE_CROP */
1594 #ifdef CONFIG_FST
1595 	if (hapd->iface->fst_ies) {
1596 		os_memcpy(tailpos, wpabuf_head(hapd->iface->fst_ies),
1597 			  wpabuf_len(hapd->iface->fst_ies));
1598 		tailpos += wpabuf_len(hapd->iface->fst_ies);
1599 	}
1600 #endif /* CONFIG_FST */
1601 
1602 #ifdef CONFIG_IEEE80211AC
1603 	if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac &&
1604 	    !is_6ghz_op_class(hapd->iconf->op_class)) {
1605 		tailpos = hostapd_eid_vht_capabilities(hapd, tailpos, 0);
1606 		tailpos = hostapd_eid_vht_operation(hapd, tailpos);
1607 		tailpos = hostapd_eid_txpower_envelope(hapd, tailpos);
1608 	}
1609 #endif /* CONFIG_IEEE80211AC */
1610 
1611 #ifdef CONFIG_IEEE80211AX
1612 	if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax &&
1613 	    is_6ghz_op_class(hapd->iconf->op_class))
1614 		tailpos = hostapd_eid_txpower_envelope(hapd, tailpos);
1615 #endif /* CONFIG_IEEE80211AX */
1616 
1617 	tailpos = hostapd_eid_wb_chsw_wrapper(hapd, tailpos);
1618 
1619 	tailpos = hostapd_eid_rnr(hapd, tailpos, WLAN_FC_STYPE_BEACON);
1620 	tailpos = hostapd_eid_fils_indic(hapd, tailpos, 0);
1621 	tailpos = hostapd_get_rsnxe(hapd, tailpos, tailend - tailpos);
1622 
1623 #ifdef CONFIG_IEEE80211AX
1624 	if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
1625 		tailpos = hostapd_eid_he_capab(hapd, tailpos,
1626 					       IEEE80211_MODE_AP);
1627 		tailpos = hostapd_eid_he_operation(hapd, tailpos);
1628 		tailpos = hostapd_eid_spatial_reuse(hapd, tailpos);
1629 		tailpos = hostapd_eid_he_mu_edca_parameter_set(hapd, tailpos);
1630 		tailpos = hostapd_eid_he_6ghz_band_cap(hapd, tailpos);
1631 	}
1632 #endif /* CONFIG_IEEE80211AX */
1633 
1634 #ifdef CONFIG_IEEE80211AC
1635 	if (hapd->conf->vendor_vht)
1636 		tailpos = hostapd_eid_vendor_vht(hapd, tailpos);
1637 #endif /* CONFIG_IEEE80211AC */
1638 
1639 	/* WPA / OSEN */
1640 	tailpos = hostapd_get_wpa_ie(hapd, tailpos, tailend - tailpos);
1641 	tailpos = hostapd_get_osen_ie(hapd, tailpos, tailend - tailpos);
1642 #ifndef LOS_CONFIG_HOSTAPD_QOS
1643 	/* Wi-Fi Alliance WMM */
1644 	tailpos = hostapd_eid_wmm(hapd, tailpos);
1645 #endif /* LOS_CONFIG_HOSTAPD_QOS */
1646 #ifdef CONFIG_WPS_AP
1647 	if (hapd->conf->wps_state && hapd->wps_beacon_ie) {
1648 		os_memcpy(tailpos, wpabuf_head(hapd->wps_beacon_ie),
1649 			  wpabuf_len(hapd->wps_beacon_ie));
1650 		tailpos += wpabuf_len(hapd->wps_beacon_ie);
1651 	}
1652 #endif /* CONFIG_WPS_AP */
1653 
1654 #ifdef CONFIG_P2P
1655 	if ((hapd->conf->p2p & P2P_ENABLED) && hapd->p2p_beacon_ie) {
1656 		os_memcpy(tailpos, wpabuf_head(hapd->p2p_beacon_ie),
1657 			  wpabuf_len(hapd->p2p_beacon_ie));
1658 		tailpos += wpabuf_len(hapd->p2p_beacon_ie);
1659 	}
1660 #endif /* CONFIG_P2P */
1661 #ifdef CONFIG_P2P_MANAGER
1662 	if ((hapd->conf->p2p & (P2P_MANAGE | P2P_ENABLED | P2P_GROUP_OWNER)) ==
1663 	    P2P_MANAGE)
1664 		tailpos = hostapd_eid_p2p_manage(hapd, tailpos);
1665 #endif /* CONFIG_P2P_MANAGER */
1666 #ifndef EXT_CODE_CROP
1667 #ifdef CONFIG_HS20
1668 	tailpos = hostapd_eid_hs20_indication(hapd, tailpos);
1669 #endif /* CONFIG_HS20 */
1670 
1671 	tailpos = hostapd_eid_mbo(hapd, tailpos, tail + tail_len - tailpos);
1672 	tailpos = hostapd_eid_owe_trans(hapd, tailpos,
1673 					tail + tail_len - tailpos);
1674 	tailpos = hostapd_eid_dpp_cc(hapd, tailpos, tail + tail_len - tailpos);
1675 
1676 	if (hapd->conf->vendor_elements) {
1677 		os_memcpy(tailpos, wpabuf_head(hapd->conf->vendor_elements),
1678 			  wpabuf_len(hapd->conf->vendor_elements));
1679 		tailpos += wpabuf_len(hapd->conf->vendor_elements);
1680 	}
1681 #endif /* EXT_CODE_CROP */
1682 
1683 	tail_len = tailpos > tail ? tailpos - tail : 0;
1684 #ifndef LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT
1685 	resp = hostapd_probe_resp_offloads(hapd, &resp_len);
1686 #endif /* LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT */
1687 #endif /* NEED_AP_MLME */
1688 
1689 	os_memset(params, 0, sizeof(*params));
1690 	params->head = (u8 *) head;
1691 	params->head_len = head_len;
1692 	params->tail = tail;
1693 	params->tail_len = tail_len;
1694 #ifndef LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT
1695 	params->proberesp = resp;
1696 	params->proberesp_len = resp_len;
1697 #endif /* LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT */
1698 	params->dtim_period = hapd->conf->dtim_period;
1699 	params->beacon_int = hapd->iconf->beacon_int;
1700 #ifndef LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT
1701 	params->basic_rates = hapd->iface->basic_rates;
1702 	params->beacon_rate = hapd->iconf->beacon_rate;
1703 	params->rate_type = hapd->iconf->rate_type;
1704 #endif /* LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT */
1705 	params->ssid = hapd->conf->ssid.ssid;
1706 	params->ssid_len = hapd->conf->ssid.ssid_len;
1707 #ifdef CONFIG_MESH
1708 	if (hapd->iface->mconf != NULL) {
1709 	/* wifi driver will copy mesh_ssid by itself. */
1710 #ifndef EXT_CODE_CROP
1711 		params->mesh_ssid = hapd->iface->mconf->meshid;
1712 		params->mesh_ssid_len = hapd->iface->mconf->meshid_len;
1713 #else
1714 		params->ssid = hapd->iface->mconf->meshid;
1715 		params->ssid_len = hapd->iface->mconf->meshid_len;
1716 #endif /* EXT_CODE_CROP */
1717 	}
1718 #endif /* LOS_CONFIG_MESH */
1719 	if ((hapd->conf->wpa & (WPA_PROTO_WPA | WPA_PROTO_RSN)) ==
1720 	    (WPA_PROTO_WPA | WPA_PROTO_RSN))
1721 		params->pairwise_ciphers = hapd->conf->wpa_pairwise |
1722 			hapd->conf->rsn_pairwise;
1723 	else if (hapd->conf->wpa & WPA_PROTO_RSN)
1724 		params->pairwise_ciphers = hapd->conf->rsn_pairwise;
1725 	else if (hapd->conf->wpa & WPA_PROTO_WPA)
1726 		params->pairwise_ciphers = hapd->conf->wpa_pairwise;
1727 	params->group_cipher = hapd->conf->wpa_group;
1728 	params->key_mgmt_suites = hapd->conf->wpa_key_mgmt;
1729 	params->auth_algs = hapd->conf->auth_algs;
1730 	params->wpa_version = hapd->conf->wpa;
1731 	params->privacy = hapd->conf->wpa;
1732 #ifdef CONFIG_WEP
1733 #ifndef LOS_CONFIG_HOSTAPD_SECURITY
1734 	params->privacy |= hapd->conf->ssid.wep.keys_set ||
1735 		(hapd->conf->ieee802_1x &&
1736 		 (hapd->conf->default_wep_key_len ||
1737 		  hapd->conf->individual_wep_key_len));
1738 #endif /* LOS_CONFIG_HOSTAPD_SECURITY */
1739 #endif /* CONFIG_WEP */
1740 	switch (hapd->conf->ignore_broadcast_ssid) {
1741 	case 0:
1742 		params->hide_ssid = NO_SSID_HIDING;
1743 		break;
1744 	case 1:
1745 		params->hide_ssid = HIDDEN_SSID_ZERO_LEN;
1746 		break;
1747 	case 2:
1748 		params->hide_ssid = HIDDEN_SSID_ZERO_CONTENTS;
1749 		break;
1750 	}
1751 #ifndef LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT
1752 	params->isolate = hapd->conf->isolate;
1753 #ifdef NEED_AP_MLME
1754 	params->cts_protect = !!(ieee802_11_erp_info(hapd) &
1755 				ERP_INFO_USE_PROTECTION);
1756 	params->preamble = hapd->iface->num_sta_no_short_preamble == 0 &&
1757 		hapd->iconf->preamble == SHORT_PREAMBLE;
1758 	if (hapd->iface->current_mode &&
1759 	    hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
1760 		params->short_slot_time =
1761 			hapd->iface->num_sta_no_short_slot_time > 0 ? 0 : 1;
1762 	else
1763 		params->short_slot_time = -1;
1764 	if (!hapd->iconf->ieee80211n || hapd->conf->disable_11n)
1765 		params->ht_opmode = -1;
1766 	else
1767 		params->ht_opmode = hapd->iface->ht_op_mode;
1768 #endif /* NEED_AP_MLME */
1769 	params->interworking = hapd->conf->interworking;
1770 	if (hapd->conf->interworking &&
1771 	    !is_zero_ether_addr(hapd->conf->hessid))
1772 		params->hessid = hapd->conf->hessid;
1773 	params->access_network_type = hapd->conf->access_network_type;
1774 #endif /* LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT */
1775 	params->ap_max_inactivity = hapd->conf->ap_max_inactivity;
1776 #ifdef CONFIG_P2P
1777 	params->p2p_go_ctwindow = hapd->iconf->p2p_go_ctwindow;
1778 #endif /* CONFIG_P2P */
1779 #ifndef LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT
1780 #ifdef CONFIG_HS20
1781 	params->disable_dgaf = hapd->conf->disable_dgaf;
1782 	if (hapd->conf->osen) {
1783 		params->privacy = 1;
1784 		params->osen = 1;
1785 	}
1786 #endif /* CONFIG_HS20 */
1787 	params->multicast_to_unicast = hapd->conf->multicast_to_unicast;
1788 	params->pbss = hapd->conf->pbss;
1789 #endif /* LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT */
1790 #ifndef EXT_CODE_CROP
1791 	if (hapd->conf->ftm_responder) {
1792 		if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_FTM_RESPONDER) {
1793 			params->ftm_responder = 1;
1794 			params->lci = hapd->iface->conf->lci;
1795 			params->civic = hapd->iface->conf->civic;
1796 		} else {
1797 			wpa_printf(MSG_WARNING,
1798 				   "Not configuring FTM responder as the driver doesn't advertise support for it");
1799 		}
1800 	}
1801 #endif /* EXT_CODE_CROP */
1802 	return 0;
1803 }
1804 
1805 
ieee802_11_free_ap_params(struct wpa_driver_ap_params * params)1806 void ieee802_11_free_ap_params(struct wpa_driver_ap_params *params)
1807 {
1808 	os_free(params->tail);
1809 	params->tail = NULL;
1810 	os_free(params->head);
1811 	params->head = NULL;
1812 #ifndef LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT
1813 	os_free(params->proberesp);
1814 	params->proberesp = NULL;
1815 #ifdef CONFIG_FILS
1816 	os_free(params->fd_frame_tmpl);
1817 	params->fd_frame_tmpl = NULL;
1818 #endif /* CONFIG_FILS */
1819 #ifdef CONFIG_IEEE80211AX
1820 	os_free(params->unsol_bcast_probe_resp_tmpl);
1821 	params->unsol_bcast_probe_resp_tmpl = NULL;
1822 #endif /* CONFIG_IEEE80211AX */
1823 #endif /* LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT */
1824 }
1825 
1826 
__ieee802_11_set_beacon(struct hostapd_data * hapd)1827 static int __ieee802_11_set_beacon(struct hostapd_data *hapd)
1828 {
1829 	struct wpa_driver_ap_params params;
1830 	struct hostapd_freq_params freq;
1831 	struct hostapd_iface *iface = hapd->iface;
1832 	struct hostapd_config *iconf = iface->conf;
1833 	struct hostapd_hw_modes *cmode = iface->current_mode;
1834 	struct wpabuf *beacon, *proberesp, *assocresp;
1835 	int res, ret = -1;
1836 
1837 	if (!hapd->drv_priv) {
1838 		wpa_printf(MSG_ERROR, "Interface is disabled");
1839 		return -1;
1840 	}
1841 
1842 	if (hapd->csa_in_progress) {
1843 		wpa_printf(MSG_ERROR, "Cannot set beacons during CSA period");
1844 		return -1;
1845 	}
1846 
1847 	hapd->beacon_set_done = 1;
1848 
1849 	if (ieee802_11_build_ap_params(hapd, &params) < 0)
1850 		return -1;
1851 
1852 #ifndef LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT
1853 	if (hostapd_build_ap_extra_ies(hapd, &beacon, &proberesp, &assocresp) <
1854 	    0)
1855 		goto fail;
1856 
1857 	params.beacon_ies = beacon;
1858 	params.proberesp_ies = proberesp;
1859 	params.assocresp_ies = assocresp;
1860 	params.reenable = hapd->reenable_beacon;
1861 	hapd->reenable_beacon = 0;
1862 #endif /* LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT */
1863 #ifdef CONFIG_IEEE80211AX
1864 	params.he_spr_ctrl = hapd->iface->conf->spr.sr_control;
1865 	params.he_spr_non_srg_obss_pd_max_offset =
1866 		hapd->iface->conf->spr.non_srg_obss_pd_max_offset;
1867 	params.he_spr_srg_obss_pd_min_offset =
1868 		hapd->iface->conf->spr.srg_obss_pd_min_offset;
1869 	params.he_spr_srg_obss_pd_max_offset =
1870 		hapd->iface->conf->spr.srg_obss_pd_max_offset;
1871 	os_memcpy(params.he_spr_bss_color_bitmap,
1872 		  hapd->iface->conf->spr.srg_bss_color_bitmap, 8);
1873 	os_memcpy(params.he_spr_partial_bssid_bitmap,
1874 		  hapd->iface->conf->spr.srg_partial_bssid_bitmap, 8);
1875 	params.he_bss_color_disabled =
1876 		hapd->iface->conf->he_op.he_bss_color_disabled;
1877 	params.he_bss_color_partial =
1878 		hapd->iface->conf->he_op.he_bss_color_partial;
1879 	params.he_bss_color = hapd->iface->conf->he_op.he_bss_color;
1880 	params.twt_responder = hostapd_get_he_twt_responder(hapd,
1881 							    IEEE80211_MODE_AP);
1882 #ifndef EXT_CODE_CROP
1883 	params.unsol_bcast_probe_resp_tmpl =
1884 		hostapd_unsol_bcast_probe_resp(hapd, &params);
1885 #endif
1886 #endif /* CONFIG_IEEE80211AX */
1887 
1888 #ifdef CONFIG_SAE
1889 	params.sae_pwe = hapd->conf->sae_pwe;
1890 #endif /* CONFIG_SAE */
1891 
1892 #ifdef CONFIG_FILS
1893 	params.fd_frame_tmpl = hostapd_fils_discovery(hapd, &params);
1894 #endif /* CONFIG_FILS */
1895 #ifndef LOS_WPA_PATCH
1896 	if (cmode &&
1897 	    hostapd_set_freq_params(&freq, iconf->hw_mode, iface->freq,
1898 				    iconf->channel, iconf->enable_edmg,
1899 				    iconf->edmg_channel, iconf->ieee80211n,
1900 				    iconf->ieee80211ac, iconf->ieee80211ax,
1901 				    iconf->secondary_channel,
1902 				    hostapd_get_oper_chwidth(iconf),
1903 				    hostapd_get_oper_centr_freq_seg0_idx(iconf),
1904 				    hostapd_get_oper_centr_freq_seg1_idx(iconf),
1905 				    cmode->vht_capab,
1906 				    &cmode->he_capab[IEEE80211_MODE_AP]) == 0)
1907 #else
1908 	if (cmode &&
1909 			hostapd_set_freq_params(&freq, iconf->hw_mode, iface->freq,
1910 						iconf->channel, iconf->ieee80211n) == 0)
1911 #endif /* LOS_WPA_PATCH */
1912 		params.freq = &freq;
1913 
1914 	res = hostapd_drv_set_ap(hapd, &params);
1915 #ifndef LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT
1916 	hostapd_free_ap_extra_ies(hapd, beacon, proberesp, assocresp);
1917 #endif /* LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT */
1918 	if (res)
1919 		wpa_printf(MSG_ERROR, "Failed to set beacon parameters");
1920 	else
1921 		ret = 0;
1922 #ifndef LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT
1923 fail:
1924 #endif /* LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT */
1925 	ieee802_11_free_ap_params(&params);
1926 	return ret;
1927 }
1928 
1929 
ieee802_11_set_beacon(struct hostapd_data * hapd)1930 int ieee802_11_set_beacon(struct hostapd_data *hapd)
1931 {
1932 	struct hostapd_iface *iface = hapd->iface;
1933 	int ret;
1934 	size_t i, j;
1935 	bool is_6g;
1936 
1937 	ret = __ieee802_11_set_beacon(hapd);
1938 	if (ret != 0)
1939 		return ret;
1940 
1941 	if (!iface->interfaces || iface->interfaces->count <= 1)
1942 		return 0;
1943 
1944 	/* Update Beacon frames in case of 6 GHz colocation */
1945 	is_6g = is_6ghz_op_class(iface->conf->op_class);
1946 	for (j = 0; j < iface->interfaces->count; j++) {
1947 		struct hostapd_iface *colocated;
1948 
1949 		colocated = iface->interfaces->iface[j];
1950 		if (colocated == iface || !colocated || !colocated->conf)
1951 			continue;
1952 
1953 		if (is_6g == is_6ghz_op_class(colocated->conf->op_class))
1954 			continue;
1955 
1956 		for (i = 0; i < colocated->num_bss; i++) {
1957 			if (colocated->bss[i] && colocated->bss[i]->started)
1958 				__ieee802_11_set_beacon(colocated->bss[i]);
1959 		}
1960 	}
1961 
1962 	return 0;
1963 }
1964 
1965 
ieee802_11_set_beacons(struct hostapd_iface * iface)1966 int ieee802_11_set_beacons(struct hostapd_iface *iface)
1967 {
1968 	size_t i;
1969 	int ret = 0;
1970 
1971 	for (i = 0; i < iface->num_bss; i++) {
1972 		if (iface->bss[i]->started &&
1973 		    ieee802_11_set_beacon(iface->bss[i]) < 0)
1974 			ret = -1;
1975 	}
1976 
1977 	return ret;
1978 }
1979 
1980 
1981 /* only update beacons if started */
ieee802_11_update_beacons(struct hostapd_iface * iface)1982 int ieee802_11_update_beacons(struct hostapd_iface *iface)
1983 {
1984 	size_t i;
1985 	int ret = 0;
1986 
1987 	for (i = 0; i < iface->num_bss; i++) {
1988 		if (iface->bss[i]->beacon_set_done && iface->bss[i]->started &&
1989 		    ieee802_11_set_beacon(iface->bss[i]) < 0)
1990 			ret = -1;
1991 	}
1992 
1993 	return ret;
1994 }
1995 
1996 #endif /* CONFIG_NATIVE_WINDOWS */
1997