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