1 /* 2 * hostapd / IEEE 802.11 Management 3 * Copyright (c) 2002-2024, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9 #include "utils/includes.h" 10 11 #include "utils/common.h" 12 #include "common/ieee802_11_defs.h" 13 #include "common/ocv.h" 14 #include "common/wpa_ctrl.h" 15 #include "hostapd.h" 16 #include "sta_info.h" 17 #include "ap_config.h" 18 #include "ap_drv_ops.h" 19 #include "wpa_auth.h" 20 #include "dpp_hostapd.h" 21 #include "ieee802_11.h" 22 23 24 static u8 * hostapd_eid_timeout_interval(u8 *pos, u8 type, u32 value) 25 { 26 *pos++ = WLAN_EID_TIMEOUT_INTERVAL; 27 *pos++ = 5; 28 *pos++ = type; 29 WPA_PUT_LE32(pos, value); 30 pos += 4; 31 32 return pos; 33 } 34 35 36 u8 * hostapd_eid_assoc_comeback_time(struct hostapd_data *hapd, 37 struct sta_info *sta, u8 *eid) 38 { 39 u32 timeout, tu; 40 struct os_reltime now, passed; 41 u8 type = WLAN_TIMEOUT_ASSOC_COMEBACK; 42 43 os_get_reltime(&now); 44 os_reltime_sub(&now, &sta->sa_query_start, &passed); 45 tu = (passed.sec * 1000000 + passed.usec) / 1024; 46 if (hapd->conf->assoc_sa_query_max_timeout > tu) 47 timeout = hapd->conf->assoc_sa_query_max_timeout - tu; 48 else 49 timeout = 0; 50 if (timeout < hapd->conf->assoc_sa_query_max_timeout) 51 timeout++; /* add some extra time for local timers */ 52 53 #ifdef CONFIG_TESTING_OPTIONS 54 if (hapd->conf->test_assoc_comeback_type != -1) 55 type = hapd->conf->test_assoc_comeback_type; 56 #endif /* CONFIG_TESTING_OPTIONS */ 57 return hostapd_eid_timeout_interval(eid, type, timeout); 58 } 59 60 61 /* MLME-SAQuery.request */ 62 void ieee802_11_send_sa_query_req(struct hostapd_data *hapd, 63 const u8 *addr, const u8 *trans_id) 64 { 65 #if defined(CONFIG_OCV) || defined(CONFIG_IEEE80211BE) 66 struct sta_info *sta = ap_get_sta(hapd, addr); 67 #endif /* CONFIG_OCV || CONFIG_IEEE80211BE */ 68 struct ieee80211_mgmt *mgmt; 69 u8 *oci_ie = NULL; 70 u8 oci_ie_len = 0; 71 u8 *end; 72 const u8 *own_addr = hapd->own_addr; 73 74 wpa_printf(MSG_DEBUG, "IEEE 802.11: Sending SA Query Request to " 75 MACSTR, MAC2STR(addr)); 76 wpa_hexdump(MSG_DEBUG, "IEEE 802.11: SA Query Transaction ID", 77 trans_id, WLAN_SA_QUERY_TR_ID_LEN); 78 79 #ifdef CONFIG_OCV 80 if (sta && wpa_auth_uses_ocv(sta->wpa_sm)) { 81 struct wpa_channel_info ci; 82 83 if (hostapd_drv_channel_info(hapd, &ci) != 0) { 84 wpa_printf(MSG_WARNING, 85 "Failed to get channel info for OCI element in SA Query Request"); 86 return; 87 } 88 #ifdef CONFIG_TESTING_OPTIONS 89 if (hapd->conf->oci_freq_override_saquery_req) { 90 wpa_printf(MSG_INFO, 91 "TEST: Override OCI frequency %d -> %u MHz", 92 ci.frequency, 93 hapd->conf->oci_freq_override_saquery_req); 94 ci.frequency = 95 hapd->conf->oci_freq_override_saquery_req; 96 } 97 #endif /* CONFIG_TESTING_OPTIONS */ 98 99 oci_ie_len = OCV_OCI_EXTENDED_LEN; 100 oci_ie = os_zalloc(oci_ie_len); 101 if (!oci_ie) { 102 wpa_printf(MSG_WARNING, 103 "Failed to allocate buffer for OCI element in SA Query Request"); 104 return; 105 } 106 107 if (ocv_insert_extended_oci(&ci, oci_ie) < 0) { 108 os_free(oci_ie); 109 return; 110 } 111 } 112 #endif /* CONFIG_OCV */ 113 114 mgmt = os_zalloc(sizeof(*mgmt) + oci_ie_len); 115 if (!mgmt) { 116 wpa_printf(MSG_DEBUG, 117 "Failed to allocate buffer for SA Query Response frame"); 118 os_free(oci_ie); 119 return; 120 } 121 122 #ifdef CONFIG_IEEE80211BE 123 if (ap_sta_is_mld(hapd, sta)) 124 own_addr = hapd->mld->mld_addr; 125 #endif /* CONFIG_IEEE80211BE */ 126 127 mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 128 WLAN_FC_STYPE_ACTION); 129 os_memcpy(mgmt->da, addr, ETH_ALEN); 130 os_memcpy(mgmt->sa, own_addr, ETH_ALEN); 131 os_memcpy(mgmt->bssid, own_addr, ETH_ALEN); 132 mgmt->u.action.category = WLAN_ACTION_SA_QUERY; 133 mgmt->u.action.u.sa_query_req.action = WLAN_SA_QUERY_REQUEST; 134 os_memcpy(mgmt->u.action.u.sa_query_req.trans_id, trans_id, 135 WLAN_SA_QUERY_TR_ID_LEN); 136 end = mgmt->u.action.u.sa_query_req.variable; 137 #ifdef CONFIG_OCV 138 if (oci_ie_len > 0) { 139 os_memcpy(end, oci_ie, oci_ie_len); 140 end += oci_ie_len; 141 } 142 #endif /* CONFIG_OCV */ 143 if (hostapd_drv_send_mlme(hapd, mgmt, end - (u8 *) mgmt, 0, NULL, 0, 0) 144 < 0) 145 wpa_printf(MSG_INFO, "ieee802_11_send_sa_query_req: send failed"); 146 147 os_free(mgmt); 148 os_free(oci_ie); 149 } 150 151 152 static void ieee802_11_send_sa_query_resp(struct hostapd_data *hapd, 153 const u8 *sa, const u8 *trans_id) 154 { 155 struct sta_info *sta; 156 struct ieee80211_mgmt *resp; 157 u8 *oci_ie = NULL; 158 u8 oci_ie_len = 0; 159 u8 *end; 160 const u8 *own_addr = hapd->own_addr; 161 162 wpa_printf(MSG_DEBUG, "IEEE 802.11: Received SA Query Request from " 163 MACSTR, MAC2STR(sa)); 164 wpa_hexdump(MSG_DEBUG, "IEEE 802.11: SA Query Transaction ID", 165 trans_id, WLAN_SA_QUERY_TR_ID_LEN); 166 167 sta = ap_get_sta(hapd, sa); 168 if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) { 169 wpa_printf(MSG_DEBUG, "IEEE 802.11: Ignore SA Query Request " 170 "from unassociated STA " MACSTR, MAC2STR(sa)); 171 return; 172 } 173 174 #ifdef CONFIG_OCV 175 if (wpa_auth_uses_ocv(sta->wpa_sm)) { 176 struct wpa_channel_info ci; 177 178 if (hostapd_drv_channel_info(hapd, &ci) != 0) { 179 wpa_printf(MSG_WARNING, 180 "Failed to get channel info for OCI element in SA Query Response"); 181 return; 182 } 183 #ifdef CONFIG_TESTING_OPTIONS 184 if (hapd->conf->oci_freq_override_saquery_resp) { 185 wpa_printf(MSG_INFO, 186 "TEST: Override OCI frequency %d -> %u MHz", 187 ci.frequency, 188 hapd->conf->oci_freq_override_saquery_resp); 189 ci.frequency = 190 hapd->conf->oci_freq_override_saquery_resp; 191 } 192 #endif /* CONFIG_TESTING_OPTIONS */ 193 194 oci_ie_len = OCV_OCI_EXTENDED_LEN; 195 oci_ie = os_zalloc(oci_ie_len); 196 if (!oci_ie) { 197 wpa_printf(MSG_WARNING, 198 "Failed to allocate buffer for for OCI element in SA Query Response"); 199 return; 200 } 201 202 if (ocv_insert_extended_oci(&ci, oci_ie) < 0) { 203 os_free(oci_ie); 204 return; 205 } 206 } 207 #endif /* CONFIG_OCV */ 208 209 resp = os_zalloc(sizeof(*resp) + oci_ie_len); 210 if (!resp) { 211 wpa_printf(MSG_DEBUG, 212 "Failed to allocate buffer for SA Query Response frame"); 213 os_free(oci_ie); 214 return; 215 } 216 217 wpa_printf(MSG_DEBUG, "IEEE 802.11: Sending SA Query Response to " 218 MACSTR, MAC2STR(sa)); 219 220 #ifdef CONFIG_IEEE80211BE 221 if (ap_sta_is_mld(hapd, sta)) 222 own_addr = hapd->mld->mld_addr; 223 #endif /* CONFIG_IEEE80211BE */ 224 225 resp->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, 226 WLAN_FC_STYPE_ACTION); 227 os_memcpy(resp->da, sa, ETH_ALEN); 228 os_memcpy(resp->sa, own_addr, ETH_ALEN); 229 os_memcpy(resp->bssid, own_addr, ETH_ALEN); 230 resp->u.action.category = WLAN_ACTION_SA_QUERY; 231 resp->u.action.u.sa_query_req.action = WLAN_SA_QUERY_RESPONSE; 232 os_memcpy(resp->u.action.u.sa_query_req.trans_id, trans_id, 233 WLAN_SA_QUERY_TR_ID_LEN); 234 end = resp->u.action.u.sa_query_req.variable; 235 #ifdef CONFIG_OCV 236 if (oci_ie_len > 0) { 237 os_memcpy(end, oci_ie, oci_ie_len); 238 end += oci_ie_len; 239 } 240 #endif /* CONFIG_OCV */ 241 if (hostapd_drv_send_mlme(hapd, resp, end - (u8 *) resp, 0, NULL, 0, 0) 242 < 0) 243 wpa_printf(MSG_INFO, "ieee80211_mgmt_sa_query_request: send failed"); 244 245 os_free(resp); 246 os_free(oci_ie); 247 } 248 249 250 void ieee802_11_sa_query_action(struct hostapd_data *hapd, 251 const struct ieee80211_mgmt *mgmt, 252 size_t len) 253 { 254 struct sta_info *sta; 255 int i; 256 const u8 *sa = mgmt->sa; 257 const u8 action_type = mgmt->u.action.u.sa_query_resp.action; 258 const u8 *trans_id = mgmt->u.action.u.sa_query_resp.trans_id; 259 260 if (((const u8 *) mgmt) + len < 261 mgmt->u.action.u.sa_query_resp.variable) { 262 wpa_printf(MSG_DEBUG, 263 "IEEE 802.11: Too short SA Query Action frame (len=%lu)", 264 (unsigned long) len); 265 return; 266 } 267 if (is_multicast_ether_addr(mgmt->da)) { 268 wpa_printf(MSG_DEBUG, 269 "IEEE 802.11: Ignore group-addressed SA Query frame (A1=" MACSTR " A2=" MACSTR ")", 270 MAC2STR(mgmt->da), MAC2STR(mgmt->sa)); 271 return; 272 } 273 274 sta = ap_get_sta(hapd, sa); 275 276 #ifdef CONFIG_OCV 277 if (sta && wpa_auth_uses_ocv(sta->wpa_sm)) { 278 struct ieee802_11_elems elems; 279 struct wpa_channel_info ci; 280 int tx_chanwidth; 281 int tx_seg1_idx; 282 size_t ies_len; 283 const u8 *ies; 284 285 ies = mgmt->u.action.u.sa_query_resp.variable; 286 ies_len = len - (ies - (u8 *) mgmt); 287 if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == 288 ParseFailed) { 289 wpa_printf(MSG_DEBUG, 290 "SA Query: Failed to parse elements"); 291 return; 292 } 293 294 if (hostapd_drv_channel_info(hapd, &ci) != 0) { 295 wpa_printf(MSG_WARNING, 296 "Failed to get channel info to validate received OCI in SA Query Action frame"); 297 return; 298 } 299 300 if (get_sta_tx_parameters(sta->wpa_sm, 301 channel_width_to_int(ci.chanwidth), 302 ci.seg1_idx, &tx_chanwidth, 303 &tx_seg1_idx) < 0) 304 return; 305 306 if (ocv_verify_tx_params(elems.oci, elems.oci_len, &ci, 307 tx_chanwidth, tx_seg1_idx) != 308 OCI_SUCCESS) { 309 wpa_msg(hapd->msg_ctx, MSG_INFO, OCV_FAILURE "addr=" 310 MACSTR " frame=saquery%s error=%s", 311 MAC2STR(sa), 312 action_type == WLAN_SA_QUERY_REQUEST ? 313 "req" : "resp", ocv_errorstr); 314 return; 315 } 316 } 317 #endif /* CONFIG_OCV */ 318 319 if (action_type == WLAN_SA_QUERY_REQUEST) { 320 if (sta) 321 sta->post_csa_sa_query = 0; 322 ieee802_11_send_sa_query_resp(hapd, sa, trans_id); 323 return; 324 } 325 326 if (action_type != WLAN_SA_QUERY_RESPONSE) { 327 wpa_printf(MSG_DEBUG, "IEEE 802.11: Unexpected SA Query " 328 "Action %d", action_type); 329 return; 330 } 331 332 wpa_printf(MSG_DEBUG, "IEEE 802.11: Received SA Query Response from " 333 MACSTR, MAC2STR(sa)); 334 wpa_hexdump(MSG_DEBUG, "IEEE 802.11: SA Query Transaction ID", 335 trans_id, WLAN_SA_QUERY_TR_ID_LEN); 336 337 /* MLME-SAQuery.confirm */ 338 339 if (sta == NULL || sta->sa_query_trans_id == NULL) { 340 wpa_printf(MSG_DEBUG, "IEEE 802.11: No matching STA with " 341 "pending SA Query request found"); 342 return; 343 } 344 345 for (i = 0; i < sta->sa_query_count; i++) { 346 if (os_memcmp(sta->sa_query_trans_id + 347 i * WLAN_SA_QUERY_TR_ID_LEN, 348 trans_id, WLAN_SA_QUERY_TR_ID_LEN) == 0) 349 break; 350 } 351 352 if (i >= sta->sa_query_count) { 353 wpa_printf(MSG_DEBUG, "IEEE 802.11: No matching SA Query " 354 "transaction identifier found"); 355 return; 356 } 357 358 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 359 HOSTAPD_LEVEL_DEBUG, 360 "Reply to pending SA Query received"); 361 ap_sta_stop_sa_query(hapd, sta); 362 } 363 364 365 static void hostapd_ext_capab_byte(struct hostapd_data *hapd, u8 *pos, int idx, 366 bool mbssid_complete) 367 { 368 *pos = 0x00; 369 370 switch (idx) { 371 case 0: /* Bits 0-7 */ 372 if (hapd->iconf->obss_interval) 373 *pos |= 0x01; /* Bit 0 - Coexistence management */ 374 if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA) 375 *pos |= 0x04; /* Bit 2 - Extended Channel Switching */ 376 break; 377 case 1: /* Bits 8-15 */ 378 if (hapd->conf->proxy_arp) 379 *pos |= 0x10; /* Bit 12 - Proxy ARP */ 380 if (hapd->conf->coloc_intf_reporting) { 381 /* Bit 13 - Collocated Interference Reporting */ 382 *pos |= 0x20; 383 } 384 break; 385 case 2: /* Bits 16-23 */ 386 if (hapd->conf->wnm_sleep_mode) 387 *pos |= 0x02; /* Bit 17 - WNM-Sleep Mode */ 388 if (hapd->conf->bss_transition) 389 *pos |= 0x08; /* Bit 19 - BSS Transition */ 390 if (hapd->iconf->mbssid) 391 *pos |= 0x40; /* Bit 22 - Multiple BSSID */ 392 break; 393 case 3: /* Bits 24-31 */ 394 #ifdef CONFIG_WNM_AP 395 *pos |= 0x02; /* Bit 25 - SSID List */ 396 #endif /* CONFIG_WNM_AP */ 397 if (hapd->conf->time_advertisement == 2) 398 *pos |= 0x08; /* Bit 27 - UTC TSF Offset */ 399 if (hapd->conf->interworking) 400 *pos |= 0x80; /* Bit 31 - Interworking */ 401 break; 402 case 4: /* Bits 32-39 */ 403 if (hapd->conf->qos_map_set_len) 404 *pos |= 0x01; /* Bit 32 - QoS Map */ 405 if (hapd->conf->tdls & TDLS_PROHIBIT) 406 *pos |= 0x40; /* Bit 38 - TDLS Prohibited */ 407 if (hapd->conf->tdls & TDLS_PROHIBIT_CHAN_SWITCH) { 408 /* Bit 39 - TDLS Channel Switching Prohibited */ 409 *pos |= 0x80; 410 } 411 break; 412 case 5: /* Bits 40-47 */ 413 #ifdef CONFIG_HS20 414 if (hapd->conf->hs20) 415 *pos |= 0x40; /* Bit 46 - WNM-Notification */ 416 #endif /* CONFIG_HS20 */ 417 #ifdef CONFIG_MBO 418 if (hapd->conf->mbo_enabled) 419 *pos |= 0x40; /* Bit 46 - WNM-Notification */ 420 #endif /* CONFIG_MBO */ 421 break; 422 case 6: /* Bits 48-55 */ 423 if (hapd->conf->ssid.utf8_ssid) 424 *pos |= 0x01; /* Bit 48 - UTF-8 SSID */ 425 break; 426 case 7: /* Bits 56-63 */ 427 break; 428 case 8: /* Bits 64-71 */ 429 if (hapd->conf->ftm_responder) 430 *pos |= 0x40; /* Bit 70 - FTM responder */ 431 if (hapd->conf->ftm_initiator) 432 *pos |= 0x80; /* Bit 71 - FTM initiator */ 433 break; 434 case 9: /* Bits 72-79 */ 435 #ifdef CONFIG_FILS 436 if ((hapd->conf->wpa & WPA_PROTO_RSN) && 437 wpa_key_mgmt_fils(hapd->conf->wpa_key_mgmt)) 438 *pos |= 0x01; 439 #endif /* CONFIG_FILS */ 440 #ifdef CONFIG_IEEE80211AX 441 if (hostapd_get_he_twt_responder(hapd, IEEE80211_MODE_AP)) 442 *pos |= 0x40; /* Bit 78 - TWT responder */ 443 #endif /* CONFIG_IEEE80211AX */ 444 if (hostapd_get_ht_vht_twt_responder(hapd)) 445 *pos |= 0x40; /* Bit 78 - TWT responder */ 446 break; 447 case 10: /* Bits 80-87 */ 448 #ifdef CONFIG_SAE 449 if (hapd->conf->wpa && 450 wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt)) { 451 int in_use = hostapd_sae_pw_id_in_use(hapd->conf); 452 453 if (in_use) 454 *pos |= 0x02; /* Bit 81 - SAE Password 455 * Identifiers In Use */ 456 if (in_use == 2) 457 *pos |= 0x04; /* Bit 82 - SAE Password 458 * Identifiers Used Exclusively */ 459 } 460 #endif /* CONFIG_SAE */ 461 if (hapd->conf->beacon_prot && 462 (hapd->iface->drv_flags & 463 WPA_DRIVER_FLAGS_BEACON_PROTECTION)) 464 *pos |= 0x10; /* Bit 84 - Beacon Protection Enabled */ 465 if (hapd->iconf->mbssid == ENHANCED_MBSSID_ENABLED) 466 *pos |= 0x08; /* Bit 83 - Enhanced multiple BSSID */ 467 if (mbssid_complete) 468 *pos |= 0x01; /* Bit 80 - Complete List of NonTxBSSID 469 * Profiles */ 470 break; 471 case 11: /* Bits 88-95 */ 472 #ifdef CONFIG_SAE_PK 473 if (hapd->conf->wpa && 474 wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) && 475 hostapd_sae_pk_exclusively(hapd->conf)) 476 *pos |= 0x01; /* Bit 88 - SAE PK Exclusively */ 477 #endif /* CONFIG_SAE_PK */ 478 break; 479 } 480 } 481 482 483 u8 * hostapd_eid_ext_capab(struct hostapd_data *hapd, u8 *eid, 484 bool mbssid_complete) 485 { 486 u8 *pos = eid; 487 u8 len = EXT_CAPA_MAX_LEN, i; 488 489 if (len < hapd->iface->extended_capa_len) 490 len = hapd->iface->extended_capa_len; 491 492 *pos++ = WLAN_EID_EXT_CAPAB; 493 *pos++ = len; 494 for (i = 0; i < len; i++, pos++) { 495 hostapd_ext_capab_byte(hapd, pos, i, mbssid_complete); 496 497 if (i < hapd->iface->extended_capa_len) { 498 *pos &= ~hapd->iface->extended_capa_mask[i]; 499 *pos |= hapd->iface->extended_capa[i]; 500 } 501 502 if (i < EXT_CAPA_MAX_LEN) { 503 *pos &= ~hapd->conf->ext_capa_mask[i]; 504 *pos |= hapd->conf->ext_capa[i]; 505 } 506 507 /* Clear bits 83 and 22 if EMA and MBSSID are not enabled 508 * otherwise association fails with some clients */ 509 if (i == 10 && hapd->iconf->mbssid < ENHANCED_MBSSID_ENABLED) 510 *pos &= ~0x08; 511 if (i == 2 && !hapd->iconf->mbssid) 512 *pos &= ~0x40; 513 } 514 515 while (len > 0 && eid[1 + len] == 0) { 516 len--; 517 eid[1] = len; 518 } 519 if (len == 0) 520 return eid; 521 522 return eid + 2 + len; 523 } 524 525 526 u8 * hostapd_eid_qos_map_set(struct hostapd_data *hapd, u8 *eid) 527 { 528 u8 *pos = eid; 529 u8 len = hapd->conf->qos_map_set_len; 530 531 if (!len) 532 return eid; 533 534 *pos++ = WLAN_EID_QOS_MAP_SET; 535 *pos++ = len; 536 os_memcpy(pos, hapd->conf->qos_map_set, len); 537 pos += len; 538 539 return pos; 540 } 541 542 543 u8 * hostapd_eid_interworking(struct hostapd_data *hapd, u8 *eid) 544 { 545 u8 *pos = eid; 546 #ifdef CONFIG_INTERWORKING 547 u8 *len; 548 549 if (!hapd->conf->interworking) 550 return eid; 551 552 *pos++ = WLAN_EID_INTERWORKING; 553 len = pos++; 554 555 *pos = hapd->conf->access_network_type; 556 if (hapd->conf->internet) 557 *pos |= INTERWORKING_ANO_INTERNET; 558 if (hapd->conf->asra) 559 *pos |= INTERWORKING_ANO_ASRA; 560 if (hapd->conf->esr) 561 *pos |= INTERWORKING_ANO_ESR; 562 if (hapd->conf->uesa) 563 *pos |= INTERWORKING_ANO_UESA; 564 pos++; 565 566 if (hapd->conf->venue_info_set) { 567 *pos++ = hapd->conf->venue_group; 568 *pos++ = hapd->conf->venue_type; 569 } 570 571 if (!is_zero_ether_addr(hapd->conf->hessid)) { 572 os_memcpy(pos, hapd->conf->hessid, ETH_ALEN); 573 pos += ETH_ALEN; 574 } 575 576 *len = pos - len - 1; 577 #endif /* CONFIG_INTERWORKING */ 578 579 return pos; 580 } 581 582 583 u8 * hostapd_eid_adv_proto(struct hostapd_data *hapd, u8 *eid) 584 { 585 u8 *pos = eid; 586 #ifdef CONFIG_INTERWORKING 587 588 /* TODO: Separate configuration for ANQP? */ 589 if (!hapd->conf->interworking) 590 return eid; 591 592 *pos++ = WLAN_EID_ADV_PROTO; 593 *pos++ = 2; 594 *pos++ = 0x7F; /* Query Response Length Limit | PAME-BI */ 595 *pos++ = ACCESS_NETWORK_QUERY_PROTOCOL; 596 #endif /* CONFIG_INTERWORKING */ 597 598 return pos; 599 } 600 601 602 u8 * hostapd_eid_roaming_consortium(struct hostapd_data *hapd, u8 *eid) 603 { 604 u8 *pos = eid; 605 #ifdef CONFIG_INTERWORKING 606 u8 *len; 607 unsigned int i, count; 608 609 if (!hapd->conf->interworking || 610 hapd->conf->roaming_consortium == NULL || 611 hapd->conf->roaming_consortium_count == 0) 612 return eid; 613 614 *pos++ = WLAN_EID_ROAMING_CONSORTIUM; 615 len = pos++; 616 617 /* Number of ANQP OIs (in addition to the max 3 listed here) */ 618 if (hapd->conf->roaming_consortium_count > 3 + 255) 619 *pos++ = 255; 620 else if (hapd->conf->roaming_consortium_count > 3) 621 *pos++ = hapd->conf->roaming_consortium_count - 3; 622 else 623 *pos++ = 0; 624 625 /* OU #1 and #2 Lengths */ 626 *pos = hapd->conf->roaming_consortium[0].len; 627 if (hapd->conf->roaming_consortium_count > 1) 628 *pos |= hapd->conf->roaming_consortium[1].len << 4; 629 pos++; 630 631 if (hapd->conf->roaming_consortium_count > 3) 632 count = 3; 633 else 634 count = hapd->conf->roaming_consortium_count; 635 636 for (i = 0; i < count; i++) { 637 os_memcpy(pos, hapd->conf->roaming_consortium[i].oi, 638 hapd->conf->roaming_consortium[i].len); 639 pos += hapd->conf->roaming_consortium[i].len; 640 } 641 642 *len = pos - len - 1; 643 #endif /* CONFIG_INTERWORKING */ 644 645 return pos; 646 } 647 648 649 u8 * hostapd_eid_time_adv(struct hostapd_data *hapd, u8 *eid) 650 { 651 if (hapd->conf->time_advertisement != 2) 652 return eid; 653 654 if (hapd->time_adv == NULL && 655 hostapd_update_time_adv(hapd) < 0) 656 return eid; 657 658 if (hapd->time_adv == NULL) 659 return eid; 660 661 os_memcpy(eid, wpabuf_head(hapd->time_adv), 662 wpabuf_len(hapd->time_adv)); 663 eid += wpabuf_len(hapd->time_adv); 664 665 return eid; 666 } 667 668 669 u8 * hostapd_eid_time_zone(struct hostapd_data *hapd, u8 *eid) 670 { 671 size_t len; 672 673 if (hapd->conf->time_advertisement != 2 || !hapd->conf->time_zone) 674 return eid; 675 676 len = os_strlen(hapd->conf->time_zone); 677 678 *eid++ = WLAN_EID_TIME_ZONE; 679 *eid++ = len; 680 os_memcpy(eid, hapd->conf->time_zone, len); 681 eid += len; 682 683 return eid; 684 } 685 686 687 int hostapd_update_time_adv(struct hostapd_data *hapd) 688 { 689 const int elen = 2 + 1 + 10 + 5 + 1; 690 struct os_time t; 691 struct os_tm tm; 692 u8 *pos; 693 694 if (hapd->conf->time_advertisement != 2) 695 return 0; 696 697 if (os_get_time(&t) < 0 || os_gmtime(t.sec, &tm) < 0) 698 return -1; 699 700 if (!hapd->time_adv) { 701 hapd->time_adv = wpabuf_alloc(elen); 702 if (hapd->time_adv == NULL) 703 return -1; 704 pos = wpabuf_put(hapd->time_adv, elen); 705 } else 706 pos = wpabuf_mhead_u8(hapd->time_adv); 707 708 *pos++ = WLAN_EID_TIME_ADVERTISEMENT; 709 *pos++ = 1 + 10 + 5 + 1; 710 711 *pos++ = 2; /* UTC time at which the TSF timer is 0 */ 712 713 /* Time Value at TSF 0 */ 714 /* FIX: need to calculate this based on the current TSF value */ 715 WPA_PUT_LE16(pos, tm.year); /* Year */ 716 pos += 2; 717 *pos++ = tm.month; /* Month */ 718 *pos++ = tm.day; /* Day of month */ 719 *pos++ = tm.hour; /* Hours */ 720 *pos++ = tm.min; /* Minutes */ 721 *pos++ = tm.sec; /* Seconds */ 722 WPA_PUT_LE16(pos, 0); /* Milliseconds (not used) */ 723 pos += 2; 724 *pos++ = 0; /* Reserved */ 725 726 /* Time Error */ 727 /* TODO: fill in an estimate on the error */ 728 *pos++ = 0; 729 *pos++ = 0; 730 *pos++ = 0; 731 *pos++ = 0; 732 *pos++ = 0; 733 734 *pos++ = hapd->time_update_counter++; 735 736 return 0; 737 } 738 739 740 u8 * hostapd_eid_bss_max_idle_period(struct hostapd_data *hapd, u8 *eid, 741 u16 value) 742 { 743 u8 *pos = eid; 744 745 #ifdef CONFIG_WNM_AP 746 if (hapd->conf->ap_max_inactivity > 0 && 747 hapd->conf->bss_max_idle) { 748 unsigned int val; 749 *pos++ = WLAN_EID_BSS_MAX_IDLE_PERIOD; 750 *pos++ = 3; 751 val = hapd->conf->ap_max_inactivity; 752 if (val > 68000) 753 val = 68000; 754 val *= 1000; 755 val /= 1024; 756 if (val == 0) 757 val = 1; 758 if (val > 65535) 759 val = 65535; 760 if (value) 761 val = value; 762 WPA_PUT_LE16(pos, val); 763 pos += 2; 764 /* Set the Protected Keep-Alive Required bit based on 765 * configuration */ 766 *pos++ = hapd->conf->bss_max_idle == 2 ? BIT(0) : 0x00; 767 } 768 #endif /* CONFIG_WNM_AP */ 769 770 return pos; 771 } 772 773 774 #ifdef CONFIG_MBO 775 776 u8 * hostapd_eid_mbo_rssi_assoc_rej(struct hostapd_data *hapd, u8 *eid, 777 size_t len, int delta) 778 { 779 u8 mbo[4]; 780 781 mbo[0] = OCE_ATTR_ID_RSSI_BASED_ASSOC_REJECT; 782 mbo[1] = 2; 783 /* Delta RSSI */ 784 mbo[2] = delta; 785 /* Retry delay */ 786 mbo[3] = hapd->iconf->rssi_reject_assoc_timeout; 787 788 return eid + mbo_add_ie(eid, len, mbo, 4); 789 } 790 791 792 u8 * hostapd_eid_mbo(struct hostapd_data *hapd, u8 *eid, size_t len) 793 { 794 u8 mbo[9], *mbo_pos = mbo; 795 u8 *pos = eid; 796 797 if (!hapd->conf->mbo_enabled && 798 !OCE_STA_CFON_ENABLED(hapd) && !OCE_AP_ENABLED(hapd)) 799 return eid; 800 801 if (hapd->conf->mbo_enabled) { 802 *mbo_pos++ = MBO_ATTR_ID_AP_CAPA_IND; 803 *mbo_pos++ = 1; 804 /* Not Cellular aware */ 805 *mbo_pos++ = 0; 806 } 807 808 if (hapd->conf->mbo_enabled && hapd->mbo_assoc_disallow) { 809 *mbo_pos++ = MBO_ATTR_ID_ASSOC_DISALLOW; 810 *mbo_pos++ = 1; 811 *mbo_pos++ = hapd->mbo_assoc_disallow; 812 } 813 814 if (OCE_STA_CFON_ENABLED(hapd) || OCE_AP_ENABLED(hapd)) { 815 u8 ctrl; 816 817 ctrl = OCE_RELEASE; 818 if (OCE_STA_CFON_ENABLED(hapd) && !OCE_AP_ENABLED(hapd)) 819 ctrl |= OCE_IS_STA_CFON; 820 821 *mbo_pos++ = OCE_ATTR_ID_CAPA_IND; 822 *mbo_pos++ = 1; 823 *mbo_pos++ = ctrl; 824 } 825 826 pos += mbo_add_ie(pos, len, mbo, mbo_pos - mbo); 827 828 return pos; 829 } 830 831 832 u8 hostapd_mbo_ie_len(struct hostapd_data *hapd) 833 { 834 u8 len; 835 836 if (!hapd->conf->mbo_enabled && 837 !OCE_STA_CFON_ENABLED(hapd) && !OCE_AP_ENABLED(hapd)) 838 return 0; 839 840 /* 841 * MBO IE header (6) + Capability Indication attribute (3) + 842 * Association Disallowed attribute (3) = 12 843 */ 844 len = 6; 845 if (hapd->conf->mbo_enabled) 846 len += 3 + (hapd->mbo_assoc_disallow ? 3 : 0); 847 848 /* OCE capability indication attribute (3) */ 849 if (OCE_STA_CFON_ENABLED(hapd) || OCE_AP_ENABLED(hapd)) 850 len += 3; 851 852 return len; 853 } 854 855 #endif /* CONFIG_MBO */ 856 857 858 #ifdef CONFIG_OWE 859 static int hostapd_eid_owe_trans_enabled(struct hostapd_data *hapd) 860 { 861 return hapd->conf->owe_transition_ssid_len > 0 && 862 !is_zero_ether_addr(hapd->conf->owe_transition_bssid); 863 } 864 #endif /* CONFIG_OWE */ 865 866 867 size_t hostapd_eid_owe_trans_len(struct hostapd_data *hapd) 868 { 869 #ifdef CONFIG_OWE 870 if (!hostapd_eid_owe_trans_enabled(hapd)) 871 return 0; 872 return 6 + ETH_ALEN + 1 + hapd->conf->owe_transition_ssid_len; 873 #else /* CONFIG_OWE */ 874 return 0; 875 #endif /* CONFIG_OWE */ 876 } 877 878 879 u8 * hostapd_eid_owe_trans(struct hostapd_data *hapd, u8 *eid, 880 size_t len) 881 { 882 #ifdef CONFIG_OWE 883 u8 *pos = eid; 884 size_t elen; 885 886 if (hapd->conf->owe_transition_ifname[0] && 887 !hostapd_eid_owe_trans_enabled(hapd)) 888 hostapd_owe_trans_get_info(hapd); 889 890 if (!hostapd_eid_owe_trans_enabled(hapd)) 891 return pos; 892 893 elen = hostapd_eid_owe_trans_len(hapd); 894 if (len < elen) { 895 wpa_printf(MSG_DEBUG, 896 "OWE: Not enough room in the buffer for OWE IE"); 897 return pos; 898 } 899 900 *pos++ = WLAN_EID_VENDOR_SPECIFIC; 901 *pos++ = elen - 2; 902 WPA_PUT_BE24(pos, OUI_WFA); 903 pos += 3; 904 *pos++ = OWE_OUI_TYPE; 905 os_memcpy(pos, hapd->conf->owe_transition_bssid, ETH_ALEN); 906 pos += ETH_ALEN; 907 *pos++ = hapd->conf->owe_transition_ssid_len; 908 os_memcpy(pos, hapd->conf->owe_transition_ssid, 909 hapd->conf->owe_transition_ssid_len); 910 pos += hapd->conf->owe_transition_ssid_len; 911 912 return pos; 913 #else /* CONFIG_OWE */ 914 return eid; 915 #endif /* CONFIG_OWE */ 916 } 917 918 919 size_t hostapd_eid_dpp_cc_len(struct hostapd_data *hapd) 920 { 921 #ifdef CONFIG_DPP2 922 if (hostapd_dpp_configurator_connectivity(hapd)) 923 return 6; 924 #endif /* CONFIG_DPP2 */ 925 return 0; 926 } 927 928 929 u8 * hostapd_eid_dpp_cc(struct hostapd_data *hapd, u8 *eid, size_t len) 930 { 931 u8 *pos = eid; 932 933 #ifdef CONFIG_DPP2 934 if (!hostapd_dpp_configurator_connectivity(hapd) || len < 6) 935 return pos; 936 937 *pos++ = WLAN_EID_VENDOR_SPECIFIC; 938 *pos++ = 4; 939 WPA_PUT_BE24(pos, OUI_WFA); 940 pos += 3; 941 *pos++ = DPP_CC_OUI_TYPE; 942 #endif /* CONFIG_DPP2 */ 943 944 return pos; 945 } 946 947 948 void ap_copy_sta_supp_op_classes(struct sta_info *sta, 949 const u8 *supp_op_classes, 950 size_t supp_op_classes_len) 951 { 952 if (!supp_op_classes) 953 return; 954 os_free(sta->supp_op_classes); 955 sta->supp_op_classes = os_malloc(1 + supp_op_classes_len); 956 if (!sta->supp_op_classes) 957 return; 958 959 sta->supp_op_classes[0] = supp_op_classes_len; 960 os_memcpy(sta->supp_op_classes + 1, supp_op_classes, 961 supp_op_classes_len); 962 } 963 964 965 u8 * hostapd_eid_fils_indic(struct hostapd_data *hapd, u8 *eid, int hessid) 966 { 967 u8 *pos = eid; 968 #ifdef CONFIG_FILS 969 u8 *len; 970 u16 fils_info = 0; 971 size_t realms; 972 struct fils_realm *realm; 973 974 if (!(hapd->conf->wpa & WPA_PROTO_RSN) || 975 !wpa_key_mgmt_fils(hapd->conf->wpa_key_mgmt)) 976 return pos; 977 978 realms = dl_list_len(&hapd->conf->fils_realms); 979 if (realms > 7) 980 realms = 7; /* 3 bit count field limits this to max 7 */ 981 982 *pos++ = WLAN_EID_FILS_INDICATION; 983 len = pos++; 984 /* TODO: B0..B2: Number of Public Key Identifiers */ 985 if (hapd->conf->erp_domain) { 986 /* B3..B5: Number of Realm Identifiers */ 987 fils_info |= realms << 3; 988 } 989 /* TODO: B6: FILS IP Address Configuration */ 990 if (hapd->conf->fils_cache_id_set) 991 fils_info |= BIT(7); 992 if (hessid && !is_zero_ether_addr(hapd->conf->hessid)) 993 fils_info |= BIT(8); /* HESSID Included */ 994 /* FILS Shared Key Authentication without PFS Supported */ 995 fils_info |= BIT(9); 996 if (hapd->conf->fils_dh_group) { 997 /* FILS Shared Key Authentication with PFS Supported */ 998 fils_info |= BIT(10); 999 } 1000 /* TODO: B11: FILS Public Key Authentication Supported */ 1001 /* B12..B15: Reserved */ 1002 WPA_PUT_LE16(pos, fils_info); 1003 pos += 2; 1004 if (hapd->conf->fils_cache_id_set) { 1005 os_memcpy(pos, hapd->conf->fils_cache_id, FILS_CACHE_ID_LEN); 1006 pos += FILS_CACHE_ID_LEN; 1007 } 1008 if (hessid && !is_zero_ether_addr(hapd->conf->hessid)) { 1009 os_memcpy(pos, hapd->conf->hessid, ETH_ALEN); 1010 pos += ETH_ALEN; 1011 } 1012 1013 dl_list_for_each(realm, &hapd->conf->fils_realms, struct fils_realm, 1014 list) { 1015 if (realms == 0) 1016 break; 1017 realms--; 1018 os_memcpy(pos, realm->hash, 2); 1019 pos += 2; 1020 } 1021 *len = pos - len - 1; 1022 #endif /* CONFIG_FILS */ 1023 1024 return pos; 1025 } 1026 1027 1028 #ifdef CONFIG_OCV 1029 int get_tx_parameters(struct sta_info *sta, int ap_max_chanwidth, 1030 int ap_seg1_idx, int *bandwidth, int *seg1_idx) 1031 { 1032 int ht_40mhz = 0; 1033 int vht_80p80 = 0; 1034 int requested_bw; 1035 1036 if (sta->ht_capabilities) 1037 ht_40mhz = !!(sta->ht_capabilities->ht_capabilities_info & 1038 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET); 1039 1040 if (sta->vht_operation) { 1041 struct ieee80211_vht_operation *oper = sta->vht_operation; 1042 1043 /* 1044 * If a VHT Operation element was present, use it to determine 1045 * the supported channel bandwidth. 1046 */ 1047 if (oper->vht_op_info_chwidth == CHANWIDTH_USE_HT) { 1048 requested_bw = ht_40mhz ? 40 : 20; 1049 } else if (oper->vht_op_info_chan_center_freq_seg1_idx == 0) { 1050 requested_bw = 80; 1051 } else { 1052 int diff; 1053 1054 requested_bw = 160; 1055 diff = abs((int) 1056 oper->vht_op_info_chan_center_freq_seg0_idx - 1057 (int) 1058 oper->vht_op_info_chan_center_freq_seg1_idx); 1059 vht_80p80 = oper->vht_op_info_chan_center_freq_seg1_idx 1060 != 0 && diff > 16; 1061 } 1062 } else if (sta->vht_capabilities) { 1063 struct ieee80211_vht_capabilities *capab; 1064 int vht_chanwidth; 1065 1066 capab = sta->vht_capabilities; 1067 1068 /* 1069 * If only the VHT Capabilities element is present (e.g., for 1070 * normal clients), use it to determine the supported channel 1071 * bandwidth. 1072 */ 1073 vht_chanwidth = capab->vht_capabilities_info & 1074 VHT_CAP_SUPP_CHAN_WIDTH_MASK; 1075 vht_80p80 = capab->vht_capabilities_info & 1076 VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ; 1077 1078 /* TODO: Also take into account Extended NSS BW Support field */ 1079 requested_bw = vht_chanwidth ? 160 : 80; 1080 } else { 1081 requested_bw = ht_40mhz ? 40 : 20; 1082 } 1083 1084 *bandwidth = requested_bw < ap_max_chanwidth ? 1085 requested_bw : ap_max_chanwidth; 1086 1087 *seg1_idx = 0; 1088 if (ap_seg1_idx && vht_80p80) 1089 *seg1_idx = ap_seg1_idx; 1090 1091 return 0; 1092 } 1093 #endif /* CONFIG_OCV */ 1094 1095 1096 u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len) 1097 { 1098 u8 *pos = eid; 1099 bool sae_pk = false; 1100 u32 capab = 0, tmp; 1101 size_t flen; 1102 1103 if (!(hapd->conf->wpa & WPA_PROTO_RSN)) 1104 return eid; 1105 1106 #ifdef CONFIG_SAE_PK 1107 sae_pk = hostapd_sae_pk_in_use(hapd->conf); 1108 #endif /* CONFIG_SAE_PK */ 1109 1110 if (wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) && 1111 (hapd->conf->sae_pwe == SAE_PWE_HASH_TO_ELEMENT || 1112 hapd->conf->sae_pwe == SAE_PWE_BOTH || 1113 hostapd_sae_pw_id_in_use(hapd->conf) || sae_pk || 1114 wpa_key_mgmt_sae_ext_key(hapd->conf->wpa_key_mgmt)) && 1115 hapd->conf->sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK) { 1116 capab |= BIT(WLAN_RSNX_CAPAB_SAE_H2E); 1117 #ifdef CONFIG_SAE_PK 1118 if (sae_pk) 1119 capab |= BIT(WLAN_RSNX_CAPAB_SAE_PK); 1120 #endif /* CONFIG_SAE_PK */ 1121 } 1122 1123 if (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF_AP) 1124 capab |= BIT(WLAN_RSNX_CAPAB_SECURE_LTF); 1125 if (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_RTT_AP) 1126 capab |= BIT(WLAN_RSNX_CAPAB_SECURE_RTT); 1127 if (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_PROT_RANGE_NEG_AP) 1128 capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR); 1129 if (hapd->conf->ssid_protection) 1130 capab |= BIT(WLAN_RSNX_CAPAB_SSID_PROTECTION); 1131 1132 if (!capab) 1133 return eid; /* no supported extended RSN capabilities */ 1134 tmp = capab; 1135 flen = 0; 1136 while (tmp) { 1137 flen++; 1138 tmp >>= 8; 1139 } 1140 1141 if (len < 2 + flen) 1142 return eid; /* no supported extended RSN capabilities */ 1143 capab |= flen - 1; /* bit 0-3 = Field length (n - 1) */ 1144 1145 *pos++ = WLAN_EID_RSNX; 1146 *pos++ = flen; 1147 while (capab) { 1148 *pos++ = capab & 0xff; 1149 capab >>= 8; 1150 } 1151 1152 return pos; 1153 } 1154 1155 1156 u16 check_ext_capab(struct hostapd_data *hapd, struct sta_info *sta, 1157 const u8 *ext_capab_ie, size_t ext_capab_ie_len) 1158 { 1159 /* check for QoS Map support */ 1160 if (ext_capab_ie_len >= 5) { 1161 if (ext_capab_ie[4] & 0x01) 1162 sta->qos_map_enabled = 1; 1163 } 1164 1165 if (ext_capab_ie_len > 0) { 1166 sta->ecsa_supported = !!(ext_capab_ie[0] & BIT(2)); 1167 os_free(sta->ext_capability); 1168 sta->ext_capability = os_malloc(1 + ext_capab_ie_len); 1169 if (sta->ext_capability) { 1170 sta->ext_capability[0] = ext_capab_ie_len; 1171 os_memcpy(sta->ext_capability + 1, ext_capab_ie, 1172 ext_capab_ie_len); 1173 } 1174 } 1175 1176 return WLAN_STATUS_SUCCESS; 1177 } 1178 1179 1180 struct sta_info * hostapd_ml_get_assoc_sta(struct hostapd_data *hapd, 1181 struct sta_info *sta, 1182 struct hostapd_data **assoc_hapd) 1183 { 1184 #ifdef CONFIG_IEEE80211BE 1185 struct hostapd_data *other_hapd = NULL; 1186 struct sta_info *tmp_sta; 1187 1188 if (!ap_sta_is_mld(hapd, sta)) 1189 return NULL; 1190 1191 *assoc_hapd = hapd; 1192 1193 /* The station is the one on which the association was performed */ 1194 if (sta->mld_assoc_link_id == hapd->mld_link_id) 1195 return sta; 1196 1197 other_hapd = hostapd_mld_get_link_bss(hapd, sta->mld_assoc_link_id); 1198 if (!other_hapd) { 1199 wpa_printf(MSG_DEBUG, "MLD: No link match for link_id=%u", 1200 sta->mld_assoc_link_id); 1201 return sta; 1202 } 1203 1204 /* 1205 * Iterate over the stations and find the one with the matching link ID 1206 * and association ID. 1207 */ 1208 for (tmp_sta = other_hapd->sta_list; tmp_sta; tmp_sta = tmp_sta->next) { 1209 if (tmp_sta->mld_assoc_link_id == sta->mld_assoc_link_id && 1210 tmp_sta->aid == sta->aid) { 1211 *assoc_hapd = other_hapd; 1212 return tmp_sta; 1213 } 1214 } 1215 #endif /* CONFIG_IEEE80211BE */ 1216 1217 return sta; 1218 } 1219 1220 1221 bool hostapd_get_ht_vht_twt_responder(struct hostapd_data *hapd) 1222 { 1223 return hapd->iconf->ht_vht_twt_responder && 1224 ((hapd->iconf->ieee80211n && !hapd->conf->disable_11n) || 1225 (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac)) && 1226 (hapd->iface->drv_flags2 & 1227 WPA_DRIVER_FLAGS2_HT_VHT_TWT_RESPONDER); 1228 } 1229