xref: /aosp_15_r20/external/wpa_supplicant_8/src/ap/beacon.c (revision 03f9172ca588f91df233974f4258bab95191f931)
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 <[email protected]>
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 "crypto/sha1.h"
21 #include "wps/wps_defs.h"
22 #include "p2p/p2p.h"
23 #include "hostapd.h"
24 #include "ieee802_11.h"
25 #include "wpa_auth.h"
26 #include "wmm.h"
27 #include "ap_config.h"
28 #include "sta_info.h"
29 #include "p2p_hostapd.h"
30 #include "ap_drv_ops.h"
31 #include "beacon.h"
32 #include "hs20.h"
33 #include "dfs.h"
34 #include "taxonomy.h"
35 #include "ieee802_11_auth.h"
36 
37 
38 #ifdef NEED_AP_MLME
39 
hostapd_eid_bss_load(struct hostapd_data * hapd,u8 * eid,size_t len)40 static u8 * hostapd_eid_bss_load(struct hostapd_data *hapd, u8 *eid, size_t len)
41 {
42 	if (len < 2 + 5)
43 		return eid;
44 
45 #ifdef CONFIG_TESTING_OPTIONS
46 	if (hapd->conf->bss_load_test_set) {
47 		*eid++ = WLAN_EID_BSS_LOAD;
48 		*eid++ = 5;
49 		os_memcpy(eid, hapd->conf->bss_load_test, 5);
50 		eid += 5;
51 		return eid;
52 	}
53 #endif /* CONFIG_TESTING_OPTIONS */
54 	if (hapd->conf->bss_load_update_period) {
55 		*eid++ = WLAN_EID_BSS_LOAD;
56 		*eid++ = 5;
57 		WPA_PUT_LE16(eid, hapd->num_sta);
58 		eid += 2;
59 		*eid++ = hapd->iface->channel_utilization;
60 		WPA_PUT_LE16(eid, 0); /* no available admission capabity */
61 		eid += 2;
62 	}
63 	return eid;
64 }
65 
66 
ieee802_11_erp_info(struct hostapd_data * hapd)67 static u8 ieee802_11_erp_info(struct hostapd_data *hapd)
68 {
69 	u8 erp = 0;
70 
71 	if (hapd->iface->current_mode == NULL ||
72 	    hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G)
73 		return 0;
74 
75 	if (hapd->iface->olbc)
76 		erp |= ERP_INFO_USE_PROTECTION;
77 	if (hapd->iface->num_sta_non_erp > 0) {
78 		erp |= ERP_INFO_NON_ERP_PRESENT |
79 			ERP_INFO_USE_PROTECTION;
80 	}
81 	if (hapd->iface->num_sta_no_short_preamble > 0 ||
82 	    hapd->iconf->preamble == LONG_PREAMBLE)
83 		erp |= ERP_INFO_BARKER_PREAMBLE_MODE;
84 
85 	return erp;
86 }
87 
88 
hostapd_eid_ds_params(struct hostapd_data * hapd,u8 * eid)89 static u8 * hostapd_eid_ds_params(struct hostapd_data *hapd, u8 *eid)
90 {
91 	enum hostapd_hw_mode hw_mode = hapd->iconf->hw_mode;
92 
93 	if (hw_mode != HOSTAPD_MODE_IEEE80211G &&
94 	    hw_mode != HOSTAPD_MODE_IEEE80211B)
95 		return eid;
96 
97 	*eid++ = WLAN_EID_DS_PARAMS;
98 	*eid++ = 1;
99 	*eid++ = hapd->iconf->channel;
100 	return eid;
101 }
102 
103 
hostapd_eid_erp_info(struct hostapd_data * hapd,u8 * eid)104 static u8 * hostapd_eid_erp_info(struct hostapd_data *hapd, u8 *eid)
105 {
106 	if (hapd->iface->current_mode == NULL ||
107 	    hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G)
108 		return eid;
109 
110 	/* Set NonERP_present and use_protection bits if there
111 	 * are any associated NonERP stations. */
112 	/* TODO: use_protection bit can be set to zero even if
113 	 * there are NonERP stations present. This optimization
114 	 * might be useful if NonERP stations are "quiet".
115 	 * See 802.11g/D6 E-1 for recommended practice.
116 	 * In addition, Non ERP present might be set, if AP detects Non ERP
117 	 * operation on other APs. */
118 
119 	/* Add ERP Information element */
120 	*eid++ = WLAN_EID_ERP_INFO;
121 	*eid++ = 1;
122 	*eid++ = ieee802_11_erp_info(hapd);
123 
124 	return eid;
125 }
126 
127 
hostapd_eid_pwr_constraint(struct hostapd_data * hapd,u8 * eid)128 static u8 * hostapd_eid_pwr_constraint(struct hostapd_data *hapd, u8 *eid)
129 {
130 	u8 *pos = eid;
131 	u8 local_pwr_constraint = 0;
132 	int dfs;
133 
134 	if (hapd->iface->current_mode == NULL ||
135 	    hapd->iface->current_mode->mode != HOSTAPD_MODE_IEEE80211A)
136 		return eid;
137 
138 	/* Let host drivers add this IE if DFS support is offloaded */
139 	if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)
140 		return eid;
141 
142 	/*
143 	 * There is no DFS support and power constraint was not directly
144 	 * requested by config option.
145 	 */
146 	if (!hapd->iconf->ieee80211h &&
147 	    hapd->iconf->local_pwr_constraint == -1)
148 		return eid;
149 
150 	/* Check if DFS is required by regulatory. */
151 	dfs = hostapd_is_dfs_required(hapd->iface);
152 	if (dfs < 0) {
153 		wpa_printf(MSG_WARNING, "Failed to check if DFS is required; ret=%d",
154 			   dfs);
155 		dfs = 0;
156 	}
157 
158 	if (dfs == 0 && hapd->iconf->local_pwr_constraint == -1)
159 		return eid;
160 
161 	/*
162 	 * ieee80211h (DFS) is enabled so Power Constraint element shall
163 	 * be added when running on DFS channel whenever local_pwr_constraint
164 	 * is configured or not. In order to meet regulations when TPC is not
165 	 * implemented using a transmit power that is below the legal maximum
166 	 * (including any mitigation factor) should help. In this case,
167 	 * indicate 3 dB below maximum allowed transmit power.
168 	 */
169 	if (hapd->iconf->local_pwr_constraint == -1)
170 		local_pwr_constraint = 3;
171 
172 	/*
173 	 * A STA that is not an AP shall use a transmit power less than or
174 	 * equal to the local maximum transmit power level for the channel.
175 	 * The local maximum transmit power can be calculated from the formula:
176 	 * local max TX pwr = max TX pwr - local pwr constraint
177 	 * Where max TX pwr is maximum transmit power level specified for
178 	 * channel in Country element and local pwr constraint is specified
179 	 * for channel in this Power Constraint element.
180 	 */
181 
182 	/* Element ID */
183 	*pos++ = WLAN_EID_PWR_CONSTRAINT;
184 	/* Length */
185 	*pos++ = 1;
186 	/* Local Power Constraint */
187 	if (local_pwr_constraint)
188 		*pos++ = local_pwr_constraint;
189 	else
190 		*pos++ = hapd->iconf->local_pwr_constraint;
191 
192 	return pos;
193 }
194 
195 
hostapd_eid_country_add(struct hostapd_data * hapd,u8 * pos,u8 * end,int chan_spacing,struct hostapd_channel_data * start,struct hostapd_channel_data * prev)196 static u8 * hostapd_eid_country_add(struct hostapd_data *hapd, u8 *pos,
197 				    u8 *end, int chan_spacing,
198 				    struct hostapd_channel_data *start,
199 				    struct hostapd_channel_data *prev)
200 {
201 	if (end - pos < 3)
202 		return pos;
203 
204 	/* first channel number */
205 	*pos++ = start->chan;
206 	/* number of channels */
207 	*pos++ = (prev->chan - start->chan) / chan_spacing + 1;
208 	/* maximum transmit power level */
209 	if (!is_6ghz_op_class(hapd->iconf->op_class))
210 		*pos++ = start->max_tx_power;
211 	else
212 		*pos++ = 0; /* Reserved when operating on the 6 GHz band */
213 
214 	return pos;
215 }
216 
217 
hostapd_fill_subband_triplets(struct hostapd_data * hapd,u8 * pos,u8 * end)218 static u8 * hostapd_fill_subband_triplets(struct hostapd_data *hapd, u8 *pos,
219 					    u8 *end)
220 {
221 	int i;
222 	struct hostapd_hw_modes *mode;
223 	struct hostapd_channel_data *start, *prev;
224 	int chan_spacing = 1;
225 
226 	mode = hapd->iface->current_mode;
227 	if (mode->mode == HOSTAPD_MODE_IEEE80211A)
228 		chan_spacing = 4;
229 
230 	start = prev = NULL;
231 	for (i = 0; i < mode->num_channels; i++) {
232 		struct hostapd_channel_data *chan = &mode->channels[i];
233 		if (chan->flag & HOSTAPD_CHAN_DISABLED)
234 			continue;
235 		if (start && prev &&
236 		    prev->chan + chan_spacing == chan->chan &&
237 		    start->max_tx_power == chan->max_tx_power) {
238 			prev = chan;
239 			continue; /* can use same entry */
240 		}
241 
242 		if (start && prev)
243 			pos = hostapd_eid_country_add(hapd, pos, end,
244 						      chan_spacing,
245 						      start, prev);
246 
247 		/* Start new group */
248 		start = prev = chan;
249 	}
250 
251 	if (start) {
252 		pos = hostapd_eid_country_add(hapd, pos, end, chan_spacing,
253 					      start, prev);
254 	}
255 
256 	return pos;
257 }
258 
259 
hostapd_eid_country(struct hostapd_data * hapd,u8 * eid,int max_len)260 static u8 * hostapd_eid_country(struct hostapd_data *hapd, u8 *eid,
261 				int max_len)
262 {
263 	u8 *pos = eid;
264 	u8 *end = eid + max_len;
265 
266 	if (!hapd->iconf->ieee80211d || max_len < 6 ||
267 	    hapd->iface->current_mode == NULL)
268 		return eid;
269 
270 	*pos++ = WLAN_EID_COUNTRY;
271 	pos++; /* length will be set later */
272 	os_memcpy(pos, hapd->iconf->country, 3); /* e.g., 'US ' */
273 	pos += 3;
274 
275 	if (is_6ghz_op_class(hapd->iconf->op_class)) {
276 		/* Force the third octet of the country string to indicate
277 		 * Global Operating Class (Table E-4) */
278 		eid[4] = 0x04;
279 
280 		/* Operating Triplet field */
281 		/* Operating Extension Identifier (>= 201 to indicate this is
282 		 * not a Subband Triplet field) */
283 		*pos++ = 201;
284 		/* Operating Class */
285 		*pos++ = hapd->iconf->op_class;
286 		/* Coverage Class */
287 		*pos++ = 0;
288 		/* Subband Triplets are required only for the 20 MHz case */
289 		if (hapd->iconf->op_class == 131 ||
290 		    hapd->iconf->op_class == 136)
291 			pos = hostapd_fill_subband_triplets(hapd, pos, end);
292 	} else {
293 		pos = hostapd_fill_subband_triplets(hapd, pos, end);
294 	}
295 
296 	if ((pos - eid) & 1) {
297 		if (end - pos < 1)
298 			return eid;
299 		*pos++ = 0; /* pad for 16-bit alignment */
300 	}
301 
302 	eid[1] = (pos - eid) - 2;
303 
304 	return pos;
305 }
306 
307 
hostapd_wpa_ie(struct hostapd_data * hapd,u8 eid)308 const u8 * hostapd_wpa_ie(struct hostapd_data *hapd, u8 eid)
309 {
310 	const u8 *ies;
311 	size_t ies_len;
312 
313 	ies = wpa_auth_get_wpa_ie(hapd->wpa_auth, &ies_len);
314 	if (!ies)
315 		return NULL;
316 
317 	return get_ie(ies, ies_len, eid);
318 }
319 
320 
hostapd_vendor_wpa_ie(struct hostapd_data * hapd,u32 vendor_type)321 static const u8 * hostapd_vendor_wpa_ie(struct hostapd_data *hapd,
322 					u32 vendor_type)
323 {
324 	const u8 *ies;
325 	size_t ies_len;
326 
327 	ies = wpa_auth_get_wpa_ie(hapd->wpa_auth, &ies_len);
328 	if (!ies)
329 		return NULL;
330 
331 	return get_vendor_ie(ies, ies_len, vendor_type);
332 }
333 
334 
hostapd_get_rsne(struct hostapd_data * hapd,u8 * pos,size_t len)335 static u8 * hostapd_get_rsne(struct hostapd_data *hapd, u8 *pos, size_t len)
336 {
337 	const u8 *ie;
338 
339 	ie = hostapd_wpa_ie(hapd, WLAN_EID_RSN);
340 	if (!ie || 2U + ie[1] > len)
341 		return pos;
342 
343 	os_memcpy(pos, ie, 2 + ie[1]);
344 	return pos + 2 + ie[1];
345 }
346 
347 
hostapd_get_mde(struct hostapd_data * hapd,u8 * pos,size_t len)348 static u8 * hostapd_get_mde(struct hostapd_data *hapd, u8 *pos, size_t len)
349 {
350 	const u8 *ie;
351 
352 	ie = hostapd_wpa_ie(hapd, WLAN_EID_MOBILITY_DOMAIN);
353 	if (!ie || 2U + ie[1] > len)
354 		return pos;
355 
356 	os_memcpy(pos, ie, 2 + ie[1]);
357 	return pos + 2 + ie[1];
358 }
359 
360 
hostapd_get_rsnxe(struct hostapd_data * hapd,u8 * pos,size_t len)361 static u8 * hostapd_get_rsnxe(struct hostapd_data *hapd, u8 *pos, size_t len)
362 {
363 	const u8 *ie;
364 
365 #ifdef CONFIG_TESTING_OPTIONS
366 	if (hapd->conf->no_beacon_rsnxe) {
367 		wpa_printf(MSG_INFO, "TESTING: Do not add RSNXE into Beacon");
368 		return pos;
369 	}
370 #endif /* CONFIG_TESTING_OPTIONS */
371 	ie = hostapd_wpa_ie(hapd, WLAN_EID_RSNX);
372 	if (!ie || 2U + ie[1] > len)
373 		return pos;
374 
375 	os_memcpy(pos, ie, 2 + ie[1]);
376 	return pos + 2 + ie[1];
377 }
378 
379 
hostapd_get_wpa_ie(struct hostapd_data * hapd,u8 * pos,size_t len)380 static u8 * hostapd_get_wpa_ie(struct hostapd_data *hapd, u8 *pos, size_t len)
381 {
382 	const u8 *ie;
383 
384 	ie = hostapd_vendor_wpa_ie(hapd, WPA_IE_VENDOR_TYPE);
385 	if (!ie || 2U + ie[1] > len)
386 		return pos;
387 
388 	os_memcpy(pos, ie, 2 + ie[1]);
389 	return pos + 2 + ie[1];
390 }
391 
392 
hostapd_get_osen_ie(struct hostapd_data * hapd,u8 * pos,size_t len)393 static u8 * hostapd_get_osen_ie(struct hostapd_data *hapd, u8 *pos, size_t len)
394 {
395 	const u8 *ie;
396 
397 	ie = hostapd_vendor_wpa_ie(hapd, OSEN_IE_VENDOR_TYPE);
398 	if (!ie || 2U + ie[1] > len)
399 		return pos;
400 
401 	os_memcpy(pos, ie, 2 + ie[1]);
402 	return pos + 2 + ie[1];
403 }
404 
405 
hostapd_get_rsne_override(struct hostapd_data * hapd,u8 * pos,size_t len)406 static u8 * hostapd_get_rsne_override(struct hostapd_data *hapd, u8 *pos,
407 				      size_t len)
408 {
409 	const u8 *ie;
410 
411 	ie = hostapd_vendor_wpa_ie(hapd, RSNE_OVERRIDE_IE_VENDOR_TYPE);
412 	if (!ie || 2U + ie[1] > len)
413 		return pos;
414 
415 	os_memcpy(pos, ie, 2 + ie[1]);
416 	return pos + 2 + ie[1];
417 }
418 
419 
hostapd_get_rsne_override_2(struct hostapd_data * hapd,u8 * pos,size_t len)420 static u8 * hostapd_get_rsne_override_2(struct hostapd_data *hapd, u8 *pos,
421 					size_t len)
422 {
423 	const u8 *ie;
424 
425 	ie = hostapd_vendor_wpa_ie(hapd, RSNE_OVERRIDE_2_IE_VENDOR_TYPE);
426 	if (!ie || 2U + ie[1] > len)
427 		return pos;
428 
429 	os_memcpy(pos, ie, 2 + ie[1]);
430 	return pos + 2 + ie[1];
431 }
432 
433 
hostapd_get_rsnxe_override(struct hostapd_data * hapd,u8 * pos,size_t len)434 static u8 * hostapd_get_rsnxe_override(struct hostapd_data *hapd, u8 *pos,
435 				       size_t len)
436 {
437 	const u8 *ie;
438 
439 	ie = hostapd_vendor_wpa_ie(hapd, RSNXE_OVERRIDE_IE_VENDOR_TYPE);
440 	if (!ie || 2U + ie[1] > len)
441 		return pos;
442 
443 	os_memcpy(pos, ie, 2 + ie[1]);
444 	return pos + 2 + ie[1];
445 }
446 
447 
hostapd_get_rsne_override_len(struct hostapd_data * hapd)448 static size_t hostapd_get_rsne_override_len(struct hostapd_data *hapd)
449 {
450 	const u8 *ie;
451 
452 	ie = hostapd_vendor_wpa_ie(hapd, RSNE_OVERRIDE_IE_VENDOR_TYPE);
453 	if (!ie)
454 		return 0;
455 	return 2 + ie[1];
456 }
457 
458 
hostapd_get_rsne_override_2_len(struct hostapd_data * hapd)459 static size_t hostapd_get_rsne_override_2_len(struct hostapd_data *hapd)
460 {
461 	const u8 *ie;
462 
463 	ie = hostapd_vendor_wpa_ie(hapd, RSNE_OVERRIDE_2_IE_VENDOR_TYPE);
464 	if (!ie)
465 		return 0;
466 	return 2 + ie[1];
467 }
468 
469 
hostapd_get_rsnxe_override_len(struct hostapd_data * hapd)470 static size_t hostapd_get_rsnxe_override_len(struct hostapd_data *hapd)
471 {
472 	const u8 *ie;
473 
474 	ie = hostapd_vendor_wpa_ie(hapd, RSNXE_OVERRIDE_IE_VENDOR_TYPE);
475 	if (!ie)
476 		return 0;
477 	return 2 + ie[1];
478 }
479 
480 
hostapd_eid_csa(struct hostapd_data * hapd,u8 * eid)481 static u8 * hostapd_eid_csa(struct hostapd_data *hapd, u8 *eid)
482 {
483 #ifdef CONFIG_TESTING_OPTIONS
484 	if (hapd->iface->cs_oper_class && hapd->iconf->ecsa_ie_only)
485 		return eid;
486 #endif /* CONFIG_TESTING_OPTIONS */
487 
488 	if (!hapd->cs_freq_params.channel)
489 		return eid;
490 
491 	*eid++ = WLAN_EID_CHANNEL_SWITCH;
492 	*eid++ = 3;
493 	*eid++ = hapd->cs_block_tx;
494 	*eid++ = hapd->cs_freq_params.channel;
495 	*eid++ = hapd->cs_count;
496 
497 	return eid;
498 }
499 
500 
hostapd_eid_ecsa(struct hostapd_data * hapd,u8 * eid)501 static u8 * hostapd_eid_ecsa(struct hostapd_data *hapd, u8 *eid)
502 {
503 	if (!hapd->cs_freq_params.channel || !hapd->iface->cs_oper_class)
504 		return eid;
505 
506 	*eid++ = WLAN_EID_EXT_CHANSWITCH_ANN;
507 	*eid++ = 4;
508 	*eid++ = hapd->cs_block_tx;
509 	*eid++ = hapd->iface->cs_oper_class;
510 	*eid++ = hapd->cs_freq_params.channel;
511 	*eid++ = hapd->cs_count;
512 
513 	return eid;
514 }
515 
516 
hostapd_eid_max_cs_time(struct hostapd_data * hapd,u8 * eid)517 static u8 * hostapd_eid_max_cs_time(struct hostapd_data *hapd, u8 *eid)
518 {
519 #ifdef CONFIG_IEEE80211BE
520 	u32 switch_time;
521 
522 	/* Add Max Channel Switch Time element only if this AP is affiliated
523 	 * with an AP MLD and channel switch is in process. */
524 	if (!hapd->conf->mld_ap || !hapd->cs_freq_params.channel)
525 		return eid;
526 
527 	/* Switch time is basically time between CSA count 1 and CSA count
528 	 * 0 (1 beacon interval) + time for interface restart + time to
529 	 * send a Beacon frame in the new channel (1 beacon interval).
530 	 *
531 	 * TODO: Use dynamic interface restart time. For now, assume 1 sec.
532 	 */
533 	switch_time = USEC_TO_TU(1000 * 1000) + 2 * hapd->iconf->beacon_int;
534 
535 	*eid++ = WLAN_EID_EXTENSION;
536 	*eid++ = 4;
537 	*eid++ = WLAN_EID_EXT_MAX_CHANNEL_SWITCH_TIME;
538 	WPA_PUT_LE24(eid, switch_time);
539 	eid += 3;
540 #endif /* CONFIG_IEEE80211BE */
541 
542 	return eid;
543 }
544 
545 
hostapd_eid_supported_op_classes(struct hostapd_data * hapd,u8 * eid)546 static u8 * hostapd_eid_supported_op_classes(struct hostapd_data *hapd, u8 *eid)
547 {
548 	u8 op_class, channel;
549 
550 	if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA) ||
551 	    !hapd->iface->freq)
552 		return eid;
553 
554 	if (ieee80211_freq_to_channel_ext(hapd->iface->freq,
555 					  hapd->iconf->secondary_channel,
556 					  hostapd_get_oper_chwidth(hapd->iconf),
557 					  &op_class, &channel) ==
558 	    NUM_HOSTAPD_MODES)
559 		return eid;
560 
561 	*eid++ = WLAN_EID_SUPPORTED_OPERATING_CLASSES;
562 	*eid++ = 2;
563 
564 	/* Current Operating Class */
565 	*eid++ = op_class;
566 
567 	/* TODO: Advertise all the supported operating classes */
568 	*eid++ = 0;
569 
570 	return eid;
571 }
572 
573 
574 static int
ieee802_11_build_ap_params_mbssid(struct hostapd_data * hapd,struct wpa_driver_ap_params * params)575 ieee802_11_build_ap_params_mbssid(struct hostapd_data *hapd,
576 				  struct wpa_driver_ap_params *params)
577 {
578 	struct hostapd_iface *iface = hapd->iface;
579 	struct hostapd_data *tx_bss;
580 	size_t len, rnr_len = 0;
581 	u8 elem_count = 0, *elem = NULL, **elem_offset = NULL, *end;
582 	u8 rnr_elem_count = 0, *rnr_elem = NULL, **rnr_elem_offset = NULL;
583 	size_t i;
584 
585 	if (!iface->mbssid_max_interfaces ||
586 	    iface->num_bss > iface->mbssid_max_interfaces ||
587 	    (iface->conf->mbssid == ENHANCED_MBSSID_ENABLED &&
588 	     !iface->ema_max_periodicity))
589 		goto fail;
590 
591 	/* Make sure bss->xrates_supported is set for all BSSs to know whether
592 	 * it need to be non-inherited. */
593 	for (i = 0; i < iface->num_bss; i++) {
594 		u8 buf[100];
595 
596 		hostapd_eid_ext_supp_rates(iface->bss[i], buf);
597 	}
598 
599 	tx_bss = hostapd_mbssid_get_tx_bss(hapd);
600 	len = hostapd_eid_mbssid_len(tx_bss, WLAN_FC_STYPE_BEACON, &elem_count,
601 				     NULL, 0, &rnr_len);
602 	if (!len || (iface->conf->mbssid == ENHANCED_MBSSID_ENABLED &&
603 		     elem_count > iface->ema_max_periodicity))
604 		goto fail;
605 
606 	elem = os_zalloc(len);
607 	if (!elem)
608 		goto fail;
609 
610 	elem_offset = os_zalloc(elem_count * sizeof(u8 *));
611 	if (!elem_offset)
612 		goto fail;
613 
614 	if (rnr_len) {
615 		rnr_elem = os_zalloc(rnr_len);
616 		if (!rnr_elem)
617 			goto fail;
618 
619 		rnr_elem_offset = os_calloc(elem_count + 1, sizeof(u8 *));
620 		if (!rnr_elem_offset)
621 			goto fail;
622 	}
623 
624 	end = hostapd_eid_mbssid(tx_bss, elem, elem + len, WLAN_FC_STYPE_BEACON,
625 				 elem_count, elem_offset, NULL, 0, rnr_elem,
626 				 &rnr_elem_count, rnr_elem_offset, rnr_len);
627 
628 	params->mbssid_tx_iface = tx_bss->conf->iface;
629 	params->mbssid_index = hostapd_mbssid_get_bss_index(hapd);
630 	params->mbssid_elem = elem;
631 	params->mbssid_elem_len = end - elem;
632 	params->mbssid_elem_count = elem_count;
633 	params->mbssid_elem_offset = elem_offset;
634 	params->rnr_elem = rnr_elem;
635 	params->rnr_elem_len = rnr_len;
636 	params->rnr_elem_count = rnr_elem_count;
637 	params->rnr_elem_offset = rnr_elem_offset;
638 	if (iface->conf->mbssid == ENHANCED_MBSSID_ENABLED)
639 		params->ema = true;
640 
641 	return 0;
642 
643 fail:
644 	os_free(rnr_elem);
645 	os_free(rnr_elem_offset);
646 	os_free(elem_offset);
647 	os_free(elem);
648 	wpa_printf(MSG_ERROR, "MBSSID: Configuration failed");
649 	return -1;
650 }
651 
652 
hostapd_eid_mbssid_config(struct hostapd_data * hapd,u8 * eid,u8 mbssid_elem_count)653 static u8 * hostapd_eid_mbssid_config(struct hostapd_data *hapd, u8 *eid,
654 				      u8 mbssid_elem_count)
655 {
656 	struct hostapd_iface *iface = hapd->iface;
657 
658 	if (iface->conf->mbssid == ENHANCED_MBSSID_ENABLED) {
659 		*eid++ = WLAN_EID_EXTENSION;
660 		*eid++ = 3;
661 		*eid++ = WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION;
662 		*eid++ = iface->num_bss;
663 		*eid++ = mbssid_elem_count;
664 	}
665 
666 	return eid;
667 }
668 
669 
he_elem_len(struct hostapd_data * hapd)670 static size_t he_elem_len(struct hostapd_data *hapd)
671 {
672 	size_t len = 0;
673 
674 #ifdef CONFIG_IEEE80211AX
675 	if (!hapd->iconf->ieee80211ax || hapd->conf->disable_11ax)
676 		return len;
677 
678 	len += 3 + sizeof(struct ieee80211_he_capabilities) +
679 		3 + sizeof(struct ieee80211_he_operation) +
680 		3 + sizeof(struct ieee80211_he_mu_edca_parameter_set) +
681 		3 + sizeof(struct ieee80211_spatial_reuse);
682 	if (is_6ghz_op_class(hapd->iconf->op_class)) {
683 		len += sizeof(struct ieee80211_he_6ghz_oper_info) +
684 			3 + sizeof(struct ieee80211_he_6ghz_band_cap);
685 		/* An additional Transmit Power Envelope element for
686 		 * subordinate client */
687 		if (he_reg_is_indoor(hapd->iconf->he_6ghz_reg_pwr_type))
688 			len += 4;
689 
690 		/* An additional Transmit Power Envelope element for
691 		 * default client with unit interpretation of regulatory
692 		 * client EIRP */
693 		if (hapd->iconf->reg_def_cli_eirp != -1 &&
694 		    he_reg_is_sp(hapd->iconf->he_6ghz_reg_pwr_type))
695 			len += 4;
696 	}
697 #endif /* CONFIG_IEEE80211AX */
698 
699 	return len;
700 }
701 
702 
703 struct probe_resp_params {
704 	const struct ieee80211_mgmt *req;
705 	bool is_p2p;
706 
707 	/* Generated IEs will be included inside an ML element */
708 	struct hostapd_data *mld_ap;
709 	struct mld_info *mld_info;
710 
711 	struct ieee80211_mgmt *resp;
712 	size_t resp_len;
713 	u8 *csa_pos;
714 	u8 *ecsa_pos;
715 	const u8 *known_bss;
716 	u8 known_bss_len;
717 
718 #ifdef CONFIG_IEEE80211AX
719 	u8 *cca_pos;
720 #endif /* CONFIG_IEEE80211AX */
721 };
722 
723 
hostapd_free_probe_resp_params(struct probe_resp_params * params)724 static void hostapd_free_probe_resp_params(struct probe_resp_params *params)
725 {
726 #ifdef CONFIG_IEEE80211BE
727 	if (!params)
728 		return;
729 
730 	os_free(params->mld_info);
731 	params->mld_info = NULL;
732 #endif /* CONFIG_IEEE80211BE */
733 }
734 
735 
hostapd_probe_resp_elems_len(struct hostapd_data * hapd,struct probe_resp_params * params)736 static size_t hostapd_probe_resp_elems_len(struct hostapd_data *hapd,
737 					   struct probe_resp_params *params)
738 {
739 	size_t buflen = 0;
740 
741 #ifdef CONFIG_WPS
742 	if (hapd->wps_probe_resp_ie)
743 		buflen += wpabuf_len(hapd->wps_probe_resp_ie);
744 #endif /* CONFIG_WPS */
745 #ifdef CONFIG_P2P
746 	if (hapd->p2p_probe_resp_ie)
747 		buflen += wpabuf_len(hapd->p2p_probe_resp_ie);
748 #endif /* CONFIG_P2P */
749 #ifdef CONFIG_FST
750 	if (hapd->iface->fst_ies)
751 		buflen += wpabuf_len(hapd->iface->fst_ies);
752 #endif /* CONFIG_FST */
753 	if (hapd->conf->vendor_elements)
754 		buflen += wpabuf_len(hapd->conf->vendor_elements);
755 #ifdef CONFIG_TESTING_OPTIONS
756 	if (hapd->conf->presp_elements)
757 		buflen += wpabuf_len(hapd->conf->presp_elements);
758 #endif /* CONFIG_TESTING_OPTIONS */
759 	if (hapd->conf->vendor_vht) {
760 		buflen += 5 + 2 + sizeof(struct ieee80211_vht_capabilities) +
761 			2 + sizeof(struct ieee80211_vht_operation);
762 	}
763 
764 	buflen += he_elem_len(hapd);
765 
766 #ifdef CONFIG_IEEE80211BE
767 	if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
768 		struct hostapd_data *ml_elem_ap =
769 			params->mld_ap ? params->mld_ap : hapd;
770 
771 		buflen += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP);
772 		buflen += 3 + sizeof(struct ieee80211_eht_operation);
773 		if (hapd->iconf->punct_bitmap)
774 			buflen += EHT_OPER_DISABLED_SUBCHAN_BITMAP_SIZE;
775 
776 		if (ml_elem_ap->conf->mld_ap) {
777 			buflen += hostapd_eid_eht_ml_beacon_len(
778 				ml_elem_ap, params->mld_info, !!params->mld_ap);
779 
780 			/* For Max Channel Switch Time element during channel
781 			 * switch */
782 			buflen += 6;
783 		}
784 	}
785 #endif /* CONFIG_IEEE80211BE */
786 
787 	buflen += hostapd_eid_mbssid_len(hapd, WLAN_FC_STYPE_PROBE_RESP, NULL,
788 					 params->known_bss,
789 					 params->known_bss_len, NULL);
790 	buflen += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_PROBE_RESP, true);
791 	buflen += hostapd_mbo_ie_len(hapd);
792 	buflen += hostapd_eid_owe_trans_len(hapd);
793 	buflen += hostapd_eid_dpp_cc_len(hapd);
794 	buflen += hostapd_get_rsne_override_len(hapd);
795 	buflen += hostapd_get_rsne_override_2_len(hapd);
796 	buflen += hostapd_get_rsnxe_override_len(hapd);
797 
798 	return buflen;
799 }
800 
801 
hostapd_probe_resp_fill_elems(struct hostapd_data * hapd,struct probe_resp_params * params,u8 * pos,size_t len)802 static u8 * hostapd_probe_resp_fill_elems(struct hostapd_data *hapd,
803 					  struct probe_resp_params *params,
804 					  u8 *pos, size_t len)
805 {
806 	u8 *csa_pos;
807 	u8 *epos;
808 
809 	epos = pos + len;
810 
811 	*pos++ = WLAN_EID_SSID;
812 	*pos++ = hapd->conf->ssid.ssid_len;
813 	os_memcpy(pos, hapd->conf->ssid.ssid,
814 		  hapd->conf->ssid.ssid_len);
815 	pos += hapd->conf->ssid.ssid_len;
816 
817 	/* Supported rates */
818 	pos = hostapd_eid_supp_rates(hapd, pos);
819 
820 	/* DS Params */
821 	pos = hostapd_eid_ds_params(hapd, pos);
822 
823 	pos = hostapd_eid_country(hapd, pos, epos - pos);
824 
825 	/* Power Constraint element */
826 	pos = hostapd_eid_pwr_constraint(hapd, pos);
827 
828 	/* CSA element */
829 	csa_pos = hostapd_eid_csa(hapd, pos);
830 	if (csa_pos != pos)
831 		params->csa_pos = csa_pos - 1;
832 	else
833 		params->csa_pos = NULL;
834 	pos = csa_pos;
835 
836 	/* ERP Information element */
837 	pos = hostapd_eid_erp_info(hapd, pos);
838 
839 	/* Extended supported rates */
840 	pos = hostapd_eid_ext_supp_rates(hapd, pos);
841 
842 	pos = hostapd_get_rsne(hapd, pos, epos - pos);
843 	pos = hostapd_eid_bss_load(hapd, pos, epos - pos);
844 	pos = hostapd_eid_mbssid(hapd, pos, epos, WLAN_FC_STYPE_PROBE_RESP, 0,
845 				 NULL, params->known_bss, params->known_bss_len,
846 				 NULL, NULL, NULL, 0);
847 	pos = hostapd_eid_rm_enabled_capab(hapd, pos, epos - pos);
848 	pos = hostapd_get_mde(hapd, pos, epos - pos);
849 
850 	/* eCSA element */
851 	csa_pos = hostapd_eid_ecsa(hapd, pos);
852 	if (csa_pos != pos)
853 		params->ecsa_pos = csa_pos - 1;
854 	else
855 		params->ecsa_pos = NULL;
856 	pos = csa_pos;
857 
858 	pos = hostapd_eid_supported_op_classes(hapd, pos);
859 	pos = hostapd_eid_ht_capabilities(hapd, pos);
860 	pos = hostapd_eid_ht_operation(hapd, pos);
861 
862 	/* Probe Response frames always include all non-TX profiles except
863 	 * when a list of known BSSes is included in the Probe Request frame. */
864 	pos = hostapd_eid_ext_capab(hapd, pos,
865 				    hapd->iconf->mbssid >= MBSSID_ENABLED &&
866 				    !params->known_bss_len);
867 
868 	pos = hostapd_eid_time_adv(hapd, pos);
869 	pos = hostapd_eid_time_zone(hapd, pos);
870 
871 	pos = hostapd_eid_interworking(hapd, pos);
872 	pos = hostapd_eid_adv_proto(hapd, pos);
873 	pos = hostapd_eid_roaming_consortium(hapd, pos);
874 
875 #ifdef CONFIG_FST
876 	if (hapd->iface->fst_ies) {
877 		os_memcpy(pos, wpabuf_head(hapd->iface->fst_ies),
878 			  wpabuf_len(hapd->iface->fst_ies));
879 		pos += wpabuf_len(hapd->iface->fst_ies);
880 	}
881 #endif /* CONFIG_FST */
882 
883 #ifdef CONFIG_IEEE80211AC
884 	if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac &&
885 	    !is_6ghz_op_class(hapd->iconf->op_class)) {
886 		pos = hostapd_eid_vht_capabilities(hapd, pos, 0);
887 		pos = hostapd_eid_vht_operation(hapd, pos);
888 		pos = hostapd_eid_txpower_envelope(hapd, pos);
889 	}
890 #endif /* CONFIG_IEEE80211AC */
891 
892 #ifdef CONFIG_IEEE80211AX
893 	if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax &&
894 	    is_6ghz_op_class(hapd->iconf->op_class))
895 		pos = hostapd_eid_txpower_envelope(hapd, pos);
896 #endif /* CONFIG_IEEE80211AX */
897 
898 	pos = hostapd_eid_chsw_wrapper(hapd, pos);
899 
900 	pos = hostapd_eid_rnr(hapd, pos, WLAN_FC_STYPE_PROBE_RESP, true);
901 	pos = hostapd_eid_fils_indic(hapd, pos, 0);
902 
903 	/* Max Channel Switch Time element */
904 	pos = hostapd_eid_max_cs_time(hapd, pos);
905 
906 	pos = hostapd_get_rsnxe(hapd, pos, epos - pos);
907 
908 #ifdef CONFIG_IEEE80211AX
909 	if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
910 		u8 *cca_pos;
911 
912 		pos = hostapd_eid_he_capab(hapd, pos, IEEE80211_MODE_AP);
913 		pos = hostapd_eid_he_operation(hapd, pos);
914 
915 		/* BSS Color Change Announcement element */
916 		cca_pos = hostapd_eid_cca(hapd, pos);
917 		if (cca_pos != pos)
918 			params->cca_pos = cca_pos - 2;
919 		else
920 			params->cca_pos = NULL;
921 		pos = cca_pos;
922 
923 		pos = hostapd_eid_spatial_reuse(hapd, pos);
924 		pos = hostapd_eid_he_mu_edca_parameter_set(hapd, pos);
925 		pos = hostapd_eid_he_6ghz_band_cap(hapd, pos);
926 	}
927 #endif /* CONFIG_IEEE80211AX */
928 
929 #ifdef CONFIG_IEEE80211BE
930 	if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
931 		struct hostapd_data *ml_elem_ap =
932 			params->mld_ap ? params->mld_ap : hapd;
933 
934 		if (ml_elem_ap->conf->mld_ap)
935 			pos = hostapd_eid_eht_ml_beacon(
936 				ml_elem_ap, params->mld_info,
937 				pos, !!params->mld_ap);
938 
939 		pos = hostapd_eid_eht_capab(hapd, pos, IEEE80211_MODE_AP);
940 		pos = hostapd_eid_eht_operation(hapd, pos);
941 	}
942 #endif /* CONFIG_IEEE80211BE */
943 
944 #ifdef CONFIG_IEEE80211AC
945 	if (hapd->conf->vendor_vht)
946 		pos = hostapd_eid_vendor_vht(hapd, pos);
947 #endif /* CONFIG_IEEE80211AC */
948 
949 	/* WPA / OSEN */
950 	pos = hostapd_get_wpa_ie(hapd, pos, epos - pos);
951 	pos = hostapd_get_osen_ie(hapd, pos, epos - pos);
952 
953 	/* Wi-Fi Alliance WMM */
954 	pos = hostapd_eid_wmm(hapd, pos);
955 
956 #ifdef CONFIG_WPS
957 	if (hapd->conf->wps_state && hapd->wps_probe_resp_ie) {
958 		os_memcpy(pos, wpabuf_head(hapd->wps_probe_resp_ie),
959 			  wpabuf_len(hapd->wps_probe_resp_ie));
960 		pos += wpabuf_len(hapd->wps_probe_resp_ie);
961 	}
962 #endif /* CONFIG_WPS */
963 
964 #ifdef CONFIG_P2P
965 	if ((hapd->conf->p2p & P2P_ENABLED) && params->is_p2p &&
966 	    hapd->p2p_probe_resp_ie) {
967 		os_memcpy(pos, wpabuf_head(hapd->p2p_probe_resp_ie),
968 			  wpabuf_len(hapd->p2p_probe_resp_ie));
969 		pos += wpabuf_len(hapd->p2p_probe_resp_ie);
970 	}
971 #endif /* CONFIG_P2P */
972 #ifdef CONFIG_P2P_MANAGER
973 	if ((hapd->conf->p2p & (P2P_MANAGE | P2P_ENABLED | P2P_GROUP_OWNER)) ==
974 	    P2P_MANAGE)
975 		pos = hostapd_eid_p2p_manage(hapd, pos);
976 #endif /* CONFIG_P2P_MANAGER */
977 
978 #ifdef CONFIG_HS20
979 	pos = hostapd_eid_hs20_indication(hapd, pos);
980 #endif /* CONFIG_HS20 */
981 
982 	pos = hostapd_eid_mbo(hapd, pos, epos - pos);
983 	pos = hostapd_eid_owe_trans(hapd, pos, epos - pos);
984 	pos = hostapd_eid_dpp_cc(hapd, pos, epos - pos);
985 
986 	pos = hostapd_get_rsne_override(hapd, pos, epos - pos);
987 	pos = hostapd_get_rsne_override_2(hapd, pos, epos - pos);
988 	pos = hostapd_get_rsnxe_override(hapd, pos, epos - pos);
989 
990 	if (hapd->conf->vendor_elements) {
991 		os_memcpy(pos, wpabuf_head(hapd->conf->vendor_elements),
992 			  wpabuf_len(hapd->conf->vendor_elements));
993 		pos += wpabuf_len(hapd->conf->vendor_elements);
994 	}
995 
996 #ifdef CONFIG_TESTING_OPTIONS
997 	if (hapd->conf->presp_elements) {
998 		os_memcpy(pos, wpabuf_head(hapd->conf->presp_elements),
999 			  wpabuf_len(hapd->conf->presp_elements));
1000 		pos += wpabuf_len(hapd->conf->presp_elements);
1001 	}
1002 #endif /* CONFIG_TESTING_OPTIONS */
1003 
1004 	return pos;
1005 }
1006 
1007 
hostapd_gen_probe_resp(struct hostapd_data * hapd,struct probe_resp_params * params)1008 static void hostapd_gen_probe_resp(struct hostapd_data *hapd,
1009 				   struct probe_resp_params *params)
1010 {
1011 	u8 *pos;
1012 	size_t buflen;
1013 
1014 	hapd = hostapd_mbssid_get_tx_bss(hapd);
1015 
1016 #define MAX_PROBERESP_LEN 768
1017 	buflen = MAX_PROBERESP_LEN;
1018 	buflen += hostapd_probe_resp_elems_len(hapd, params);
1019 	params->resp = os_zalloc(buflen);
1020 	if (!params->resp) {
1021 		params->resp_len = 0;
1022 		return;
1023 	}
1024 
1025 	params->resp->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
1026 						   WLAN_FC_STYPE_PROBE_RESP);
1027 	/* Unicast the response to all requests on bands other than 6 GHz. For
1028 	 * the 6 GHz, unicast is used only if the actual SSID is not included in
1029 	 * the Beacon frames. Otherwise, broadcast response is used per IEEE
1030 	 * Std 802.11ax-2021, 26.17.2.3.2. Broadcast address is also used for
1031 	 * the Probe Response frame template for the unsolicited (i.e., not as
1032 	 * a response to a specific request) case. */
1033 	if (params->req && (!is_6ghz_op_class(hapd->iconf->op_class) ||
1034 		    hapd->conf->ignore_broadcast_ssid))
1035 		os_memcpy(params->resp->da, params->req->sa, ETH_ALEN);
1036 	else
1037 		os_memset(params->resp->da, 0xff, ETH_ALEN);
1038 	os_memcpy(params->resp->sa, hapd->own_addr, ETH_ALEN);
1039 
1040 	os_memcpy(params->resp->bssid, hapd->own_addr, ETH_ALEN);
1041 	params->resp->u.probe_resp.beacon_int =
1042 		host_to_le16(hapd->iconf->beacon_int);
1043 
1044 	/* hardware or low-level driver will setup seq_ctrl and timestamp */
1045 	params->resp->u.probe_resp.capab_info =
1046 		host_to_le16(hostapd_own_capab_info(hapd));
1047 
1048 	pos = hostapd_probe_resp_fill_elems(hapd, params,
1049 					    params->resp->u.probe_resp.variable,
1050 					    buflen);
1051 
1052 	params->resp_len = pos - (u8 *) params->resp;
1053 }
1054 
1055 
1056 #ifdef CONFIG_IEEE80211BE
hostapd_fill_probe_resp_ml_params(struct hostapd_data * hapd,struct probe_resp_params * params,const struct ieee80211_mgmt * mgmt,int mld_id,u16 links)1057 static void hostapd_fill_probe_resp_ml_params(struct hostapd_data *hapd,
1058 					      struct probe_resp_params *params,
1059 					      const struct ieee80211_mgmt *mgmt,
1060 					      int mld_id, u16 links)
1061 {
1062 	struct hostapd_data *link;
1063 
1064 	params->mld_ap = NULL;
1065 	params->mld_info = os_zalloc(sizeof(*params->mld_info));
1066 	if (!params->mld_info)
1067 		return;
1068 
1069 	wpa_printf(MSG_DEBUG,
1070 		   "MLD: Got ML probe request with AP MLD ID %d for links %04x",
1071 		   mld_id, links);
1072 
1073 	for_each_mld_link(link, hapd) {
1074 		struct mld_link_info *link_info;
1075 		u8 mld_link_id = link->mld_link_id;
1076 
1077 		/*
1078 		 * Set mld_ap iff the ML probe request explicitly
1079 		 * requested a specific MLD ID. In that case, the targeted
1080 		 * AP may have been a nontransmitted BSSID on the same
1081 		 * interface.
1082 		 */
1083 		if (mld_id != -1 && link->iface == hapd->iface)
1084 			params->mld_ap = link;
1085 
1086 		/* Never duplicate main Probe Response frame body */
1087 		if (link == hapd)
1088 			continue;
1089 
1090 		/* Only include requested links */
1091 		if (!(BIT(mld_link_id) & links))
1092 			continue;
1093 
1094 		link_info = &params->mld_info->links[mld_link_id];
1095 		os_memcpy(link_info, &hapd->partner_links[mld_link_id],
1096 			  sizeof(hapd->partner_links[mld_link_id]));
1097 
1098 		wpa_printf(MSG_DEBUG,
1099 			   "MLD: ML probe response includes link STA info for %d: %u bytes",
1100 			   mld_link_id, link_info->resp_sta_profile_len);
1101 	}
1102 
1103 	if (mld_id != -1 && !params->mld_ap) {
1104 		wpa_printf(MSG_DEBUG,
1105 			   "MLD: No nontransmitted BSSID for MLD ID %d",
1106 			   mld_id);
1107 		goto fail;
1108 	}
1109 
1110 	return;
1111 
1112 fail:
1113 	hostapd_free_probe_resp_params(params);
1114 	params->mld_ap = NULL;
1115 	params->mld_info = NULL;
1116 }
1117 #endif /* CONFIG_IEEE80211BE */
1118 
1119 
1120 enum ssid_match_result {
1121 	NO_SSID_MATCH,
1122 	EXACT_SSID_MATCH,
1123 	WILDCARD_SSID_MATCH,
1124 	CO_LOCATED_SSID_MATCH,
1125 };
1126 
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)1127 static enum ssid_match_result ssid_match(struct hostapd_data *hapd,
1128 					 const u8 *ssid, size_t ssid_len,
1129 					 const u8 *ssid_list,
1130 					 size_t ssid_list_len,
1131 					 const u8 *short_ssid_list,
1132 					 size_t short_ssid_list_len)
1133 {
1134 	const u8 *pos, *end;
1135 	struct hostapd_iface *iface = hapd->iface;
1136 	int wildcard = 0;
1137 	size_t i, j;
1138 
1139 	if (ssid_len == 0)
1140 		wildcard = 1;
1141 	if (ssid_len == hapd->conf->ssid.ssid_len &&
1142 	    os_memcmp(ssid, hapd->conf->ssid.ssid, ssid_len) == 0)
1143 		return EXACT_SSID_MATCH;
1144 
1145 	if (ssid_list) {
1146 		pos = ssid_list;
1147 		end = ssid_list + ssid_list_len;
1148 		while (end - pos >= 2) {
1149 			if (2 + pos[1] > end - pos)
1150 				break;
1151 			if (pos[1] == 0)
1152 				wildcard = 1;
1153 			if (pos[1] == hapd->conf->ssid.ssid_len &&
1154 			    os_memcmp(pos + 2, hapd->conf->ssid.ssid,
1155 				      pos[1]) == 0)
1156 				return EXACT_SSID_MATCH;
1157 			pos += 2 + pos[1];
1158 		}
1159 	}
1160 
1161 	if (short_ssid_list) {
1162 		pos = short_ssid_list;
1163 		end = short_ssid_list + short_ssid_list_len;
1164 		while (end - pos >= 4) {
1165 			if (hapd->conf->ssid.short_ssid == WPA_GET_LE32(pos))
1166 				return EXACT_SSID_MATCH;
1167 			pos += 4;
1168 		}
1169 	}
1170 
1171 	if (wildcard)
1172 		return WILDCARD_SSID_MATCH;
1173 
1174 	if (!iface->interfaces || iface->interfaces->count <= 1 ||
1175 	    is_6ghz_op_class(hapd->iconf->op_class))
1176 		return NO_SSID_MATCH;
1177 
1178 	for (i = 0; i < iface->interfaces->count; i++) {
1179 		struct hostapd_iface *colocated;
1180 
1181 		colocated = iface->interfaces->iface[i];
1182 
1183 		if (colocated == iface ||
1184 		    !is_6ghz_op_class(colocated->conf->op_class))
1185 			continue;
1186 
1187 		for (j = 0; j < colocated->num_bss; j++) {
1188 			struct hostapd_bss_config *conf;
1189 
1190 			conf = colocated->bss[j]->conf;
1191 			if (ssid_len == conf->ssid.ssid_len &&
1192 			    os_memcmp(ssid, conf->ssid.ssid, ssid_len) == 0)
1193 				return CO_LOCATED_SSID_MATCH;
1194 		}
1195 	}
1196 
1197 	return NO_SSID_MATCH;
1198 }
1199 
1200 
sta_track_expire(struct hostapd_iface * iface,int force)1201 void sta_track_expire(struct hostapd_iface *iface, int force)
1202 {
1203 	struct os_reltime now;
1204 	struct hostapd_sta_info *info;
1205 
1206 	if (!iface->num_sta_seen)
1207 		return;
1208 
1209 	os_get_reltime(&now);
1210 	while ((info = dl_list_first(&iface->sta_seen, struct hostapd_sta_info,
1211 				     list))) {
1212 		if (!force &&
1213 		    !os_reltime_expired(&now, &info->last_seen,
1214 					iface->conf->track_sta_max_age))
1215 			break;
1216 		force = 0;
1217 
1218 		wpa_printf(MSG_MSGDUMP, "%s: Expire STA tracking entry for "
1219 			   MACSTR, iface->bss[0]->conf->iface,
1220 			   MAC2STR(info->addr));
1221 		dl_list_del(&info->list);
1222 		iface->num_sta_seen--;
1223 		sta_track_del(info);
1224 	}
1225 }
1226 
1227 
sta_track_get(struct hostapd_iface * iface,const u8 * addr)1228 static struct hostapd_sta_info * sta_track_get(struct hostapd_iface *iface,
1229 					       const u8 *addr)
1230 {
1231 	struct hostapd_sta_info *info;
1232 
1233 	dl_list_for_each(info, &iface->sta_seen, struct hostapd_sta_info, list)
1234 		if (ether_addr_equal(addr, info->addr))
1235 			return info;
1236 
1237 	return NULL;
1238 }
1239 
1240 
sta_track_add(struct hostapd_iface * iface,const u8 * addr,int ssi_signal)1241 void sta_track_add(struct hostapd_iface *iface, const u8 *addr, int ssi_signal)
1242 {
1243 	struct hostapd_sta_info *info;
1244 
1245 	info = sta_track_get(iface, addr);
1246 	if (info) {
1247 		/* Move the most recent entry to the end of the list */
1248 		dl_list_del(&info->list);
1249 		dl_list_add_tail(&iface->sta_seen, &info->list);
1250 		os_get_reltime(&info->last_seen);
1251 		info->ssi_signal = ssi_signal;
1252 		return;
1253 	}
1254 
1255 	/* Add a new entry */
1256 	info = os_zalloc(sizeof(*info));
1257 	if (info == NULL)
1258 		return;
1259 	os_memcpy(info->addr, addr, ETH_ALEN);
1260 	os_get_reltime(&info->last_seen);
1261 	info->ssi_signal = ssi_signal;
1262 
1263 	if (iface->num_sta_seen >= iface->conf->track_sta_max_num) {
1264 		/* Expire oldest entry to make room for a new one */
1265 		sta_track_expire(iface, 1);
1266 	}
1267 
1268 	wpa_printf(MSG_MSGDUMP, "%s: Add STA tracking entry for "
1269 		   MACSTR, iface->bss[0]->conf->iface, MAC2STR(addr));
1270 	dl_list_add_tail(&iface->sta_seen, &info->list);
1271 	iface->num_sta_seen++;
1272 }
1273 
1274 
1275 struct hostapd_data *
sta_track_seen_on(struct hostapd_iface * iface,const u8 * addr,const char * ifname)1276 sta_track_seen_on(struct hostapd_iface *iface, const u8 *addr,
1277 		  const char *ifname)
1278 {
1279 	struct hapd_interfaces *interfaces = iface->interfaces;
1280 	size_t i, j;
1281 
1282 	for (i = 0; i < interfaces->count; i++) {
1283 		struct hostapd_data *hapd = NULL;
1284 
1285 		iface = interfaces->iface[i];
1286 		for (j = 0; j < iface->num_bss; j++) {
1287 			hapd = iface->bss[j];
1288 			if (os_strcmp(ifname, hapd->conf->iface) == 0)
1289 				break;
1290 			hapd = NULL;
1291 		}
1292 
1293 		if (hapd && sta_track_get(iface, addr))
1294 			return hapd;
1295 	}
1296 
1297 	return NULL;
1298 }
1299 
1300 
1301 #ifdef CONFIG_TAXONOMY
sta_track_claim_taxonomy_info(struct hostapd_iface * iface,const u8 * addr,struct wpabuf ** probe_ie_taxonomy)1302 void sta_track_claim_taxonomy_info(struct hostapd_iface *iface, const u8 *addr,
1303 				   struct wpabuf **probe_ie_taxonomy)
1304 {
1305 	struct hostapd_sta_info *info;
1306 
1307 	info = sta_track_get(iface, addr);
1308 	if (!info)
1309 		return;
1310 
1311 	wpabuf_free(*probe_ie_taxonomy);
1312 	*probe_ie_taxonomy = info->probe_ie_taxonomy;
1313 	info->probe_ie_taxonomy = NULL;
1314 }
1315 #endif /* CONFIG_TAXONOMY */
1316 
1317 
1318 #ifdef CONFIG_IEEE80211BE
parse_ml_probe_req(const struct ieee80211_eht_ml * ml,size_t ml_len,int * mld_id,u16 * links)1319 static bool parse_ml_probe_req(const struct ieee80211_eht_ml *ml, size_t ml_len,
1320 			       int *mld_id, u16 *links)
1321 {
1322 	u16 ml_control;
1323 	const struct element *sub;
1324 	const u8 *pos;
1325 	size_t len;
1326 
1327 	*mld_id = -1;
1328 	*links = 0xffff;
1329 
1330 	if (ml_len < sizeof(struct ieee80211_eht_ml))
1331 		return false;
1332 
1333 	ml_control = le_to_host16(ml->ml_control);
1334 	if ((ml_control & MULTI_LINK_CONTROL_TYPE_MASK) !=
1335 	    MULTI_LINK_CONTROL_TYPE_PROBE_REQ) {
1336 		wpa_printf(MSG_DEBUG, "MLD: Not an ML probe req");
1337 		return false;
1338 	}
1339 
1340 	if (sizeof(struct ieee80211_eht_ml) + 1 > ml_len) {
1341 		wpa_printf(MSG_DEBUG, "MLD: ML probe req too short");
1342 		return false;
1343 	}
1344 
1345 	pos = ml->variable;
1346 	len = pos[0];
1347 	if (len < 1 || sizeof(struct ieee80211_eht_ml) + len > ml_len) {
1348 		wpa_printf(MSG_DEBUG,
1349 			   "MLD: ML probe request with invalid length");
1350 		return false;
1351 	}
1352 
1353 	if (ml_control & EHT_ML_PRES_BM_PROBE_REQ_AP_MLD_ID) {
1354 		if (len < 2) {
1355 			wpa_printf(MSG_DEBUG,
1356 				   "MLD: ML probe req too short for MLD ID");
1357 			return false;
1358 		}
1359 
1360 		*mld_id = pos[1];
1361 	}
1362 	pos += len;
1363 
1364 	/* Parse subelements (if there are any) */
1365 	len = ml_len - len - sizeof(struct ieee80211_eht_ml);
1366 	for_each_element_id(sub, 0, pos, len) {
1367 		const struct ieee80211_eht_per_sta_profile *sta;
1368 		u16 sta_control;
1369 
1370 		if (*links == 0xffff)
1371 			*links = 0;
1372 
1373 		if (sub->datalen <
1374 		    sizeof(struct ieee80211_eht_per_sta_profile)) {
1375 			wpa_printf(MSG_DEBUG,
1376 				   "MLD: ML probe req %d too short for sta profile",
1377 				   sub->datalen);
1378 			return false;
1379 		}
1380 
1381 		sta = (struct ieee80211_eht_per_sta_profile *) sub->data;
1382 
1383 		/*
1384 		 * Extract the link ID, do not return whether a complete or
1385 		 * partial profile was requested.
1386 		 */
1387 		sta_control = le_to_host16(sta->sta_control);
1388 		*links |= BIT(sta_control & EHT_PER_STA_CTRL_LINK_ID_MSK);
1389 	}
1390 
1391 	if (!for_each_element_completed(sub, pos, len)) {
1392 		wpa_printf(MSG_DEBUG,
1393 			   "MLD: ML probe req sub-elements parsing error");
1394 		return false;
1395 	}
1396 
1397 	return true;
1398 }
1399 #endif /* CONFIG_IEEE80211BE */
1400 
1401 
handle_probe_req(struct hostapd_data * hapd,const struct ieee80211_mgmt * mgmt,size_t len,int ssi_signal)1402 void handle_probe_req(struct hostapd_data *hapd,
1403 		      const struct ieee80211_mgmt *mgmt, size_t len,
1404 		      int ssi_signal)
1405 {
1406 	struct ieee802_11_elems elems;
1407 	const u8 *ie;
1408 	size_t ie_len;
1409 	size_t i;
1410 	int noack;
1411 	enum ssid_match_result res;
1412 	int ret;
1413 	u16 csa_offs[2];
1414 	size_t csa_offs_len;
1415 	struct radius_sta rad_info;
1416 	struct probe_resp_params params;
1417 #ifdef CONFIG_IEEE80211BE
1418 	int mld_id;
1419 	u16 links;
1420 #endif /* CONFIG_IEEE80211BE */
1421 
1422 	if (hapd->iconf->rssi_ignore_probe_request && ssi_signal &&
1423 	    ssi_signal < hapd->iconf->rssi_ignore_probe_request)
1424 		return;
1425 
1426 	if (len < IEEE80211_HDRLEN)
1427 		return;
1428 	ie = ((const u8 *) mgmt) + IEEE80211_HDRLEN;
1429 	if (hapd->iconf->track_sta_max_num)
1430 		sta_track_add(hapd->iface, mgmt->sa, ssi_signal);
1431 	ie_len = len - IEEE80211_HDRLEN;
1432 
1433 	ret = hostapd_allowed_address(hapd, mgmt->sa, (const u8 *) mgmt, len,
1434 				      &rad_info, 1);
1435 	if (ret == HOSTAPD_ACL_REJECT) {
1436 		wpa_msg(hapd->msg_ctx, MSG_DEBUG,
1437 			"Ignore Probe Request frame from " MACSTR
1438 			" due to ACL reject ", MAC2STR(mgmt->sa));
1439 		return;
1440 	}
1441 
1442 	for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++)
1443 		if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx,
1444 					    mgmt->sa, mgmt->da, mgmt->bssid,
1445 					    ie, ie_len, ssi_signal) > 0)
1446 			return;
1447 
1448 	if (!hapd->conf->send_probe_response)
1449 		return;
1450 
1451 	if (ieee802_11_parse_elems(ie, ie_len, &elems, 0) == ParseFailed) {
1452 		wpa_printf(MSG_DEBUG, "Could not parse ProbeReq from " MACSTR,
1453 			   MAC2STR(mgmt->sa));
1454 		return;
1455 	}
1456 
1457 	if ((!elems.ssid || !elems.supp_rates)) {
1458 		wpa_printf(MSG_DEBUG, "STA " MACSTR " sent probe request "
1459 			   "without SSID or supported rates element",
1460 			   MAC2STR(mgmt->sa));
1461 		return;
1462 	}
1463 
1464 	/*
1465 	 * No need to reply if the Probe Request frame was sent on an adjacent
1466 	 * channel. IEEE Std 802.11-2012 describes this as a requirement for an
1467 	 * AP with dot11RadioMeasurementActivated set to true, but strictly
1468 	 * speaking does not allow such ignoring of Probe Request frames if
1469 	 * dot11RadioMeasurementActivated is false. Anyway, this can help reduce
1470 	 * number of unnecessary Probe Response frames for cases where the STA
1471 	 * is less likely to see them (Probe Request frame sent on a
1472 	 * neighboring, but partially overlapping, channel).
1473 	 */
1474 	if (elems.ds_params &&
1475 	    hapd->iface->current_mode &&
1476 	    (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G ||
1477 	     hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211B) &&
1478 	    hapd->iconf->channel != elems.ds_params[0]) {
1479 		wpa_printf(MSG_DEBUG,
1480 			   "Ignore Probe Request due to DS Params mismatch: chan=%u != ds.chan=%u",
1481 			   hapd->iconf->channel, elems.ds_params[0]);
1482 		return;
1483 	}
1484 
1485 #ifdef CONFIG_P2P
1486 	if (hapd->p2p && hapd->p2p_group && elems.wps_ie) {
1487 		struct wpabuf *wps;
1488 		wps = ieee802_11_vendor_ie_concat(ie, ie_len, WPS_DEV_OUI_WFA);
1489 		if (wps && !p2p_group_match_dev_type(hapd->p2p_group, wps)) {
1490 			wpa_printf(MSG_MSGDUMP, "P2P: Ignore Probe Request "
1491 				   "due to mismatch with Requested Device "
1492 				   "Type");
1493 			wpabuf_free(wps);
1494 			return;
1495 		}
1496 		wpabuf_free(wps);
1497 	}
1498 
1499 	if (hapd->p2p && hapd->p2p_group && elems.p2p) {
1500 		struct wpabuf *p2p;
1501 		p2p = ieee802_11_vendor_ie_concat(ie, ie_len, P2P_IE_VENDOR_TYPE);
1502 		if (p2p && !p2p_group_match_dev_id(hapd->p2p_group, p2p)) {
1503 			wpa_printf(MSG_MSGDUMP, "P2P: Ignore Probe Request "
1504 				   "due to mismatch with Device ID");
1505 			wpabuf_free(p2p);
1506 			return;
1507 		}
1508 		wpabuf_free(p2p);
1509 	}
1510 #endif /* CONFIG_P2P */
1511 
1512 	if (hapd->conf->ignore_broadcast_ssid && elems.ssid_len == 0 &&
1513 	    elems.ssid_list_len == 0 && elems.short_ssid_list_len == 0) {
1514 		wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR " for "
1515 			   "broadcast SSID ignored", MAC2STR(mgmt->sa));
1516 		return;
1517 	}
1518 
1519 #ifdef CONFIG_P2P
1520 	if ((hapd->conf->p2p & P2P_GROUP_OWNER) &&
1521 	    elems.ssid_len == P2P_WILDCARD_SSID_LEN &&
1522 	    os_memcmp(elems.ssid, P2P_WILDCARD_SSID,
1523 		      P2P_WILDCARD_SSID_LEN) == 0) {
1524 		/* Process P2P Wildcard SSID like Wildcard SSID */
1525 		elems.ssid_len = 0;
1526 	}
1527 #endif /* CONFIG_P2P */
1528 
1529 #ifdef CONFIG_TAXONOMY
1530 	{
1531 		struct sta_info *sta;
1532 		struct hostapd_sta_info *info;
1533 
1534 		if ((sta = ap_get_sta(hapd, mgmt->sa)) != NULL) {
1535 			taxonomy_sta_info_probe_req(hapd, sta, ie, ie_len);
1536 		} else if ((info = sta_track_get(hapd->iface,
1537 						 mgmt->sa)) != NULL) {
1538 			taxonomy_hostapd_sta_info_probe_req(hapd, info,
1539 							    ie, ie_len);
1540 		}
1541 	}
1542 #endif /* CONFIG_TAXONOMY */
1543 
1544 	res = ssid_match(hapd, elems.ssid, elems.ssid_len,
1545 			 elems.ssid_list, elems.ssid_list_len,
1546 			 elems.short_ssid_list, elems.short_ssid_list_len);
1547 	if (res == NO_SSID_MATCH) {
1548 		if (!(mgmt->da[0] & 0x01)) {
1549 			wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
1550 				   " for foreign SSID '%s' (DA " MACSTR ")%s",
1551 				   MAC2STR(mgmt->sa),
1552 				   wpa_ssid_txt(elems.ssid, elems.ssid_len),
1553 				   MAC2STR(mgmt->da),
1554 				   elems.ssid_list ? " (SSID list)" : "");
1555 		}
1556 		return;
1557 	}
1558 
1559 	if (hapd->conf->ignore_broadcast_ssid && res == WILDCARD_SSID_MATCH) {
1560 		wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR " for "
1561 			   "broadcast SSID ignored", MAC2STR(mgmt->sa));
1562 		return;
1563 	}
1564 
1565 #ifdef CONFIG_INTERWORKING
1566 	if (hapd->conf->interworking &&
1567 	    elems.interworking && elems.interworking_len >= 1) {
1568 		u8 ant = elems.interworking[0] & 0x0f;
1569 		if (ant != INTERWORKING_ANT_WILDCARD &&
1570 		    ant != hapd->conf->access_network_type) {
1571 			wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
1572 				   " for mismatching ANT %u ignored",
1573 				   MAC2STR(mgmt->sa), ant);
1574 			return;
1575 		}
1576 	}
1577 
1578 	if (hapd->conf->interworking && elems.interworking &&
1579 	    (elems.interworking_len == 7 || elems.interworking_len == 9)) {
1580 		const u8 *hessid;
1581 		if (elems.interworking_len == 7)
1582 			hessid = elems.interworking + 1;
1583 		else
1584 			hessid = elems.interworking + 1 + 2;
1585 		if (!is_broadcast_ether_addr(hessid) &&
1586 		    !ether_addr_equal(hessid, hapd->conf->hessid)) {
1587 			wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
1588 				   " for mismatching HESSID " MACSTR
1589 				   " ignored",
1590 				   MAC2STR(mgmt->sa), MAC2STR(hessid));
1591 			return;
1592 		}
1593 	}
1594 #endif /* CONFIG_INTERWORKING */
1595 
1596 #ifdef CONFIG_P2P
1597 	if ((hapd->conf->p2p & P2P_GROUP_OWNER) &&
1598 	    supp_rates_11b_only(&elems)) {
1599 		/* Indicates support for 11b rates only */
1600 		wpa_printf(MSG_EXCESSIVE, "P2P: Ignore Probe Request from "
1601 			   MACSTR " with only 802.11b rates",
1602 			   MAC2STR(mgmt->sa));
1603 		return;
1604 	}
1605 #endif /* CONFIG_P2P */
1606 
1607 	/* TODO: verify that supp_rates contains at least one matching rate
1608 	 * with AP configuration */
1609 
1610 	if (hapd->conf->no_probe_resp_if_seen_on &&
1611 	    is_multicast_ether_addr(mgmt->da) &&
1612 	    is_multicast_ether_addr(mgmt->bssid) &&
1613 	    sta_track_seen_on(hapd->iface, mgmt->sa,
1614 			      hapd->conf->no_probe_resp_if_seen_on)) {
1615 		wpa_printf(MSG_MSGDUMP, "%s: Ignore Probe Request from " MACSTR
1616 			   " since STA has been seen on %s",
1617 			   hapd->conf->iface, MAC2STR(mgmt->sa),
1618 			   hapd->conf->no_probe_resp_if_seen_on);
1619 		return;
1620 	}
1621 
1622 	if (hapd->conf->no_probe_resp_if_max_sta &&
1623 	    is_multicast_ether_addr(mgmt->da) &&
1624 	    is_multicast_ether_addr(mgmt->bssid) &&
1625 	    hapd->num_sta >= hapd->conf->max_num_sta &&
1626 	    !ap_get_sta(hapd, mgmt->sa)) {
1627 		wpa_printf(MSG_MSGDUMP, "%s: Ignore Probe Request from " MACSTR
1628 			   " since no room for additional STA",
1629 			   hapd->conf->iface, MAC2STR(mgmt->sa));
1630 		return;
1631 	}
1632 
1633 #ifdef CONFIG_TESTING_OPTIONS
1634 	if (hapd->iconf->ignore_probe_probability > 0.0 &&
1635 	    drand48() < hapd->iconf->ignore_probe_probability) {
1636 		wpa_printf(MSG_INFO,
1637 			   "TESTING: ignoring probe request from " MACSTR,
1638 			   MAC2STR(mgmt->sa));
1639 		return;
1640 	}
1641 #endif /* CONFIG_TESTING_OPTIONS */
1642 
1643 	/* Do not send Probe Response frame from a non-transmitting multiple
1644 	 * BSSID profile unless the Probe Request frame is directed at that
1645 	 * particular BSS. */
1646 	if (hapd != hostapd_mbssid_get_tx_bss(hapd) && res != EXACT_SSID_MATCH)
1647 		return;
1648 
1649 	wpa_msg_ctrl(hapd->msg_ctx, MSG_INFO, RX_PROBE_REQUEST "sa=" MACSTR
1650 		     " signal=%d", MAC2STR(mgmt->sa), ssi_signal);
1651 
1652 	os_memset(&params, 0, sizeof(params));
1653 
1654 #ifdef CONFIG_IEEE80211BE
1655 	if (hapd->conf->mld_ap && elems.probe_req_mle &&
1656 	    parse_ml_probe_req((struct ieee80211_eht_ml *) elems.probe_req_mle,
1657 			       elems.probe_req_mle_len, &mld_id, &links)) {
1658 		hostapd_fill_probe_resp_ml_params(hapd, &params, mgmt,
1659 						  mld_id, links);
1660 	}
1661 #endif /* CONFIG_IEEE80211BE */
1662 
1663 	params.req = mgmt;
1664 	params.is_p2p = !!elems.p2p;
1665 	params.known_bss = elems.mbssid_known_bss;
1666 	params.known_bss_len = elems.mbssid_known_bss_len;
1667 
1668 	hostapd_gen_probe_resp(hapd, &params);
1669 
1670 	hostapd_free_probe_resp_params(&params);
1671 
1672 	if (!params.resp)
1673 		return;
1674 
1675 	/*
1676 	 * If this is a broadcast probe request, apply no ack policy to avoid
1677 	 * excessive retries.
1678 	 */
1679 	noack = !!(res == WILDCARD_SSID_MATCH &&
1680 		   is_broadcast_ether_addr(mgmt->da));
1681 
1682 	csa_offs_len = 0;
1683 	if (hapd->csa_in_progress) {
1684 		if (params.csa_pos)
1685 			csa_offs[csa_offs_len++] =
1686 				params.csa_pos - (u8 *) params.resp;
1687 
1688 		if (params.ecsa_pos)
1689 			csa_offs[csa_offs_len++] =
1690 				params.ecsa_pos - (u8 *) params.resp;
1691 	}
1692 
1693 	ret = hostapd_drv_send_mlme(hapd, params.resp, params.resp_len, noack,
1694 				    csa_offs_len ? csa_offs : NULL,
1695 				    csa_offs_len, 0);
1696 
1697 	if (ret < 0)
1698 		wpa_printf(MSG_INFO, "handle_probe_req: send failed");
1699 
1700 	os_free(params.resp);
1701 
1702 	wpa_printf(MSG_EXCESSIVE, "STA " MACSTR " sent probe request for %s "
1703 		   "SSID", MAC2STR(mgmt->sa),
1704 		   elems.ssid_len == 0 ? "broadcast" : "our");
1705 }
1706 
1707 
hostapd_probe_resp_offloads(struct hostapd_data * hapd,size_t * resp_len)1708 static u8 * hostapd_probe_resp_offloads(struct hostapd_data *hapd,
1709 					size_t *resp_len)
1710 {
1711 	struct probe_resp_params params;
1712 
1713 	/* check probe response offloading caps and print warnings */
1714 	if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_PROBE_RESP_OFFLOAD))
1715 		return NULL;
1716 
1717 #ifdef CONFIG_WPS
1718 	if (hapd->conf->wps_state && hapd->wps_probe_resp_ie &&
1719 	    (!(hapd->iface->probe_resp_offloads &
1720 	       (WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS |
1721 		WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS2))))
1722 		wpa_printf(MSG_WARNING, "Device is trying to offload WPS "
1723 			   "Probe Response while not supporting this");
1724 #endif /* CONFIG_WPS */
1725 
1726 #ifdef CONFIG_P2P
1727 	if ((hapd->conf->p2p & P2P_ENABLED) && hapd->p2p_probe_resp_ie &&
1728 	    !(hapd->iface->probe_resp_offloads &
1729 	      WPA_DRIVER_PROBE_RESP_OFFLOAD_P2P))
1730 		wpa_printf(MSG_WARNING, "Device is trying to offload P2P "
1731 			   "Probe Response while not supporting this");
1732 #endif  /* CONFIG_P2P */
1733 
1734 	if (hapd->conf->interworking &&
1735 	    !(hapd->iface->probe_resp_offloads &
1736 	      WPA_DRIVER_PROBE_RESP_OFFLOAD_INTERWORKING))
1737 		wpa_printf(MSG_WARNING, "Device is trying to offload "
1738 			   "Interworking Probe Response while not supporting "
1739 			   "this");
1740 
1741 	/* Generate a Probe Response template for the non-P2P case */
1742 	os_memset(&params, 0, sizeof(params));
1743 	params.req = NULL;
1744 	params.is_p2p = false;
1745 	params.known_bss = NULL;
1746 	params.known_bss_len = 0;
1747 	params.mld_ap = NULL;
1748 	params.mld_info = NULL;
1749 
1750 	hostapd_gen_probe_resp(hapd, &params);
1751 	*resp_len = params.resp_len;
1752 	if (!params.resp)
1753 		return NULL;
1754 
1755 	/* TODO: Avoid passing these through struct hostapd_data */
1756 	if (params.csa_pos)
1757 		hapd->cs_c_off_proberesp = params.csa_pos - (u8 *) params.resp;
1758 	if (params.ecsa_pos)
1759 		hapd->cs_c_off_ecsa_proberesp = params.ecsa_pos -
1760 			(u8 *) params.resp;
1761 #ifdef CONFIG_IEEE80211AX
1762 	if (params.cca_pos)
1763 		hapd->cca_c_off_proberesp = params.cca_pos - (u8 *) params.resp;
1764 #endif /* CONFIG_IEEE80211AX */
1765 
1766 	return (u8 *) params.resp;
1767 }
1768 
1769 #endif /* NEED_AP_MLME */
1770 
1771 
1772 #ifdef CONFIG_IEEE80211AX
1773 /* Unsolicited broadcast Probe Response transmission, 6 GHz only */
hostapd_unsol_bcast_probe_resp(struct hostapd_data * hapd,struct unsol_bcast_probe_resp * ubpr)1774 u8 * hostapd_unsol_bcast_probe_resp(struct hostapd_data *hapd,
1775 				    struct unsol_bcast_probe_resp *ubpr)
1776 {
1777 	struct probe_resp_params probe_params;
1778 
1779 	if (!is_6ghz_op_class(hapd->iconf->op_class))
1780 		return NULL;
1781 
1782 	ubpr->unsol_bcast_probe_resp_interval =
1783 		hapd->conf->unsol_bcast_probe_resp_interval;
1784 
1785 	os_memset(&probe_params, 0, sizeof(probe_params));
1786 	probe_params.req = NULL;
1787 	probe_params.is_p2p = false;
1788 	probe_params.known_bss = NULL;
1789 	probe_params.known_bss_len = 0;
1790 	probe_params.mld_ap = NULL;
1791 	probe_params.mld_info = NULL;
1792 
1793 	hostapd_gen_probe_resp(hapd, &probe_params);
1794 	ubpr->unsol_bcast_probe_resp_tmpl_len = probe_params.resp_len;
1795 	return (u8 *) probe_params.resp;
1796 }
1797 #endif /* CONFIG_IEEE80211AX */
1798 
1799 
sta_track_del(struct hostapd_sta_info * info)1800 void sta_track_del(struct hostapd_sta_info *info)
1801 {
1802 #ifdef CONFIG_TAXONOMY
1803 	wpabuf_free(info->probe_ie_taxonomy);
1804 	info->probe_ie_taxonomy = NULL;
1805 #endif /* CONFIG_TAXONOMY */
1806 	os_free(info);
1807 }
1808 
1809 
1810 #ifdef CONFIG_FILS
1811 
hostapd_gen_fils_discovery_phy_index(struct hostapd_data * hapd)1812 static u16 hostapd_gen_fils_discovery_phy_index(struct hostapd_data *hapd)
1813 {
1814 #ifdef CONFIG_IEEE80211BE
1815 	if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be)
1816 		return FD_CAP_PHY_INDEX_EHT;
1817 #endif /* CONFIG_IEEE80211BE */
1818 
1819 #ifdef CONFIG_IEEE80211AX
1820 	if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax)
1821 		return FD_CAP_PHY_INDEX_HE;
1822 #endif /* CONFIG_IEEE80211AX */
1823 
1824 #ifdef CONFIG_IEEE80211AC
1825 	if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac)
1826 		return FD_CAP_PHY_INDEX_VHT;
1827 #endif /* CONFIG_IEEE80211AC */
1828 
1829 	if (hapd->iconf->ieee80211n && !hapd->conf->disable_11n)
1830 		return FD_CAP_PHY_INDEX_HT;
1831 
1832 	return 0;
1833 }
1834 
1835 
hostapd_gen_fils_discovery_nss(struct hostapd_hw_modes * mode,u16 phy_index,u8 he_mcs_nss_size)1836 static u16 hostapd_gen_fils_discovery_nss(struct hostapd_hw_modes *mode,
1837 					  u16 phy_index, u8 he_mcs_nss_size)
1838 {
1839 	u16 nss = 0;
1840 
1841 	if (!mode)
1842 		return 0;
1843 
1844 	if (phy_index == FD_CAP_PHY_INDEX_HE) {
1845 		const u8 *he_mcs = mode->he_capab[IEEE80211_MODE_AP].mcs;
1846 		int i;
1847 		u16 mcs[6];
1848 
1849 		os_memset(mcs, 0xff, 6 * sizeof(u16));
1850 
1851 		if (he_mcs_nss_size == 4) {
1852 			mcs[0] = WPA_GET_LE16(&he_mcs[0]);
1853 			mcs[1] = WPA_GET_LE16(&he_mcs[2]);
1854 		}
1855 
1856 		if (he_mcs_nss_size == 8) {
1857 			mcs[2] = WPA_GET_LE16(&he_mcs[4]);
1858 			mcs[3] = WPA_GET_LE16(&he_mcs[6]);
1859 		}
1860 
1861 		if (he_mcs_nss_size == 12) {
1862 			mcs[4] = WPA_GET_LE16(&he_mcs[8]);
1863 			mcs[5] = WPA_GET_LE16(&he_mcs[10]);
1864 		}
1865 
1866 		for (i = 0; i < HE_NSS_MAX_STREAMS; i++) {
1867 			u16 nss_mask = 0x3 << (i * 2);
1868 
1869 			/*
1870 			 * If Tx and/or Rx indicate support for a given NSS,
1871 			 * count it towards the maximum NSS.
1872 			 */
1873 			if (he_mcs_nss_size == 4 &&
1874 			    (((mcs[0] & nss_mask) != nss_mask) ||
1875 			     ((mcs[1] & nss_mask) != nss_mask))) {
1876 				nss++;
1877 				continue;
1878 			}
1879 
1880 			if (he_mcs_nss_size == 8 &&
1881 			    (((mcs[2] & nss_mask) != nss_mask) ||
1882 			     ((mcs[3] & nss_mask) != nss_mask))) {
1883 				nss++;
1884 				continue;
1885 			}
1886 
1887 			if (he_mcs_nss_size == 12 &&
1888 			    (((mcs[4] & nss_mask) != nss_mask) ||
1889 			     ((mcs[5] & nss_mask) != nss_mask))) {
1890 				nss++;
1891 				continue;
1892 			}
1893 		}
1894 	} else if (phy_index == FD_CAP_PHY_INDEX_EHT) {
1895 		u8 rx_nss, tx_nss, max_nss = 0, i;
1896 		u8 *mcs = mode->eht_capab[IEEE80211_MODE_AP].mcs;
1897 
1898 		/*
1899 		 * The Supported EHT-MCS And NSS Set field for the AP contains
1900 		 * one to three EHT-MCS Map fields based on the supported
1901 		 * bandwidth. Check the first byte (max NSS for Rx/Tx that
1902 		 * supports EHT-MCS 0-9) for each bandwidth (<= 80,
1903 		 * 160, 320) to find the maximum NSS. This assumes that
1904 		 * the lowest MCS rates support the largest number of spatial
1905 		 * streams. If values are different between Tx, Rx or the
1906 		 * bandwidths, choose the highest value.
1907 		 */
1908 		for (i = 0; i < 3; i++) {
1909 			rx_nss = mcs[3 * i] & 0x0F;
1910 			if (rx_nss > max_nss)
1911 				max_nss = rx_nss;
1912 
1913 			tx_nss = (mcs[3 * i] & 0xF0) >> 4;
1914 			if (tx_nss > max_nss)
1915 				max_nss = tx_nss;
1916 		}
1917 
1918 		nss = max_nss;
1919 	}
1920 
1921 	if (nss > 4)
1922 		return FD_CAP_NSS_5_8 << FD_CAP_NSS_SHIFT;
1923 	if (nss)
1924 		return (nss - 1) << FD_CAP_NSS_SHIFT;
1925 
1926 	return 0;
1927 }
1928 
1929 
hostapd_fils_discovery_cap(struct hostapd_data * hapd)1930 static u16 hostapd_fils_discovery_cap(struct hostapd_data *hapd)
1931 {
1932 	u16 cap_info, phy_index;
1933 	u8 chwidth = FD_CAP_BSS_CHWIDTH_20, he_mcs_nss_size = 4;
1934 	struct hostapd_hw_modes *mode = hapd->iface->current_mode;
1935 
1936 	cap_info = FD_CAP_ESS;
1937 	if (hapd->conf->wpa)
1938 		cap_info |= FD_CAP_PRIVACY;
1939 
1940 	if (is_6ghz_op_class(hapd->iconf->op_class)) {
1941 		switch (hapd->iconf->op_class) {
1942 		case 137:
1943 			chwidth = FD_CAP_BSS_CHWIDTH_320;
1944 			break;
1945 		case 135:
1946 			he_mcs_nss_size += 4;
1947 			/* fallthrough */
1948 		case 134:
1949 			he_mcs_nss_size += 4;
1950 			chwidth = FD_CAP_BSS_CHWIDTH_160_80_80;
1951 			break;
1952 		case 133:
1953 			chwidth = FD_CAP_BSS_CHWIDTH_80;
1954 			break;
1955 		case 132:
1956 			chwidth = FD_CAP_BSS_CHWIDTH_40;
1957 			break;
1958 		}
1959 	} else {
1960 		switch (hostapd_get_oper_chwidth(hapd->iconf)) {
1961 		case CONF_OPER_CHWIDTH_80P80MHZ:
1962 			he_mcs_nss_size += 4;
1963 			/* fallthrough */
1964 		case CONF_OPER_CHWIDTH_160MHZ:
1965 			he_mcs_nss_size += 4;
1966 			chwidth = FD_CAP_BSS_CHWIDTH_160_80_80;
1967 			break;
1968 		case CONF_OPER_CHWIDTH_80MHZ:
1969 			chwidth = FD_CAP_BSS_CHWIDTH_80;
1970 			break;
1971 		case CONF_OPER_CHWIDTH_USE_HT:
1972 			if (hapd->iconf->secondary_channel)
1973 				chwidth = FD_CAP_BSS_CHWIDTH_40;
1974 			else
1975 				chwidth = FD_CAP_BSS_CHWIDTH_20;
1976 			break;
1977 		default:
1978 			break;
1979 		}
1980 	}
1981 
1982 	phy_index = hostapd_gen_fils_discovery_phy_index(hapd);
1983 	cap_info |= phy_index << FD_CAP_PHY_INDEX_SHIFT;
1984 	cap_info |= chwidth << FD_CAP_BSS_CHWIDTH_SHIFT;
1985 	cap_info |= hostapd_gen_fils_discovery_nss(mode, phy_index,
1986 						   he_mcs_nss_size);
1987 	return cap_info;
1988 }
1989 
1990 
hostapd_gen_fils_discovery(struct hostapd_data * hapd,size_t * len)1991 static u8 * hostapd_gen_fils_discovery(struct hostapd_data *hapd, size_t *len)
1992 {
1993 	struct ieee80211_mgmt *head;
1994 	const u8 *mobility_domain;
1995 	u8 *pos, *length_pos, buf[200];
1996 	u16 ctl = 0;
1997 	u8 fd_rsn_info[5];
1998 	size_t total_len, buf_len;
1999 
2000 	total_len = 24 + 2 + 12;
2001 
2002 	/* FILS Discovery Frame Control */
2003 	ctl = (sizeof(hapd->conf->ssid.short_ssid) - 1) |
2004 		FD_FRAME_CTL_SHORT_SSID_PRESENT |
2005 		FD_FRAME_CTL_LENGTH_PRESENT |
2006 		FD_FRAME_CTL_CAP_PRESENT;
2007 	total_len += 4 + 1 + 2;
2008 
2009 	/* Fill primary channel information for 6 GHz channels with over 20 MHz
2010 	 * bandwidth, if the primary channel is not a PSC */
2011 	if (is_6ghz_op_class(hapd->iconf->op_class) &&
2012 	    !is_6ghz_psc_frequency(ieee80211_chan_to_freq(
2013 					   NULL, hapd->iconf->op_class,
2014 					   hapd->iconf->channel)) &&
2015 	    op_class_to_bandwidth(hapd->iconf->op_class) > 20) {
2016 		ctl |= FD_FRAME_CTL_PRI_CHAN_PRESENT;
2017 		total_len += 2;
2018 	}
2019 
2020 	/* Check for optional subfields and calculate length */
2021 	if (wpa_auth_write_fd_rsn_info(hapd->wpa_auth, fd_rsn_info)) {
2022 		ctl |= FD_FRAME_CTL_RSN_INFO_PRESENT;
2023 		total_len += sizeof(fd_rsn_info);
2024 	}
2025 
2026 	mobility_domain = hostapd_wpa_ie(hapd, WLAN_EID_MOBILITY_DOMAIN);
2027 	if (mobility_domain) {
2028 		ctl |= FD_FRAME_CTL_MD_PRESENT;
2029 		total_len += 3;
2030 	}
2031 
2032 	total_len += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_ACTION, true);
2033 
2034 	pos = hostapd_eid_fils_indic(hapd, buf, 0);
2035 	buf_len = pos - buf;
2036 	total_len += buf_len;
2037 
2038 	/* he_elem_len() may return too large a value for FD frame, but that is
2039 	 * fine here since this is used as the maximum length of the buffer. */
2040 	total_len += he_elem_len(hapd);
2041 
2042 	head = os_zalloc(total_len);
2043 	if (!head)
2044 		return NULL;
2045 
2046 	head->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
2047 					   WLAN_FC_STYPE_ACTION);
2048 	os_memset(head->da, 0xff, ETH_ALEN);
2049 	os_memcpy(head->sa, hapd->own_addr, ETH_ALEN);
2050 	os_memcpy(head->bssid, hapd->own_addr, ETH_ALEN);
2051 
2052 	head->u.action.category = WLAN_ACTION_PUBLIC;
2053 	head->u.action.u.public_action.action = WLAN_PA_FILS_DISCOVERY;
2054 
2055 	pos = &head->u.action.u.public_action.variable[0];
2056 
2057 	/* FILS Discovery Information field */
2058 
2059 	/* FILS Discovery Frame Control */
2060 	WPA_PUT_LE16(pos, ctl);
2061 	pos += 2;
2062 
2063 	/* Hardware or low-level driver will fill in the Timestamp value */
2064 	pos += 8;
2065 
2066 	/* Beacon Interval */
2067 	WPA_PUT_LE16(pos, hapd->iconf->beacon_int);
2068 	pos += 2;
2069 
2070 	/* Short SSID */
2071 	WPA_PUT_LE32(pos, hapd->conf->ssid.short_ssid);
2072 	pos += sizeof(hapd->conf->ssid.short_ssid);
2073 
2074 	/* Store position of FILS discovery information element Length field */
2075 	length_pos = pos++;
2076 
2077 	/* FD Capability */
2078 	WPA_PUT_LE16(pos, hostapd_fils_discovery_cap(hapd));
2079 	pos += 2;
2080 
2081 	/* Operating Class and Primary Channel - if a 6 GHz chan is non PSC */
2082 	if (ctl & FD_FRAME_CTL_PRI_CHAN_PRESENT) {
2083 		*pos++ = hapd->iconf->op_class;
2084 		*pos++ = hapd->iconf->channel;
2085 	}
2086 
2087 	/* AP Configuration Sequence Number - not present */
2088 
2089 	/* Access Network Options - not present */
2090 
2091 	/* FD RSN Information */
2092 	if (ctl & FD_FRAME_CTL_RSN_INFO_PRESENT) {
2093 		os_memcpy(pos, fd_rsn_info, sizeof(fd_rsn_info));
2094 		pos += sizeof(fd_rsn_info);
2095 	}
2096 
2097 	/* Channel Center Frequency Segment 1 - not present */
2098 
2099 	/* Mobility Domain */
2100 	if (ctl & FD_FRAME_CTL_MD_PRESENT) {
2101 		os_memcpy(pos, &mobility_domain[2], 3);
2102 		pos += 3;
2103 	}
2104 
2105 	/* Fill in the Length field value */
2106 	*length_pos = pos - (length_pos + 1);
2107 
2108 	pos = hostapd_eid_rnr(hapd, pos, WLAN_FC_STYPE_ACTION, true);
2109 
2110 	/* FILS Indication element */
2111 	if (buf_len) {
2112 		os_memcpy(pos, buf, buf_len);
2113 		pos += buf_len;
2114 	}
2115 
2116 	if (is_6ghz_op_class(hapd->iconf->op_class))
2117 		pos = hostapd_eid_txpower_envelope(hapd, pos);
2118 
2119 	*len = pos - (u8 *) head;
2120 	wpa_hexdump(MSG_DEBUG, "FILS Discovery frame template",
2121 		    head, pos - (u8 *) head);
2122 	return (u8 *) head;
2123 }
2124 
2125 
2126 /* Configure FILS Discovery frame transmission parameters */
hostapd_fils_discovery(struct hostapd_data * hapd,struct wpa_driver_ap_params * params)2127 static u8 * hostapd_fils_discovery(struct hostapd_data *hapd,
2128 				   struct wpa_driver_ap_params *params)
2129 {
2130 	params->fd_max_int = hapd->conf->fils_discovery_max_int;
2131 	if (is_6ghz_op_class(hapd->iconf->op_class) &&
2132 	    params->fd_max_int > FD_MAX_INTERVAL_6GHZ)
2133 		params->fd_max_int = FD_MAX_INTERVAL_6GHZ;
2134 
2135 	params->fd_min_int = hapd->conf->fils_discovery_min_int;
2136 	if (params->fd_min_int > params->fd_max_int)
2137 		params->fd_min_int = params->fd_max_int;
2138 
2139 	if (params->fd_max_int)
2140 		return hostapd_gen_fils_discovery(hapd,
2141 						  &params->fd_frame_tmpl_len);
2142 
2143 	return NULL;
2144 }
2145 
2146 #endif /* CONFIG_FILS */
2147 
2148 
ieee802_11_build_ap_params(struct hostapd_data * hapd,struct wpa_driver_ap_params * params)2149 int ieee802_11_build_ap_params(struct hostapd_data *hapd,
2150 			       struct wpa_driver_ap_params *params)
2151 {
2152 	struct ieee80211_mgmt *head = NULL;
2153 	u8 *tail = NULL;
2154 	size_t head_len = 0, tail_len = 0;
2155 	u8 *resp = NULL;
2156 	size_t resp_len = 0;
2157 #ifdef NEED_AP_MLME
2158 	u16 capab_info;
2159 	u8 *pos, *tailpos, *tailend, *csa_pos;
2160 	bool complete = false;
2161 #endif /* NEED_AP_MLME */
2162 
2163 	os_memset(params, 0, sizeof(*params));
2164 
2165 #ifdef NEED_AP_MLME
2166 #define BEACON_HEAD_BUF_SIZE 256
2167 #define BEACON_TAIL_BUF_SIZE 1500
2168 	head = os_zalloc(BEACON_HEAD_BUF_SIZE);
2169 	tail_len = BEACON_TAIL_BUF_SIZE;
2170 #ifdef CONFIG_WPS
2171 	if (hapd->conf->wps_state && hapd->wps_beacon_ie)
2172 		tail_len += wpabuf_len(hapd->wps_beacon_ie);
2173 #endif /* CONFIG_WPS */
2174 #ifdef CONFIG_P2P
2175 	if (hapd->p2p_beacon_ie)
2176 		tail_len += wpabuf_len(hapd->p2p_beacon_ie);
2177 #endif /* CONFIG_P2P */
2178 #ifdef CONFIG_FST
2179 	if (hapd->iface->fst_ies)
2180 		tail_len += wpabuf_len(hapd->iface->fst_ies);
2181 #endif /* CONFIG_FST */
2182 	if (hapd->conf->vendor_elements)
2183 		tail_len += wpabuf_len(hapd->conf->vendor_elements);
2184 
2185 #ifdef CONFIG_IEEE80211AC
2186 	if (hapd->conf->vendor_vht) {
2187 		tail_len += 5 + 2 + sizeof(struct ieee80211_vht_capabilities) +
2188 			2 + sizeof(struct ieee80211_vht_operation);
2189 	}
2190 #endif /* CONFIG_IEEE80211AC */
2191 
2192 	tail_len += he_elem_len(hapd);
2193 
2194 #ifdef CONFIG_IEEE80211BE
2195 	if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
2196 		tail_len += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP);
2197 		tail_len += 3 + sizeof(struct ieee80211_eht_operation);
2198 		if (hapd->iconf->punct_bitmap)
2199 			tail_len += EHT_OPER_DISABLED_SUBCHAN_BITMAP_SIZE;
2200 
2201 		/*
2202 		 * TODO: Multi-Link element has variable length and can be
2203 		 * long based on the common info and number of per
2204 		 * station profiles. For now use 256.
2205 		 */
2206 		if (hapd->conf->mld_ap) {
2207 			tail_len += 256;
2208 
2209 			/* for Max Channel Switch Time element during channel
2210 			 * switch */
2211 			tail_len += 6;
2212 		}
2213 	}
2214 #endif /* CONFIG_IEEE80211BE */
2215 
2216 	if (hapd->iconf->mbssid == ENHANCED_MBSSID_ENABLED &&
2217 	    hapd == hostapd_mbssid_get_tx_bss(hapd))
2218 		tail_len += 5; /* Multiple BSSID Configuration element */
2219 	tail_len += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_BEACON, true);
2220 	tail_len += hostapd_mbo_ie_len(hapd);
2221 	tail_len += hostapd_eid_owe_trans_len(hapd);
2222 	tail_len += hostapd_eid_dpp_cc_len(hapd);
2223 	tail_len += hostapd_get_rsne_override_len(hapd);
2224 	tail_len += hostapd_get_rsne_override_2_len(hapd);
2225 	tail_len += hostapd_get_rsnxe_override_len(hapd);
2226 
2227 	tailpos = tail = os_malloc(tail_len);
2228 	if (head == NULL || tail == NULL) {
2229 		wpa_printf(MSG_ERROR, "Failed to set beacon data");
2230 		os_free(head);
2231 		os_free(tail);
2232 		return -1;
2233 	}
2234 	tailend = tail + tail_len;
2235 
2236 	head->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
2237 					   WLAN_FC_STYPE_BEACON);
2238 	head->duration = host_to_le16(0);
2239 	os_memset(head->da, 0xff, ETH_ALEN);
2240 
2241 	os_memcpy(head->sa, hapd->own_addr, ETH_ALEN);
2242 	os_memcpy(head->bssid, hapd->own_addr, ETH_ALEN);
2243 	head->u.beacon.beacon_int =
2244 		host_to_le16(hapd->iconf->beacon_int);
2245 
2246 	/* hardware or low-level driver will setup seq_ctrl and timestamp */
2247 	capab_info = hostapd_own_capab_info(hapd);
2248 	head->u.beacon.capab_info = host_to_le16(capab_info);
2249 	pos = &head->u.beacon.variable[0];
2250 
2251 	/* SSID */
2252 	*pos++ = WLAN_EID_SSID;
2253 	if (hapd->conf->ignore_broadcast_ssid == 2) {
2254 		/* clear the data, but keep the correct length of the SSID */
2255 		*pos++ = hapd->conf->ssid.ssid_len;
2256 		os_memset(pos, 0, hapd->conf->ssid.ssid_len);
2257 		pos += hapd->conf->ssid.ssid_len;
2258 	} else if (hapd->conf->ignore_broadcast_ssid) {
2259 		*pos++ = 0; /* empty SSID */
2260 	} else {
2261 		*pos++ = hapd->conf->ssid.ssid_len;
2262 		os_memcpy(pos, hapd->conf->ssid.ssid,
2263 			  hapd->conf->ssid.ssid_len);
2264 		pos += hapd->conf->ssid.ssid_len;
2265 	}
2266 
2267 	/* Supported rates */
2268 	pos = hostapd_eid_supp_rates(hapd, pos);
2269 
2270 	/* DS Params */
2271 	pos = hostapd_eid_ds_params(hapd, pos);
2272 
2273 	head_len = pos - (u8 *) head;
2274 
2275 	tailpos = hostapd_eid_country(hapd, tailpos, tailend - tailpos);
2276 
2277 	/* Power Constraint element */
2278 	tailpos = hostapd_eid_pwr_constraint(hapd, tailpos);
2279 
2280 	/* CSA IE */
2281 	csa_pos = hostapd_eid_csa(hapd, tailpos);
2282 	if (csa_pos != tailpos)
2283 		hapd->cs_c_off_beacon = csa_pos - tail - 1;
2284 	tailpos = csa_pos;
2285 
2286 	/* ERP Information element */
2287 	tailpos = hostapd_eid_erp_info(hapd, tailpos);
2288 
2289 	/* Extended supported rates */
2290 	tailpos = hostapd_eid_ext_supp_rates(hapd, tailpos);
2291 
2292 	tailpos = hostapd_get_rsne(hapd, tailpos, tailend - tailpos);
2293 	tailpos = hostapd_eid_bss_load(hapd, tailpos, tailend - tailpos);
2294 	tailpos = hostapd_eid_rm_enabled_capab(hapd, tailpos,
2295 					       tailend - tailpos);
2296 	tailpos = hostapd_get_mde(hapd, tailpos, tailend - tailpos);
2297 
2298 	/* eCSA IE */
2299 	csa_pos = hostapd_eid_ecsa(hapd, tailpos);
2300 	if (csa_pos != tailpos)
2301 		hapd->cs_c_off_ecsa_beacon = csa_pos - tail - 1;
2302 	tailpos = csa_pos;
2303 
2304 	tailpos = hostapd_eid_supported_op_classes(hapd, tailpos);
2305 	tailpos = hostapd_eid_ht_capabilities(hapd, tailpos);
2306 	tailpos = hostapd_eid_ht_operation(hapd, tailpos);
2307 
2308 	if (hapd->iconf->mbssid && hapd->iconf->num_bss > 1) {
2309 		if (ieee802_11_build_ap_params_mbssid(hapd, params)) {
2310 			os_free(head);
2311 			os_free(tail);
2312 			wpa_printf(MSG_ERROR,
2313 				   "MBSSID: Failed to set beacon data");
2314 			return -1;
2315 		}
2316 		complete = hapd->iconf->mbssid == MBSSID_ENABLED ||
2317 			(hapd->iconf->mbssid == ENHANCED_MBSSID_ENABLED &&
2318 			 params->mbssid_elem_count == 1);
2319 	}
2320 
2321 	tailpos = hostapd_eid_ext_capab(hapd, tailpos, complete);
2322 
2323 	/*
2324 	 * TODO: Time Advertisement element should only be included in some
2325 	 * DTIM Beacon frames.
2326 	 */
2327 	tailpos = hostapd_eid_time_adv(hapd, tailpos);
2328 
2329 	tailpos = hostapd_eid_interworking(hapd, tailpos);
2330 	tailpos = hostapd_eid_adv_proto(hapd, tailpos);
2331 	tailpos = hostapd_eid_roaming_consortium(hapd, tailpos);
2332 
2333 #ifdef CONFIG_FST
2334 	if (hapd->iface->fst_ies) {
2335 		os_memcpy(tailpos, wpabuf_head(hapd->iface->fst_ies),
2336 			  wpabuf_len(hapd->iface->fst_ies));
2337 		tailpos += wpabuf_len(hapd->iface->fst_ies);
2338 	}
2339 #endif /* CONFIG_FST */
2340 
2341 #ifdef CONFIG_IEEE80211AC
2342 	if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac &&
2343 	    !is_6ghz_op_class(hapd->iconf->op_class)) {
2344 		tailpos = hostapd_eid_vht_capabilities(hapd, tailpos, 0);
2345 		tailpos = hostapd_eid_vht_operation(hapd, tailpos);
2346 		tailpos = hostapd_eid_txpower_envelope(hapd, tailpos);
2347 	}
2348 #endif /* CONFIG_IEEE80211AC */
2349 
2350 #ifdef CONFIG_IEEE80211AX
2351 	if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax &&
2352 	    is_6ghz_op_class(hapd->iconf->op_class))
2353 		tailpos = hostapd_eid_txpower_envelope(hapd, tailpos);
2354 #endif /* CONFIG_IEEE80211AX */
2355 
2356 	tailpos = hostapd_eid_chsw_wrapper(hapd, tailpos);
2357 
2358 	tailpos = hostapd_eid_rnr(hapd, tailpos, WLAN_FC_STYPE_BEACON, true);
2359 	tailpos = hostapd_eid_fils_indic(hapd, tailpos, 0);
2360 
2361 	/* Max Channel Switch Time element */
2362 	tailpos = hostapd_eid_max_cs_time(hapd, tailpos);
2363 
2364 	tailpos = hostapd_get_rsnxe(hapd, tailpos, tailend - tailpos);
2365 	tailpos = hostapd_eid_mbssid_config(hapd, tailpos,
2366 					    params->mbssid_elem_count);
2367 
2368 #ifdef CONFIG_IEEE80211AX
2369 	if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
2370 		u8 *cca_pos;
2371 
2372 		tailpos = hostapd_eid_he_capab(hapd, tailpos,
2373 					       IEEE80211_MODE_AP);
2374 		tailpos = hostapd_eid_he_operation(hapd, tailpos);
2375 
2376 		/* BSS Color Change Announcement element */
2377 		cca_pos = hostapd_eid_cca(hapd, tailpos);
2378 		if (cca_pos != tailpos)
2379 			hapd->cca_c_off_beacon = cca_pos - tail - 2;
2380 		tailpos = cca_pos;
2381 
2382 		tailpos = hostapd_eid_spatial_reuse(hapd, tailpos);
2383 		tailpos = hostapd_eid_he_mu_edca_parameter_set(hapd, tailpos);
2384 		tailpos = hostapd_eid_he_6ghz_band_cap(hapd, tailpos);
2385 	}
2386 #endif /* CONFIG_IEEE80211AX */
2387 
2388 #ifdef CONFIG_IEEE80211BE
2389 	if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
2390 		if (hapd->conf->mld_ap)
2391 			tailpos = hostapd_eid_eht_ml_beacon(hapd, NULL,
2392 							    tailpos, false);
2393 		tailpos = hostapd_eid_eht_capab(hapd, tailpos,
2394 						IEEE80211_MODE_AP);
2395 		tailpos = hostapd_eid_eht_operation(hapd, tailpos);
2396 	}
2397 #endif /* CONFIG_IEEE80211BE */
2398 
2399 #ifdef CONFIG_IEEE80211AC
2400 	if (hapd->conf->vendor_vht)
2401 		tailpos = hostapd_eid_vendor_vht(hapd, tailpos);
2402 #endif /* CONFIG_IEEE80211AC */
2403 
2404 	/* WPA / OSEN */
2405 	tailpos = hostapd_get_wpa_ie(hapd, tailpos, tailend - tailpos);
2406 	tailpos = hostapd_get_osen_ie(hapd, tailpos, tailend - tailpos);
2407 
2408 	/* Wi-Fi Alliance WMM */
2409 	tailpos = hostapd_eid_wmm(hapd, tailpos);
2410 
2411 #ifdef CONFIG_WPS
2412 	if (hapd->conf->wps_state && hapd->wps_beacon_ie) {
2413 		os_memcpy(tailpos, wpabuf_head(hapd->wps_beacon_ie),
2414 			  wpabuf_len(hapd->wps_beacon_ie));
2415 		tailpos += wpabuf_len(hapd->wps_beacon_ie);
2416 	}
2417 #endif /* CONFIG_WPS */
2418 
2419 #ifdef CONFIG_P2P
2420 	if ((hapd->conf->p2p & P2P_ENABLED) && hapd->p2p_beacon_ie) {
2421 		os_memcpy(tailpos, wpabuf_head(hapd->p2p_beacon_ie),
2422 			  wpabuf_len(hapd->p2p_beacon_ie));
2423 		tailpos += wpabuf_len(hapd->p2p_beacon_ie);
2424 	}
2425 #endif /* CONFIG_P2P */
2426 #ifdef CONFIG_P2P_MANAGER
2427 	if ((hapd->conf->p2p & (P2P_MANAGE | P2P_ENABLED | P2P_GROUP_OWNER)) ==
2428 	    P2P_MANAGE)
2429 		tailpos = hostapd_eid_p2p_manage(hapd, tailpos);
2430 #endif /* CONFIG_P2P_MANAGER */
2431 
2432 #ifdef CONFIG_HS20
2433 	tailpos = hostapd_eid_hs20_indication(hapd, tailpos);
2434 #endif /* CONFIG_HS20 */
2435 
2436 	tailpos = hostapd_eid_mbo(hapd, tailpos, tail + tail_len - tailpos);
2437 	tailpos = hostapd_eid_owe_trans(hapd, tailpos,
2438 					tail + tail_len - tailpos);
2439 	tailpos = hostapd_eid_dpp_cc(hapd, tailpos, tail + tail_len - tailpos);
2440 
2441 	tailpos = hostapd_get_rsne_override(hapd, tailpos,
2442 					    tail + tail_len - tailpos);
2443 	tailpos = hostapd_get_rsne_override_2(hapd, tailpos,
2444 					      tail + tail_len - tailpos);
2445 	tailpos = hostapd_get_rsnxe_override(hapd, tailpos,
2446 					     tail + tail_len - tailpos);
2447 
2448 	if (hapd->conf->vendor_elements) {
2449 		os_memcpy(tailpos, wpabuf_head(hapd->conf->vendor_elements),
2450 			  wpabuf_len(hapd->conf->vendor_elements));
2451 		tailpos += wpabuf_len(hapd->conf->vendor_elements);
2452 	}
2453 
2454 	tail_len = tailpos > tail ? tailpos - tail : 0;
2455 
2456 	resp = hostapd_probe_resp_offloads(hapd, &resp_len);
2457 #endif /* NEED_AP_MLME */
2458 
2459 	/* If key management offload is enabled, configure PSK to the driver. */
2460 	if (wpa_key_mgmt_wpa_psk_no_sae(hapd->conf->wpa_key_mgmt) &&
2461 	    (hapd->iface->drv_flags2 &
2462 	     WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK)) {
2463 		if (hapd->conf->ssid.wpa_psk && hapd->conf->ssid.wpa_psk_set) {
2464 			os_memcpy(params->psk, hapd->conf->ssid.wpa_psk->psk,
2465 				  PMK_LEN);
2466 			params->psk_len = PMK_LEN;
2467 		} else if (hapd->conf->ssid.wpa_passphrase &&
2468 			   pbkdf2_sha1(hapd->conf->ssid.wpa_passphrase,
2469 				       hapd->conf->ssid.ssid,
2470 				       hapd->conf->ssid.ssid_len, 4096,
2471 				       params->psk, PMK_LEN) == 0) {
2472 			params->psk_len = PMK_LEN;
2473 		}
2474 	}
2475 
2476 #ifdef CONFIG_SAE
2477 	/* If SAE offload is enabled, provide password to lower layer for
2478 	 * SAE authentication and PMK generation.
2479 	 */
2480 	if (wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt |
2481 			     hapd->conf->rsn_override_key_mgmt |
2482 			     hapd->conf->rsn_override_key_mgmt_2) &&
2483 	    (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SAE_OFFLOAD_AP)) {
2484 		if (hostapd_sae_pk_in_use(hapd->conf)) {
2485 			wpa_printf(MSG_ERROR,
2486 				   "SAE PK not supported with SAE offload");
2487 			return -1;
2488 		}
2489 
2490 		if (hostapd_sae_pw_id_in_use(hapd->conf)) {
2491 			wpa_printf(MSG_ERROR,
2492 				   "SAE Password Identifiers not supported with SAE offload");
2493 			return -1;
2494 		}
2495 
2496 		params->sae_password = sae_get_password(hapd, NULL, NULL, NULL,
2497 							NULL, NULL);
2498 		if (!params->sae_password) {
2499 			wpa_printf(MSG_ERROR, "SAE password not configured for offload");
2500 			return -1;
2501 		}
2502 	}
2503 #endif /* CONFIG_SAE */
2504 
2505 	params->head = (u8 *) head;
2506 	params->head_len = head_len;
2507 	params->tail = tail;
2508 	params->tail_len = tail_len;
2509 	params->proberesp = resp;
2510 	params->proberesp_len = resp_len;
2511 	params->dtim_period = hapd->conf->dtim_period;
2512 	params->beacon_int = hapd->iconf->beacon_int;
2513 	params->basic_rates = hapd->iface->basic_rates;
2514 	params->beacon_rate = hapd->iconf->beacon_rate;
2515 	params->rate_type = hapd->iconf->rate_type;
2516 	params->ssid = hapd->conf->ssid.ssid;
2517 	params->ssid_len = hapd->conf->ssid.ssid_len;
2518 	if ((hapd->conf->wpa & (WPA_PROTO_WPA | WPA_PROTO_RSN)) ==
2519 	    (WPA_PROTO_WPA | WPA_PROTO_RSN))
2520 		params->pairwise_ciphers = hapd->conf->wpa_pairwise |
2521 			hapd->conf->rsn_pairwise;
2522 	else if (hapd->conf->wpa & WPA_PROTO_RSN)
2523 		params->pairwise_ciphers = hapd->conf->rsn_pairwise;
2524 	else if (hapd->conf->wpa & WPA_PROTO_WPA)
2525 		params->pairwise_ciphers = hapd->conf->wpa_pairwise;
2526 	params->group_cipher = hapd->conf->wpa_group;
2527 	params->key_mgmt_suites = hapd->conf->wpa_key_mgmt |
2528 		hapd->conf->rsn_override_key_mgmt |
2529 		hapd->conf->rsn_override_key_mgmt_2;
2530 	params->auth_algs = hapd->conf->auth_algs;
2531 	params->wpa_version = hapd->conf->wpa;
2532 	params->privacy = hapd->conf->wpa;
2533 #ifdef CONFIG_WEP
2534 	params->privacy |= hapd->conf->ssid.wep.keys_set ||
2535 		(hapd->conf->ieee802_1x &&
2536 		 (hapd->conf->default_wep_key_len ||
2537 		  hapd->conf->individual_wep_key_len));
2538 #endif /* CONFIG_WEP */
2539 	switch (hapd->conf->ignore_broadcast_ssid) {
2540 	case 0:
2541 		params->hide_ssid = NO_SSID_HIDING;
2542 		break;
2543 	case 1:
2544 		params->hide_ssid = HIDDEN_SSID_ZERO_LEN;
2545 		break;
2546 	case 2:
2547 		params->hide_ssid = HIDDEN_SSID_ZERO_CONTENTS;
2548 		break;
2549 	}
2550 	params->isolate = hapd->conf->isolate;
2551 #ifdef NEED_AP_MLME
2552 	params->cts_protect = !!(ieee802_11_erp_info(hapd) &
2553 				ERP_INFO_USE_PROTECTION);
2554 	params->preamble = hapd->iface->num_sta_no_short_preamble == 0 &&
2555 		hapd->iconf->preamble == SHORT_PREAMBLE;
2556 	if (hapd->iface->current_mode &&
2557 	    hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
2558 		params->short_slot_time =
2559 			hapd->iface->num_sta_no_short_slot_time > 0 ? 0 : 1;
2560 	else
2561 		params->short_slot_time = -1;
2562 	if (!hapd->iconf->ieee80211n || hapd->conf->disable_11n)
2563 		params->ht_opmode = -1;
2564 	else
2565 		params->ht_opmode = hapd->iface->ht_op_mode;
2566 #endif /* NEED_AP_MLME */
2567 	params->interworking = hapd->conf->interworking;
2568 	if (hapd->conf->interworking &&
2569 	    !is_zero_ether_addr(hapd->conf->hessid))
2570 		params->hessid = hapd->conf->hessid;
2571 	params->access_network_type = hapd->conf->access_network_type;
2572 	params->ap_max_inactivity = hapd->conf->ap_max_inactivity;
2573 #ifdef CONFIG_P2P
2574 	params->p2p_go_ctwindow = hapd->iconf->p2p_go_ctwindow;
2575 #endif /* CONFIG_P2P */
2576 #ifdef CONFIG_HS20
2577 	params->disable_dgaf = hapd->conf->disable_dgaf;
2578 	if (hapd->conf->osen) {
2579 		params->privacy = 1;
2580 		params->osen = 1;
2581 	}
2582 #endif /* CONFIG_HS20 */
2583 	params->multicast_to_unicast = hapd->conf->multicast_to_unicast;
2584 	params->pbss = hapd->conf->pbss;
2585 
2586 	if (hapd->conf->ftm_responder) {
2587 		if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_FTM_RESPONDER) {
2588 			params->ftm_responder = 1;
2589 			params->lci = hapd->iface->conf->lci;
2590 			params->civic = hapd->iface->conf->civic;
2591 		} else {
2592 			wpa_printf(MSG_WARNING,
2593 				   "Not configuring FTM responder as the driver doesn't advertise support for it");
2594 		}
2595 	}
2596 
2597 #ifdef CONFIG_IEEE80211BE
2598 	if (hapd->conf->mld_ap && hapd->iconf->ieee80211be &&
2599 	    !hapd->conf->disable_11be) {
2600 		params->mld_ap = true;
2601 		params->mld_link_id = hapd->mld_link_id;
2602 	}
2603 #endif /* CONFIG_IEEE80211BE */
2604 
2605 	return 0;
2606 }
2607 
2608 
ieee802_11_free_ap_params(struct wpa_driver_ap_params * params)2609 void ieee802_11_free_ap_params(struct wpa_driver_ap_params *params)
2610 {
2611 	os_free(params->tail);
2612 	params->tail = NULL;
2613 	os_free(params->head);
2614 	params->head = NULL;
2615 	os_free(params->proberesp);
2616 	params->proberesp = NULL;
2617 	os_free(params->mbssid_elem);
2618 	params->mbssid_elem = NULL;
2619 	os_free(params->mbssid_elem_offset);
2620 	params->mbssid_elem_offset = NULL;
2621 	os_free(params->rnr_elem);
2622 	params->rnr_elem = NULL;
2623 	os_free(params->rnr_elem_offset);
2624 	params->rnr_elem_offset = NULL;
2625 #ifdef CONFIG_FILS
2626 	os_free(params->fd_frame_tmpl);
2627 	params->fd_frame_tmpl = NULL;
2628 #endif /* CONFIG_FILS */
2629 #ifdef CONFIG_IEEE80211AX
2630 	os_free(params->ubpr.unsol_bcast_probe_resp_tmpl);
2631 	params->ubpr.unsol_bcast_probe_resp_tmpl = NULL;
2632 #endif /* CONFIG_IEEE80211AX */
2633 	os_free(params->allowed_freqs);
2634 	params->allowed_freqs = NULL;
2635 }
2636 
2637 
__ieee802_11_set_beacon(struct hostapd_data * hapd)2638 static int __ieee802_11_set_beacon(struct hostapd_data *hapd)
2639 {
2640 	struct wpa_driver_ap_params params;
2641 	struct hostapd_freq_params freq;
2642 	struct hostapd_iface *iface = hapd->iface;
2643 	struct hostapd_config *iconf = iface->conf;
2644 	struct hostapd_hw_modes *cmode = iface->current_mode;
2645 	struct wpabuf *beacon, *proberesp, *assocresp;
2646 	bool twt_he_responder = false;
2647 	int res, ret = -1, i;
2648 	struct hostapd_hw_modes *mode;
2649 
2650 	if (!hapd->drv_priv) {
2651 		wpa_printf(MSG_ERROR, "Interface is disabled");
2652 		return -1;
2653 	}
2654 
2655 	if (hapd->csa_in_progress) {
2656 		wpa_printf(MSG_ERROR, "Cannot set beacons during CSA period");
2657 		return -1;
2658 	}
2659 
2660 	hapd->beacon_set_done = 1;
2661 
2662 	if (ieee802_11_build_ap_params(hapd, &params) < 0)
2663 		return -1;
2664 
2665 	if (hostapd_build_ap_extra_ies(hapd, &beacon, &proberesp, &assocresp) <
2666 	    0)
2667 		goto fail;
2668 
2669 	params.beacon_ies = beacon;
2670 	params.proberesp_ies = proberesp;
2671 	params.assocresp_ies = assocresp;
2672 	params.reenable = hapd->reenable_beacon;
2673 #ifdef CONFIG_IEEE80211AX
2674 	params.he_spr_ctrl = hapd->iface->conf->spr.sr_control;
2675 	params.he_spr_non_srg_obss_pd_max_offset =
2676 		hapd->iface->conf->spr.non_srg_obss_pd_max_offset;
2677 	params.he_spr_srg_obss_pd_min_offset =
2678 		hapd->iface->conf->spr.srg_obss_pd_min_offset;
2679 	params.he_spr_srg_obss_pd_max_offset =
2680 		hapd->iface->conf->spr.srg_obss_pd_max_offset;
2681 	os_memcpy(params.he_spr_bss_color_bitmap,
2682 		  hapd->iface->conf->spr.srg_bss_color_bitmap, 8);
2683 	os_memcpy(params.he_spr_partial_bssid_bitmap,
2684 		  hapd->iface->conf->spr.srg_partial_bssid_bitmap, 8);
2685 	params.he_bss_color_disabled =
2686 		hapd->iface->conf->he_op.he_bss_color_disabled;
2687 	params.he_bss_color_partial =
2688 		hapd->iface->conf->he_op.he_bss_color_partial;
2689 	params.he_bss_color = hapd->iface->conf->he_op.he_bss_color;
2690 	twt_he_responder = hostapd_get_he_twt_responder(hapd,
2691 							IEEE80211_MODE_AP);
2692 	params.ubpr.unsol_bcast_probe_resp_tmpl =
2693 		hostapd_unsol_bcast_probe_resp(hapd, &params.ubpr);
2694 #endif /* CONFIG_IEEE80211AX */
2695 	params.twt_responder =
2696 		twt_he_responder || hostapd_get_ht_vht_twt_responder(hapd);
2697 	hapd->reenable_beacon = 0;
2698 #ifdef CONFIG_SAE
2699 	params.sae_pwe = hapd->conf->sae_pwe;
2700 #endif /* CONFIG_SAE */
2701 
2702 #ifdef CONFIG_FILS
2703 	params.fd_frame_tmpl = hostapd_fils_discovery(hapd, &params);
2704 #endif /* CONFIG_FILS */
2705 
2706 #ifdef CONFIG_IEEE80211BE
2707 	params.punct_bitmap = iconf->punct_bitmap;
2708 #endif /* CONFIG_IEEE80211BE */
2709 
2710 	if (cmode &&
2711 	    hostapd_set_freq_params(&freq, iconf->hw_mode, iface->freq,
2712 				    iconf->channel, iconf->enable_edmg,
2713 				    iconf->edmg_channel, iconf->ieee80211n,
2714 				    iconf->ieee80211ac, iconf->ieee80211ax,
2715 				    iconf->ieee80211be,
2716 				    iconf->secondary_channel,
2717 				    hostapd_get_oper_chwidth(iconf),
2718 				    hostapd_get_oper_centr_freq_seg0_idx(iconf),
2719 				    hostapd_get_oper_centr_freq_seg1_idx(iconf),
2720 				    cmode->vht_capab,
2721 				    &cmode->he_capab[IEEE80211_MODE_AP],
2722 				    &cmode->eht_capab[IEEE80211_MODE_AP],
2723 				    hostapd_get_punct_bitmap(hapd)) == 0) {
2724 		freq.link_id = -1;
2725 #ifdef CONFIG_IEEE80211BE
2726 		if (hapd->conf->mld_ap)
2727 			freq.link_id = hapd->mld_link_id;
2728 #endif /* CONFIG_IEEE80211BE */
2729 		params.freq = &freq;
2730 	}
2731 
2732 	for (i = 0; i < hapd->iface->num_hw_features; i++) {
2733 		mode = &hapd->iface->hw_features[i];
2734 
2735 		if (iconf->hw_mode != HOSTAPD_MODE_IEEE80211ANY &&
2736 		    iconf->hw_mode != mode->mode)
2737 			continue;
2738 
2739 		hostapd_get_hw_mode_any_channels(hapd, mode,
2740 						 !(iconf->acs_freq_list.num ||
2741 						   iconf->acs_ch_list.num),
2742 						 true, &params.allowed_freqs);
2743 	}
2744 
2745 	res = hostapd_drv_set_ap(hapd, &params);
2746 	hostapd_free_ap_extra_ies(hapd, beacon, proberesp, assocresp);
2747 	if (res)
2748 		wpa_printf(MSG_ERROR, "Failed to set beacon parameters");
2749 	else
2750 		ret = 0;
2751 fail:
2752 	ieee802_11_free_ap_params(&params);
2753 	return ret;
2754 }
2755 
2756 
ieee802_11_set_beacon_per_bss_only(struct hostapd_data * hapd)2757 void ieee802_11_set_beacon_per_bss_only(struct hostapd_data *hapd)
2758 {
2759 	__ieee802_11_set_beacon(hapd);
2760 }
2761 
2762 
2763 #ifdef CONFIG_IEEE80211BE
2764 
hostapd_get_probe_resp_tmpl(struct hostapd_data * hapd,struct probe_resp_params * params,bool is_ml_sta_info)2765 static int hostapd_get_probe_resp_tmpl(struct hostapd_data *hapd,
2766 				       struct probe_resp_params *params,
2767 				       bool is_ml_sta_info)
2768 {
2769 	os_memset(params, 0, sizeof(*params));
2770 	hostapd_gen_probe_resp(hapd, params);
2771 	if (!params->resp)
2772 		return -1;
2773 
2774 	/* The caller takes care of freeing params->resp. */
2775 	return 0;
2776 }
2777 
2778 
is_restricted_eid_in_sta_profile(u8 eid,bool tx_vap)2779 static bool is_restricted_eid_in_sta_profile(u8 eid, bool tx_vap)
2780 {
2781 	switch (eid) {
2782 	case WLAN_EID_TIM:
2783 	case WLAN_EID_BSS_MAX_IDLE_PERIOD:
2784 	case WLAN_EID_MULTIPLE_BSSID:
2785 	case WLAN_EID_REDUCED_NEIGHBOR_REPORT:
2786 	case WLAN_EID_NEIGHBOR_REPORT:
2787 		return true;
2788 	case WLAN_EID_SSID:
2789 		/* SSID is not restricted for non-transmitted BSSID */
2790 		return tx_vap;
2791 	default:
2792 		return false;
2793 	}
2794 }
2795 
2796 
is_restricted_ext_eid_in_sta_profile(u8 ext_id)2797 static bool is_restricted_ext_eid_in_sta_profile(u8 ext_id)
2798 {
2799 	switch (ext_id) {
2800 	case WLAN_EID_EXT_MULTI_LINK:
2801 		return true;
2802 	default:
2803 		return false;
2804 	}
2805 }
2806 
2807 
2808 /* Create the link STA profiles based on inheritance from the reporting
2809  * profile.
2810  *
2811  * NOTE: The same function is used for length calculation as well as filling
2812  * data in the given buffer. This avoids risk of not updating the length
2813  * function but filling function or vice versa.
2814  */
hostapd_add_sta_profile(struct ieee80211_mgmt * link_fdata,size_t link_data_len,struct ieee80211_mgmt * own_fdata,size_t own_data_len,u8 * sta_profile,bool tx_vap)2815 static size_t hostapd_add_sta_profile(struct ieee80211_mgmt *link_fdata,
2816 				      size_t link_data_len,
2817 				      struct ieee80211_mgmt *own_fdata,
2818 				      size_t own_data_len,
2819 				      u8 *sta_profile, bool tx_vap)
2820 {
2821 	const struct element *link_elem;
2822 	size_t sta_profile_len = 0;
2823 	const u8 *link_elem_data;
2824 	u8 link_ele_len;
2825 	u8 *link_data;
2826 	const struct element *own_elem;
2827 	u8 link_eid, own_eid, own_ele_len;
2828 	const u8 *own_elem_data;
2829 	u8 *own_data;
2830 	bool is_ext;
2831 	bool ie_found;
2832 	u8 non_inherit_ele_ext_list[256] = { 0 };
2833 	u8 non_inherit_ele_ext_list_len = 0;
2834 	u8 non_inherit_ele_list[256] = { 0 };
2835 	u8 non_inherit_ele_list_len = 0;
2836 	u8 num_link_elem_vendor_ies = 0, num_own_elem_vendor_ies = 0;
2837 	bool add_vendor_ies = false, is_identical_vendor_ies = true;
2838 	/* The bitmap of parsed EIDs. There are 256 EIDs and ext EIDs, so 32
2839 	 * bytes to store the bitmaps. */
2840 	u8 parsed_eid_bmap[32] = { 0 }, parsed_ext_eid_bmap[32] = { 0 };
2841 	/* extra len used in the logic includes the element id and len */
2842 	u8 extra_len = 2;
2843 
2844 	/* Include len for capab info */
2845 	sta_profile_len += sizeof(le16);
2846 	if (sta_profile) {
2847 		os_memcpy(sta_profile, &link_fdata->u.probe_resp.capab_info,
2848 			  sizeof(le16));
2849 		sta_profile += sizeof(le16);
2850 	}
2851 
2852 	own_data = own_fdata->u.probe_resp.variable;
2853 	link_data = link_fdata->u.probe_resp.variable;
2854 
2855 	/* The below logic takes the reporting BSS data and reported BSS data
2856 	 * and performs intersection to build the STA profile of the reported
2857 	 * BSS. Certain elements are not added to the STA profile as
2858 	 * recommended in standard. Matching element information in the
2859 	 * reporting BSS profile are ignored in the STA profile. Remaining
2860 	 * elements pertaining to the STA profile are appended at the end. */
2861 	for_each_element(own_elem, own_data, own_data_len) {
2862 		is_ext = false;
2863 		ie_found = false;
2864 
2865 		/* Pick one of own elements and get its EID and length */
2866 		own_elem_data = own_elem->data;
2867 		own_ele_len = own_elem->datalen;
2868 
2869 		if (own_elem->id == WLAN_EID_EXTENSION) {
2870 			is_ext = true;
2871 			own_eid = *(own_elem_data);
2872 			if (is_restricted_ext_eid_in_sta_profile(own_eid))
2873 				continue;
2874 		} else {
2875 			own_eid = own_elem->id;
2876 			if (is_restricted_eid_in_sta_profile(own_eid, tx_vap))
2877 				continue;
2878 		}
2879 
2880 		for_each_element(link_elem, link_data, link_data_len) {
2881 			/* If the element type mismatches, do not consider
2882 			 * this link element for comparison. */
2883 			if ((link_elem->id == WLAN_EID_EXTENSION &&
2884 			     !is_ext) ||
2885 			    (is_ext && link_elem->id != WLAN_EID_EXTENSION))
2886 				continue;
2887 
2888 			/* Comparison can be done so get the link element and
2889 			 * its EID and length. */
2890 			link_elem_data = link_elem->data;
2891 			link_ele_len = link_elem->datalen;
2892 
2893 			if (link_elem->id == WLAN_EID_EXTENSION)
2894 				link_eid = *(link_elem_data);
2895 			else
2896 				link_eid = link_elem->id;
2897 
2898 			/* Ignore if EID does not match */
2899 			if (own_eid != link_eid)
2900 				continue;
2901 
2902 			ie_found = true;
2903 
2904 			/* Ignore if the contents is identical. */
2905 			if (own_ele_len == link_ele_len &&
2906 			    os_memcmp(own_elem->data, link_elem->data,
2907 				      own_ele_len) == 0) {
2908 				if (own_eid == WLAN_EID_VENDOR_SPECIFIC) {
2909 					is_identical_vendor_ies = true;
2910 					num_own_elem_vendor_ies++;
2911 				}
2912 				continue;
2913 			}
2914 
2915 			/* No need to include this non-matching Vendor Specific
2916 			 * element explicitly at this point. */
2917 			if (own_eid == WLAN_EID_VENDOR_SPECIFIC) {
2918 				is_identical_vendor_ies = false;
2919 				continue;
2920 			}
2921 
2922 			/* This element is present in the reported profile
2923 			 * as well as present in the reporting profile.
2924 			 * However, there is a mismatch in the contents and
2925 			 * hence, include this in the per STA profile. */
2926 			sta_profile_len += link_ele_len + extra_len;
2927 			if (sta_profile) {
2928 				os_memcpy(sta_profile,
2929 					  link_elem->data - extra_len,
2930 					  link_ele_len + extra_len);
2931 				sta_profile += link_ele_len + extra_len;
2932 			}
2933 
2934 			/* Update the parsed EIDs bitmap */
2935 			if (is_ext)
2936 				parsed_ext_eid_bmap[own_eid / 8] |=
2937 					BIT(own_eid % 8);
2938 			else
2939 				parsed_eid_bmap[own_eid / 8] |=
2940 					BIT(own_eid % 8);
2941 			break;
2942 		}
2943 
2944 		/* We found at least one Vendor Specific element in reporting
2945 		 * link which is not same (or present) in the reported link. We
2946 		 * need to include all Vendor Specific elements from the
2947 		 * reported link. */
2948 		if (!is_identical_vendor_ies)
2949 			add_vendor_ies = true;
2950 
2951 		/* This is a unique element in the reporting profile which is
2952 		 * not present in the reported profile. Update the
2953 		 * non-inheritance list. */
2954 		if (!ie_found) {
2955 			u8 idx;
2956 
2957 			if (is_ext) {
2958 				idx = non_inherit_ele_ext_list_len++;
2959 				non_inherit_ele_ext_list[idx] = own_eid;
2960 			} else {
2961 				idx = non_inherit_ele_list_len++;
2962 				non_inherit_ele_list[idx] = own_eid;
2963 			}
2964 		}
2965 	}
2966 
2967 	/* Parse the remaining elements in the reported profile */
2968 	for_each_element(link_elem, link_data, link_data_len) {
2969 		link_elem_data = link_elem->data;
2970 		link_ele_len = link_elem->datalen;
2971 
2972 		/* No need to check this Vendor Specific element at this point.
2973 		 * Just take the count and continue. */
2974 		if (link_elem->id == WLAN_EID_VENDOR_SPECIFIC) {
2975 			num_link_elem_vendor_ies++;
2976 			continue;
2977 		}
2978 
2979 		if (link_elem->id == WLAN_EID_EXTENSION) {
2980 			link_eid = *(link_elem_data);
2981 
2982 			if ((parsed_ext_eid_bmap[link_eid / 8] &
2983 			     BIT(link_eid % 8)) ||
2984 			    is_restricted_ext_eid_in_sta_profile(link_eid))
2985 				continue;
2986 		} else {
2987 			link_eid = link_elem->id;
2988 
2989 			if ((parsed_eid_bmap[link_eid / 8] &
2990 			     BIT(link_eid % 8)) ||
2991 			    is_restricted_eid_in_sta_profile(link_eid, tx_vap))
2992 				continue;
2993 		}
2994 
2995 		sta_profile_len += link_ele_len + extra_len;
2996 		if (sta_profile) {
2997 			os_memcpy(sta_profile, link_elem_data - extra_len,
2998 				  link_ele_len + extra_len);
2999 			sta_profile += link_ele_len + extra_len;
3000 		}
3001 	}
3002 
3003 	/* Handle Vendor Specific elements
3004 	 * Add all the Vendor Specific elements of the reported link if
3005 	 *  a. There is at least one non-matching Vendor Specific element, or
3006 	 *  b. The number of Vendor Specific elements in reporting and reported
3007 	 *     link is not same. */
3008 	if (add_vendor_ies ||
3009 	    num_own_elem_vendor_ies != num_link_elem_vendor_ies) {
3010 		for_each_element(link_elem, link_data, link_data_len) {
3011 			link_elem_data = link_elem->data;
3012 			link_ele_len = link_elem->datalen;
3013 
3014 			if (link_elem->id != WLAN_EID_VENDOR_SPECIFIC)
3015 				continue;
3016 
3017 			sta_profile_len += link_ele_len + extra_len;
3018 			if (sta_profile) {
3019 				os_memcpy(sta_profile,
3020 					  link_elem_data - extra_len,
3021 					  link_ele_len + extra_len);
3022 				sta_profile += link_ele_len + extra_len;
3023 			}
3024 		}
3025 	}
3026 
3027 	/* Handle non-inheritance
3028 	 * Non-Inheritance element:
3029 	 *      Element ID Ext: 1 octet
3030 	 *	Length: 1 octet
3031 	 *	Ext tag number: 1 octet
3032 	 *	Length of Elements ID list: 1 octet
3033 	 *	Elements ID list: variable
3034 	 *      Length of Elements ID Extension list: 1 octet
3035 	 *	Elements ID extensions list: variable
3036 	 */
3037 	if (non_inherit_ele_list_len || non_inherit_ele_ext_list_len)
3038 		sta_profile_len += 3 + 2 + non_inherit_ele_list_len +
3039 			non_inherit_ele_ext_list_len;
3040 
3041 	if (sta_profile &&
3042 	    (non_inherit_ele_list_len || non_inherit_ele_ext_list_len)) {
3043 		*sta_profile++ = WLAN_EID_EXTENSION;
3044 		*sta_profile++ = non_inherit_ele_list_len +
3045 			non_inherit_ele_ext_list_len + 3;
3046 		*sta_profile++ = WLAN_EID_EXT_NON_INHERITANCE;
3047 		*sta_profile++ = non_inherit_ele_list_len;
3048 		os_memcpy(sta_profile, non_inherit_ele_list,
3049 			  non_inherit_ele_list_len);
3050 		sta_profile += non_inherit_ele_list_len;
3051 		*sta_profile++ = non_inherit_ele_ext_list_len;
3052 		os_memcpy(sta_profile, non_inherit_ele_ext_list,
3053 			  non_inherit_ele_ext_list_len);
3054 		sta_profile += non_inherit_ele_ext_list_len;
3055 	}
3056 
3057 	return sta_profile_len;
3058 }
3059 
3060 
hostapd_gen_sta_profile(struct ieee80211_mgmt * link_data,size_t link_data_len,struct ieee80211_mgmt * own_data,size_t own_data_len,size_t * sta_profile_len,bool tx_vap)3061 static u8 * hostapd_gen_sta_profile(struct ieee80211_mgmt *link_data,
3062 				    size_t link_data_len,
3063 				    struct ieee80211_mgmt *own_data,
3064 				    size_t own_data_len,
3065 				    size_t *sta_profile_len, bool tx_vap)
3066 {
3067 	u8 *sta_profile;
3068 
3069 	/* Get the length first */
3070 	*sta_profile_len = hostapd_add_sta_profile(link_data, link_data_len,
3071 						   own_data, own_data_len,
3072 						   NULL, tx_vap);
3073 	if (!(*sta_profile_len) || *sta_profile_len > EHT_ML_MAX_STA_PROF_LEN)
3074 		return NULL;
3075 
3076 	sta_profile = os_zalloc(*sta_profile_len);
3077 	if (!sta_profile)
3078 		return NULL;
3079 
3080 	/* Now fill in the data */
3081 	hostapd_add_sta_profile(link_data, link_data_len, own_data,
3082 				own_data_len, sta_profile, tx_vap);
3083 
3084 	/* The caller takes care of freeing the returned sta_profile */
3085 	return sta_profile;
3086 }
3087 
3088 
hostapd_gen_per_sta_profiles(struct hostapd_data * hapd)3089 static void hostapd_gen_per_sta_profiles(struct hostapd_data *hapd)
3090 {
3091 	bool tx_vap = hapd == hostapd_mbssid_get_tx_bss(hapd);
3092 	size_t link_data_len, sta_profile_len;
3093 	size_t own_data_len;
3094 	struct probe_resp_params link_params;
3095 	struct probe_resp_params own_params;
3096 	struct ieee80211_mgmt *link_data;
3097 	struct ieee80211_mgmt *own_data;
3098 	struct mld_link_info *link_info;
3099 	struct hostapd_data *link_bss;
3100 	u8 link_id, *sta_profile;
3101 
3102 	if (!hapd->conf->mld_ap)
3103 		return;
3104 
3105 	wpa_printf(MSG_DEBUG, "MLD: Generating per STA profiles for MLD %s",
3106 		   hapd->conf->iface);
3107 
3108 	wpa_printf(MSG_DEBUG, "MLD: Reporting link %d", hapd->mld_link_id);
3109 
3110 	/* Generate a Probe Response template for self */
3111 	if (hostapd_get_probe_resp_tmpl(hapd, &own_params, false)) {
3112 		wpa_printf(MSG_ERROR,
3113 			   "MLD: Error in building per STA profiles");
3114 		return;
3115 	}
3116 
3117 	own_data = own_params.resp;
3118 	own_data_len = own_params.resp_len;
3119 
3120 	/* Consider the length of the variable fields */
3121 	own_data_len -= offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
3122 
3123 	for_each_mld_link(link_bss, hapd) {
3124 		if (link_bss == hapd || !link_bss->started)
3125 			continue;
3126 
3127 		link_id = link_bss->mld_link_id;
3128 		if (link_id >= MAX_NUM_MLD_LINKS)
3129 			continue;
3130 
3131 		sta_profile = NULL;
3132 		sta_profile_len = 0;
3133 
3134 		/* Generate a Probe Response frame template for partner link */
3135 		if (hostapd_get_probe_resp_tmpl(link_bss, &link_params, true)) {
3136 			wpa_printf(MSG_ERROR,
3137 				   "MLD: Could not get link STA probe response template for link %d",
3138 				   link_id);
3139 			continue;
3140 		}
3141 
3142 		link_data = link_params.resp;
3143 		link_data_len = link_params.resp_len;
3144 
3145 		/* Consider length of the variable fields */
3146 		link_data_len -= offsetof(struct ieee80211_mgmt,
3147 					  u.probe_resp.variable);
3148 
3149 		sta_profile = hostapd_gen_sta_profile(link_data, link_data_len,
3150 						      own_data, own_data_len,
3151 						      &sta_profile_len, tx_vap);
3152 		if (!sta_profile) {
3153 			wpa_printf(MSG_ERROR,
3154 				   "MLD: Could not generate link STA profile for link %d",
3155 				   link_id);
3156 			continue;
3157 		}
3158 
3159 		link_info = &hapd->partner_links[link_id];
3160 		link_info->valid = true;
3161 
3162 		os_free(link_info->resp_sta_profile);
3163 		link_info->resp_sta_profile_len = sta_profile_len;
3164 
3165 		link_info->resp_sta_profile = os_memdup(sta_profile,
3166 							sta_profile_len);
3167 		if (!link_info->resp_sta_profile)
3168 			link_info->resp_sta_profile_len = 0;
3169 
3170 		os_memcpy(link_info->local_addr, link_bss->own_addr, ETH_ALEN);
3171 
3172 		wpa_printf(MSG_DEBUG,
3173 			   "MLD: Reported link STA info for %d: %u bytes",
3174 			   link_id, link_info->resp_sta_profile_len);
3175 
3176 		os_free(sta_profile);
3177 		os_free(link_params.resp);
3178 	}
3179 
3180 	os_free(own_params.resp);
3181 }
3182 
3183 #endif /* CONFIG_IEEE80211BE */
3184 
3185 
ieee802_11_set_beacon(struct hostapd_data * hapd)3186 int ieee802_11_set_beacon(struct hostapd_data *hapd)
3187 {
3188 	struct hostapd_iface *iface = hapd->iface;
3189 	int ret;
3190 	size_t i, j;
3191 	bool is_6g, hapd_mld = false;
3192 #ifdef CONFIG_IEEE80211BE
3193 	struct hostapd_data *link_bss;
3194 #endif /* CONFIG_IEEE80211BE */
3195 
3196 	ret = __ieee802_11_set_beacon(hapd);
3197 	if (ret != 0)
3198 		return ret;
3199 
3200 	if (!iface->interfaces || iface->interfaces->count <= 1)
3201 		return 0;
3202 
3203 #ifdef CONFIG_IEEE80211BE
3204 	hapd_mld = hapd->conf->mld_ap;
3205 #endif /* CONFIG_IEEE80211BE */
3206 
3207 	/* Update Beacon frames in case of 6 GHz colocation or AP MLD */
3208 	is_6g = is_6ghz_op_class(iface->conf->op_class);
3209 	for (j = 0; j < iface->interfaces->count; j++) {
3210 		struct hostapd_iface *other;
3211 		bool other_iface_6g;
3212 
3213 		other = iface->interfaces->iface[j];
3214 		if (other == iface || !other || !other->conf)
3215 			continue;
3216 
3217 		other_iface_6g = is_6ghz_op_class(other->conf->op_class);
3218 
3219 		if (is_6g == other_iface_6g && !hapd_mld)
3220 			continue;
3221 
3222 		for (i = 0; i < other->num_bss; i++) {
3223 #ifdef CONFIG_IEEE80211BE
3224 			if (is_6g == other_iface_6g &&
3225 			    !(hapd_mld && other->bss[i]->conf->mld_ap &&
3226 			      hostapd_is_ml_partner(hapd, other->bss[i])))
3227 				continue;
3228 #endif /* CONFIG_IEEE80211BE */
3229 
3230 			if (other->bss[i] && other->bss[i]->started)
3231 				__ieee802_11_set_beacon(other->bss[i]);
3232 		}
3233 	}
3234 
3235 #ifdef CONFIG_IEEE80211BE
3236 	if (!hapd_mld)
3237 		return 0;
3238 
3239 	/* Generate per STA profiles for each affiliated APs */
3240 	for_each_mld_link(link_bss, hapd)
3241 		hostapd_gen_per_sta_profiles(link_bss);
3242 #endif /* CONFIG_IEEE80211BE */
3243 
3244 	return 0;
3245 }
3246 
3247 
ieee802_11_set_beacons(struct hostapd_iface * iface)3248 int ieee802_11_set_beacons(struct hostapd_iface *iface)
3249 {
3250 	size_t i;
3251 	int ret = 0;
3252 
3253 	for (i = 0; i < iface->num_bss; i++) {
3254 		if (iface->bss[i]->started &&
3255 		    ieee802_11_set_beacon(iface->bss[i]) < 0)
3256 			ret = -1;
3257 	}
3258 
3259 	return ret;
3260 }
3261 
3262 
3263 /* only update beacons if started */
ieee802_11_update_beacons(struct hostapd_iface * iface)3264 int ieee802_11_update_beacons(struct hostapd_iface *iface)
3265 {
3266 	size_t i;
3267 	int ret = 0;
3268 
3269 	for (i = 0; i < iface->num_bss; i++) {
3270 		if (iface->bss[i]->beacon_set_done && iface->bss[i]->started &&
3271 		    ieee802_11_set_beacon(iface->bss[i]) < 0)
3272 			ret = -1;
3273 	}
3274 
3275 	return ret;
3276 }
3277 
3278 #endif /* CONFIG_NATIVE_WINDOWS */
3279