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