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