1 /*
2 * hostapd / Callback functions for driver wrappers
3 * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
4 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
5 *
6 * This software may be distributed under the terms of the BSD license.
7 * See README for more details.
8 */
9
10 #include "utils/includes.h"
11
12 #include "utils/common.h"
13 #include "utils/eloop.h"
14 #include "radius/radius.h"
15 #include "drivers/driver.h"
16 #include "common/ieee802_11_defs.h"
17 #include "common/ieee802_11_common.h"
18 #include "common/wpa_ctrl.h"
19 #include "common/dpp.h"
20 #include "common/sae.h"
21 #include "common/hw_features_common.h"
22 #include "common/nan_de.h"
23 #include "crypto/random.h"
24 #include "p2p/p2p.h"
25 #include "wps/wps.h"
26 #include "fst/fst.h"
27 #include "wnm_ap.h"
28 #include "hostapd.h"
29 #include "ieee802_11.h"
30 #include "ieee802_11_auth.h"
31 #include "sta_info.h"
32 #include "accounting.h"
33 #include "tkip_countermeasures.h"
34 #include "ieee802_1x.h"
35 #include "wpa_auth.h"
36 #include "wps_hostapd.h"
37 #include "ap_drv_ops.h"
38 #include "ap_config.h"
39 #include "ap_mlme.h"
40 #include "hw_features.h"
41 #include "dfs.h"
42 #include "beacon.h"
43 #include "mbo_ap.h"
44 #include "dpp_hostapd.h"
45 #include "fils_hlp.h"
46 #include "neighbor_db.h"
47 #include "nan_usd_ap.h"
48 #include "interference.h"
49
50
51 #ifdef CONFIG_FILS
hostapd_notify_assoc_fils_finish(struct hostapd_data * hapd,struct sta_info * sta)52 void hostapd_notify_assoc_fils_finish(struct hostapd_data *hapd,
53 struct sta_info *sta)
54 {
55 u16 reply_res = WLAN_STATUS_SUCCESS;
56 struct ieee802_11_elems elems;
57 u8 buf[IEEE80211_MAX_MMPDU_SIZE], *p = buf;
58 int new_assoc;
59 bool updated;
60
61 wpa_printf(MSG_DEBUG, "%s FILS: Finish association with " MACSTR,
62 __func__, MAC2STR(sta->addr));
63 eloop_cancel_timeout(fils_hlp_timeout, hapd, sta);
64 if (!sta->fils_pending_assoc_req)
65 return;
66
67 if (ieee802_11_parse_elems(sta->fils_pending_assoc_req,
68 sta->fils_pending_assoc_req_len, &elems,
69 0) == ParseFailed ||
70 !elems.fils_session) {
71 wpa_printf(MSG_DEBUG, "%s failed to find FILS Session element",
72 __func__);
73 return;
74 }
75
76 p = hostapd_eid_assoc_fils_session(sta->wpa_sm, p,
77 elems.fils_session,
78 sta->fils_hlp_resp);
79 if (!p)
80 return;
81
82 reply_res = hostapd_sta_assoc(hapd, sta->addr,
83 sta->fils_pending_assoc_is_reassoc,
84 WLAN_STATUS_SUCCESS,
85 buf, p - buf);
86 updated = ap_sta_set_authorized_flag(hapd, sta, 1);
87 new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;
88 sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
89 sta->flags &= ~WLAN_STA_WNM_SLEEP_MODE;
90 hostapd_set_sta_flags(hapd, sta);
91 if (updated)
92 ap_sta_set_authorized_event(hapd, sta, 1);
93 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FILS);
94 ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
95 hostapd_new_assoc_sta(hapd, sta, !new_assoc);
96 os_free(sta->fils_pending_assoc_req);
97 sta->fils_pending_assoc_req = NULL;
98 sta->fils_pending_assoc_req_len = 0;
99 wpabuf_free(sta->fils_hlp_resp);
100 sta->fils_hlp_resp = NULL;
101 wpabuf_free(sta->hlp_dhcp_discover);
102 sta->hlp_dhcp_discover = NULL;
103 fils_hlp_deinit(hapd);
104
105 /*
106 * Remove the station in case transmission of a success response fails
107 * (the STA was added associated to the driver) or if the station was
108 * previously added unassociated.
109 */
110 if (reply_res != WLAN_STATUS_SUCCESS || sta->added_unassoc) {
111 hostapd_drv_sta_remove(hapd, sta->addr);
112 sta->added_unassoc = 0;
113 }
114 }
115 #endif /* CONFIG_FILS */
116
117
check_sa_query_need(struct hostapd_data * hapd,struct sta_info * sta)118 static bool check_sa_query_need(struct hostapd_data *hapd, struct sta_info *sta)
119 {
120 if ((sta->flags &
121 (WLAN_STA_ASSOC | WLAN_STA_MFP | WLAN_STA_AUTHORIZED)) !=
122 (WLAN_STA_ASSOC | WLAN_STA_MFP | WLAN_STA_AUTHORIZED))
123 return false;
124
125 if (!sta->sa_query_timed_out && sta->sa_query_count > 0)
126 ap_check_sa_query_timeout(hapd, sta);
127
128 if (!sta->sa_query_timed_out && (sta->auth_alg != WLAN_AUTH_FT)) {
129 /*
130 * STA has already been associated with MFP and SA Query timeout
131 * has not been reached. Reject the association attempt
132 * temporarily and start SA Query, if one is not pending.
133 */
134 if (sta->sa_query_count == 0)
135 ap_sta_start_sa_query(hapd, sta);
136
137 return true;
138 }
139
140 return false;
141 }
142
143
144 #ifdef CONFIG_IEEE80211BE
hostapd_update_sta_links_status(struct hostapd_data * hapd,struct sta_info * sta,const u8 * resp_ies,size_t resp_ies_len)145 static int hostapd_update_sta_links_status(struct hostapd_data *hapd,
146 struct sta_info *sta,
147 const u8 *resp_ies,
148 size_t resp_ies_len)
149 {
150 struct mld_info *info = &sta->mld_info;
151 struct wpabuf *mlebuf;
152 const u8 *mle, *pos;
153 struct ieee802_11_elems elems;
154 size_t mle_len, rem_len;
155 int ret = 0;
156
157 if (!resp_ies) {
158 wpa_printf(MSG_DEBUG,
159 "MLO: (Re)Association Response frame elements not available");
160 return -1;
161 }
162
163 if (ieee802_11_parse_elems(resp_ies, resp_ies_len, &elems, 0) ==
164 ParseFailed) {
165 wpa_printf(MSG_DEBUG,
166 "MLO: Failed to parse (Re)Association Response frame elements");
167 return -1;
168 }
169
170 mlebuf = ieee802_11_defrag(elems.basic_mle, elems.basic_mle_len, true);
171 if (!mlebuf) {
172 wpa_printf(MSG_ERROR,
173 "MLO: Basic Multi-Link element not found in (Re)Association Response frame");
174 return -1;
175 }
176
177 mle = wpabuf_head(mlebuf);
178 mle_len = wpabuf_len(mlebuf);
179 if (mle_len < MULTI_LINK_CONTROL_LEN + 1 ||
180 mle_len - MULTI_LINK_CONTROL_LEN < mle[MULTI_LINK_CONTROL_LEN]) {
181 wpa_printf(MSG_ERROR,
182 "MLO: Invalid Multi-Link element in (Re)Association Response frame");
183 ret = -1;
184 goto out;
185 }
186
187 /* Skip Common Info */
188 pos = mle + MULTI_LINK_CONTROL_LEN + mle[MULTI_LINK_CONTROL_LEN];
189 rem_len = mle_len -
190 (MULTI_LINK_CONTROL_LEN + mle[MULTI_LINK_CONTROL_LEN]);
191
192 /* Parse Subelements */
193 while (rem_len > 2) {
194 size_t ie_len, subelem_defrag_len;
195 int num_frag_subelems;
196
197 num_frag_subelems =
198 ieee802_11_defrag_mle_subelem(mlebuf, pos,
199 &subelem_defrag_len);
200 if (num_frag_subelems < 0) {
201 wpa_printf(MSG_DEBUG,
202 "MLD: Failed to parse MLE subelem");
203 break;
204 }
205
206 ie_len = 2 + subelem_defrag_len;
207 if ((size_t) num_frag_subelems * 2 > rem_len)
208 break;
209 rem_len -= num_frag_subelems * 2;
210
211 if (rem_len < ie_len)
212 break;
213
214 if (pos[0] == MULTI_LINK_SUB_ELEM_ID_PER_STA_PROFILE) {
215 u8 link_id;
216 const u8 *sta_profile;
217 size_t sta_profile_len;
218 u16 sta_ctrl;
219
220 if (subelem_defrag_len < BASIC_MLE_STA_CTRL_LEN + 1) {
221 wpa_printf(MSG_DEBUG,
222 "MLO: Invalid per-STA profile IE");
223 goto next_subelem;
224 }
225
226 sta_profile_len = subelem_defrag_len;
227 sta_profile = &pos[2];
228 sta_ctrl = WPA_GET_LE16(sta_profile);
229 link_id = sta_ctrl & BASIC_MLE_STA_CTRL_LINK_ID_MASK;
230 if (link_id >= MAX_NUM_MLD_LINKS) {
231 wpa_printf(MSG_DEBUG,
232 "MLO: Invalid link ID in per-STA profile IE");
233 goto next_subelem;
234 }
235
236 /* Skip STA Control and STA Info */
237 if (sta_profile_len - BASIC_MLE_STA_CTRL_LEN <
238 sta_profile[BASIC_MLE_STA_CTRL_LEN]) {
239 wpa_printf(MSG_DEBUG,
240 "MLO: Invalid STA info in per-STA profile IE");
241 goto next_subelem;
242 }
243
244 sta_profile_len = sta_profile_len -
245 (BASIC_MLE_STA_CTRL_LEN +
246 sta_profile[BASIC_MLE_STA_CTRL_LEN]);
247 sta_profile = sta_profile + BASIC_MLE_STA_CTRL_LEN +
248 sta_profile[BASIC_MLE_STA_CTRL_LEN];
249
250 /* Skip Capabilities Information field */
251 if (sta_profile_len < 2)
252 goto next_subelem;
253 sta_profile_len -= 2;
254 sta_profile += 2;
255
256 /* Get status of the link */
257 info->links[link_id].status = WPA_GET_LE16(sta_profile);
258 }
259 next_subelem:
260 pos += ie_len;
261 rem_len -= ie_len;
262 }
263
264 out:
265 wpabuf_free(mlebuf);
266 return ret;
267 }
268 #endif /* CONFIG_IEEE80211BE */
269
270
271 #if defined(HOSTAPD) || defined(CONFIG_IEEE80211BE)
hostapd_find_by_sta(struct hostapd_iface * iface,const u8 * src,bool rsn,struct sta_info ** sta_ret)272 static struct hostapd_data * hostapd_find_by_sta(struct hostapd_iface *iface,
273 const u8 *src, bool rsn,
274 struct sta_info **sta_ret)
275 {
276 struct hostapd_data *hapd;
277 struct sta_info *sta;
278 unsigned int j;
279
280 if (sta_ret)
281 *sta_ret = NULL;
282
283 for (j = 0; j < iface->num_bss; j++) {
284 hapd = iface->bss[j];
285 sta = ap_get_sta(hapd, src);
286 if (sta && (sta->flags & WLAN_STA_ASSOC) &&
287 (!rsn || sta->wpa_sm)) {
288 if (sta_ret)
289 *sta_ret = sta;
290 return hapd;
291 }
292 #ifdef CONFIG_IEEE80211BE
293 if (hapd->conf->mld_ap) {
294 struct hostapd_data *p_hapd;
295
296 for_each_mld_link(p_hapd, hapd) {
297 if (p_hapd == hapd)
298 continue;
299
300 sta = ap_get_sta(p_hapd, src);
301 if (sta && (sta->flags & WLAN_STA_ASSOC) &&
302 (!rsn || sta->wpa_sm)) {
303 if (sta_ret)
304 *sta_ret = sta;
305 return p_hapd;
306 }
307 }
308 }
309 #endif /* CONFIG_IEEE80211BE */
310 }
311
312 return NULL;
313 }
314 #endif /* HOSTAPD || CONFIG_IEEE80211BE */
315
316
hostapd_notif_assoc(struct hostapd_data * hapd,const u8 * addr,const u8 * req_ies,size_t req_ies_len,const u8 * resp_ies,size_t resp_ies_len,const u8 * link_addr,int reassoc)317 int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
318 const u8 *req_ies, size_t req_ies_len,
319 const u8 *resp_ies, size_t resp_ies_len,
320 const u8 *link_addr, int reassoc)
321 {
322 struct sta_info *sta;
323 int new_assoc;
324 enum wpa_validate_result res;
325 struct ieee802_11_elems elems;
326 const u8 *ie;
327 size_t ielen;
328 u8 buf[sizeof(struct ieee80211_mgmt) + 1024];
329 u8 *p = buf;
330 u16 reason = WLAN_REASON_UNSPECIFIED;
331 int status = WLAN_STATUS_SUCCESS;
332 const u8 *p2p_dev_addr = NULL;
333 #ifdef CONFIG_OWE
334 struct hostapd_iface *iface = hapd->iface;
335 #endif /* CONFIG_OWE */
336 bool updated = false;
337 bool driver_acl;
338
339 #ifdef CONFIG_P2P
340 if (hapd->p2p_group && (!hapd->started || hapd->disabled)) {
341 wpa_printf(MSG_DEBUG,
342 "hostapd_notif_assoc: Ignore assoc event - P2P GO not started or disabled");
343 return 0;
344 }
345 #endif /* CONFIG_P2P */
346
347 if (addr == NULL) {
348 /*
349 * This could potentially happen with unexpected event from the
350 * driver wrapper. This was seen at least in one case where the
351 * driver ended up being set to station mode while hostapd was
352 * running, so better make sure we stop processing such an
353 * event here.
354 */
355 wpa_printf(MSG_DEBUG,
356 "hostapd_notif_assoc: Skip event with no address");
357 return -1;
358 }
359
360 if (is_multicast_ether_addr(addr) ||
361 is_zero_ether_addr(addr) ||
362 ether_addr_equal(addr, hapd->own_addr)) {
363 /* Do not process any frames with unexpected/invalid SA so that
364 * we do not add any state for unexpected STA addresses or end
365 * up sending out frames to unexpected destination. */
366 wpa_printf(MSG_DEBUG, "%s: Invalid SA=" MACSTR
367 " in received indication - ignore this indication silently",
368 __func__, MAC2STR(addr));
369 return 0;
370 }
371
372 random_add_randomness(addr, ETH_ALEN);
373
374 hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
375 HOSTAPD_LEVEL_INFO, "associated");
376
377 if (ieee802_11_parse_elems(req_ies, req_ies_len, &elems, 0) ==
378 ParseFailed) {
379 wpa_printf(MSG_DEBUG, "%s: Could not parse elements", __func__);
380 return -1;
381 }
382
383 if (elems.wps_ie) {
384 ie = elems.wps_ie - 2;
385 ielen = elems.wps_ie_len + 2;
386 wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)AssocReq");
387 } else if (elems.rsn_ie) {
388 ie = elems.rsn_ie - 2;
389 ielen = elems.rsn_ie_len + 2;
390 wpa_printf(MSG_DEBUG, "STA included RSN IE in (Re)AssocReq");
391 } else if (elems.wpa_ie) {
392 ie = elems.wpa_ie - 2;
393 ielen = elems.wpa_ie_len + 2;
394 wpa_printf(MSG_DEBUG, "STA included WPA IE in (Re)AssocReq");
395 } else {
396 ie = NULL;
397 ielen = 0;
398 wpa_printf(MSG_DEBUG,
399 "STA did not include WPS/RSN/WPA IE in (Re)AssocReq");
400 }
401
402 sta = ap_get_sta(hapd, addr);
403 if (sta) {
404 ap_sta_no_session_timeout(hapd, sta);
405 accounting_sta_stop(hapd, sta);
406
407 /*
408 * Make sure that the previously registered inactivity timer
409 * will not remove the STA immediately.
410 */
411 sta->timeout_next = STA_NULLFUNC;
412 } else if (!hostapd_acceptable_sta_addr(hapd, addr, addr, false)) {
413 wpa_printf(MSG_INFO, "STA " MACSTR " not allowed to connect",
414 MAC2STR(addr));
415 hostapd_drv_sta_disassoc(hapd, addr, WLAN_REASON_UNSPECIFIED);
416 return -1;
417 } else {
418 sta = ap_sta_add(hapd, addr);
419 if (sta == NULL) {
420 hostapd_drv_sta_disassoc(hapd, addr,
421 WLAN_REASON_DISASSOC_AP_BUSY);
422 return -1;
423 }
424 }
425
426 if (hapd->conf->wpa && check_sa_query_need(hapd, sta)) {
427 status = WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY;
428 p = hostapd_eid_assoc_comeback_time(hapd, sta, p);
429 hostapd_sta_assoc(hapd, addr, reassoc, status, buf, p - buf);
430
431 return 0;
432 }
433
434 #ifdef CONFIG_IEEE80211BE
435 if (link_addr) {
436 struct mld_info *info = &sta->mld_info;
437 int i, num_valid_links = 0;
438 u8 link_id = hapd->mld_link_id;
439
440 ap_sta_set_mld(sta, true);
441 sta->mld_assoc_link_id = link_id;
442 os_memcpy(info->common_info.mld_addr, addr, ETH_ALEN);
443 info->links[link_id].valid = true;
444 os_memcpy(info->links[link_id].peer_addr, link_addr, ETH_ALEN);
445 os_memcpy(info->links[link_id].local_addr, hapd->own_addr,
446 ETH_ALEN);
447
448 if (!elems.basic_mle ||
449 hostapd_process_ml_assoc_req(hapd, &elems, sta) !=
450 WLAN_STATUS_SUCCESS) {
451 reason = WLAN_REASON_UNSPECIFIED;
452 wpa_printf(MSG_DEBUG,
453 "Failed to get STA non-assoc links info");
454 goto fail;
455 }
456
457 for (i = 0 ; i < MAX_NUM_MLD_LINKS; i++) {
458 if (info->links[i].valid)
459 num_valid_links++;
460 }
461 if (num_valid_links > 1 &&
462 hostapd_update_sta_links_status(hapd, sta, resp_ies,
463 resp_ies_len)) {
464 wpa_printf(MSG_DEBUG,
465 "Failed to get STA non-assoc links status info");
466 reason = WLAN_REASON_UNSPECIFIED;
467 goto fail;
468 }
469 }
470 #endif /* CONFIG_IEEE80211BE */
471
472 sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2);
473
474 /*
475 * ACL configurations to the drivers (implementing AP SME and ACL
476 * offload) without hostapd's knowledge, can result in a disconnection
477 * though the driver accepts the connection. Skip the hostapd check for
478 * ACL if the driver supports ACL offload to avoid potentially
479 * conflicting ACL rules.
480 */
481 driver_acl = hapd->iface->drv_max_acl_mac_addrs > 0;
482 #ifdef CONFIG_IEEE80211BE
483 if (hapd->conf->mld_ap)
484 driver_acl = false;
485 #endif /* CONFIG_IEEE80211BE */
486 if (!driver_acl &&
487 hostapd_check_acl(hapd, addr, NULL) != HOSTAPD_ACL_ACCEPT) {
488 wpa_printf(MSG_INFO, "STA " MACSTR " not allowed to connect",
489 MAC2STR(addr));
490 reason = WLAN_REASON_UNSPECIFIED;
491 goto fail;
492 }
493 #ifdef CONFIG_IEEE80211BE
494 /*
495 * The idea is that ACL is per link. For MLO associations, check
496 * whether peer MLD MAC address is acceptable in all requested links.
497 * For each peer link address, check the corresponding association
498 * local link's ACL configuration whether it is acceptable.
499 */
500 if (!driver_acl && hapd->conf->mld_ap && link_addr) {
501 int link_id;
502 struct mld_link_info *info;
503 struct hostapd_data *bss;
504
505 for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) {
506 info = &sta->mld_info.links[link_id];
507 if (!info->valid)
508 continue;
509
510 bss = hostapd_mld_get_link_bss(hapd, link_id);
511 if (bss && bss != hapd &&
512 hostapd_check_acl(bss, addr, NULL) !=
513 HOSTAPD_ACL_ACCEPT) {
514 wpa_printf(MSG_INFO, "STA " MACSTR
515 " not allowed to connect",
516 MAC2STR(addr));
517 reason = WLAN_REASON_UNSPECIFIED;
518 goto fail;
519 }
520 if (bss &&
521 hostapd_check_acl(bss, info->peer_addr, NULL) !=
522 HOSTAPD_ACL_ACCEPT) {
523 wpa_printf(MSG_INFO, "link addr " MACSTR
524 " not allowed to connect",
525 MAC2STR(info->peer_addr));
526 reason = WLAN_REASON_UNSPECIFIED;
527 goto fail;
528 }
529 }
530 }
531 #endif /* CONFIG_IEEE80211BE */
532
533 #ifdef CONFIG_P2P
534 if (elems.p2p) {
535 wpabuf_free(sta->p2p_ie);
536 sta->p2p_ie = ieee802_11_vendor_ie_concat(req_ies, req_ies_len,
537 P2P_IE_VENDOR_TYPE);
538 if (sta->p2p_ie)
539 p2p_dev_addr = p2p_get_go_dev_addr(sta->p2p_ie);
540 }
541 #endif /* CONFIG_P2P */
542
543 #ifdef NEED_AP_MLME
544 if (elems.ht_capabilities &&
545 (hapd->iface->conf->ht_capab &
546 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) {
547 struct ieee80211_ht_capabilities *ht_cap =
548 (struct ieee80211_ht_capabilities *)
549 elems.ht_capabilities;
550
551 if (le_to_host16(ht_cap->ht_capabilities_info) &
552 HT_CAP_INFO_40MHZ_INTOLERANT)
553 ht40_intolerant_add(hapd->iface, sta);
554 }
555 #endif /* NEED_AP_MLME */
556
557 check_ext_capab(hapd, sta, elems.ext_capab, elems.ext_capab_len);
558
559 #ifdef CONFIG_HS20
560 wpabuf_free(sta->hs20_ie);
561 if (elems.hs20 && elems.hs20_len > 4) {
562 sta->hs20_ie = wpabuf_alloc_copy(elems.hs20 + 4,
563 elems.hs20_len - 4);
564 } else
565 sta->hs20_ie = NULL;
566
567 wpabuf_free(sta->roaming_consortium);
568 if (elems.roaming_cons_sel)
569 sta->roaming_consortium = wpabuf_alloc_copy(
570 elems.roaming_cons_sel + 4,
571 elems.roaming_cons_sel_len - 4);
572 else
573 sta->roaming_consortium = NULL;
574 #endif /* CONFIG_HS20 */
575
576 #ifdef CONFIG_FST
577 wpabuf_free(sta->mb_ies);
578 if (hapd->iface->fst)
579 sta->mb_ies = mb_ies_by_info(&elems.mb_ies);
580 else
581 sta->mb_ies = NULL;
582 #endif /* CONFIG_FST */
583
584 mbo_ap_check_sta_assoc(hapd, sta, &elems);
585
586 ap_copy_sta_supp_op_classes(sta, elems.supp_op_classes,
587 elems.supp_op_classes_len);
588
589 if (hapd->conf->wpa) {
590 if (ie == NULL || ielen == 0) {
591 #ifdef CONFIG_WPS
592 if (hapd->conf->wps_state) {
593 wpa_printf(MSG_DEBUG,
594 "STA did not include WPA/RSN IE in (Re)Association Request - possible WPS use");
595 sta->flags |= WLAN_STA_MAYBE_WPS;
596 goto skip_wpa_check;
597 }
598 #endif /* CONFIG_WPS */
599
600 wpa_printf(MSG_DEBUG, "No WPA/RSN IE from STA");
601 reason = WLAN_REASON_INVALID_IE;
602 status = WLAN_STATUS_INVALID_ELEMENT;
603 goto fail;
604 }
605 #ifdef CONFIG_WPS
606 if (hapd->conf->wps_state && ie[0] == 0xdd && ie[1] >= 4 &&
607 os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) {
608 struct wpabuf *wps;
609
610 sta->flags |= WLAN_STA_WPS;
611 wps = ieee802_11_vendor_ie_concat(ie, ielen,
612 WPS_IE_VENDOR_TYPE);
613 if (wps) {
614 if (wps_is_20(wps)) {
615 wpa_printf(MSG_DEBUG,
616 "WPS: STA supports WPS 2.0");
617 sta->flags |= WLAN_STA_WPS2;
618 }
619 wpabuf_free(wps);
620 }
621 goto skip_wpa_check;
622 }
623 #endif /* CONFIG_WPS */
624
625 if (sta->wpa_sm == NULL)
626 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
627 sta->addr,
628 p2p_dev_addr);
629 if (sta->wpa_sm == NULL) {
630 wpa_printf(MSG_ERROR,
631 "Failed to initialize WPA state machine");
632 return -1;
633 }
634 wpa_auth_set_rsn_selection(sta->wpa_sm, elems.rsn_selection,
635 elems.rsn_selection_len);
636 wpa_auth_set_auth_alg(sta->wpa_sm, sta->auth_alg);
637 #ifdef CONFIG_IEEE80211BE
638 if (ap_sta_is_mld(hapd, sta)) {
639 wpa_printf(MSG_DEBUG,
640 "MLD: Set ML info in RSN Authenticator");
641 wpa_auth_set_ml_info(sta->wpa_sm,
642 sta->mld_assoc_link_id,
643 &sta->mld_info);
644 }
645 #endif /* CONFIG_IEEE80211BE */
646 res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
647 hapd->iface->freq,
648 ie, ielen,
649 elems.rsnxe ? elems.rsnxe - 2 : NULL,
650 elems.rsnxe ? elems.rsnxe_len + 2 : 0,
651 elems.mdie, elems.mdie_len,
652 elems.owe_dh, elems.owe_dh_len, NULL,
653 ap_sta_is_mld(hapd, sta));
654 reason = WLAN_REASON_INVALID_IE;
655 status = WLAN_STATUS_INVALID_ELEMENT;
656 switch (res) {
657 case WPA_IE_OK:
658 reason = WLAN_REASON_UNSPECIFIED;
659 status = WLAN_STATUS_SUCCESS;
660 break;
661 case WPA_INVALID_IE:
662 reason = WLAN_REASON_INVALID_IE;
663 status = WLAN_STATUS_INVALID_ELEMENT;
664 break;
665 case WPA_INVALID_GROUP:
666 reason = WLAN_REASON_GROUP_CIPHER_NOT_VALID;
667 status = WLAN_STATUS_INVALID_GROUP_CIPHER;
668 break;
669 case WPA_INVALID_PAIRWISE:
670 reason = WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID;
671 status = WLAN_STATUS_INVALID_PAIRWISE_CIPHER;
672 break;
673 case WPA_INVALID_AKMP:
674 reason = WLAN_REASON_AKMP_NOT_VALID;
675 status = WLAN_STATUS_INVALID_AKMP;
676 break;
677 case WPA_NOT_ENABLED:
678 reason = WLAN_REASON_INVALID_IE;
679 status = WLAN_STATUS_INVALID_ELEMENT;
680 break;
681 case WPA_ALLOC_FAIL:
682 reason = WLAN_REASON_UNSPECIFIED;
683 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
684 break;
685 case WPA_MGMT_FRAME_PROTECTION_VIOLATION:
686 reason = WLAN_REASON_INVALID_IE;
687 status = WLAN_STATUS_INVALID_ELEMENT;
688 break;
689 case WPA_INVALID_MGMT_GROUP_CIPHER:
690 reason = WLAN_REASON_CIPHER_SUITE_REJECTED;
691 status = WLAN_STATUS_CIPHER_OUT_OF_POLICY;
692 break;
693 case WPA_INVALID_MDIE:
694 reason = WLAN_REASON_INVALID_MDE;
695 status = WLAN_STATUS_INVALID_MDE;
696 break;
697 case WPA_INVALID_PROTO:
698 reason = WLAN_REASON_INVALID_IE;
699 status = WLAN_STATUS_INVALID_ELEMENT;
700 break;
701 case WPA_INVALID_PMKID:
702 reason = WLAN_REASON_INVALID_PMKID;
703 status = WLAN_STATUS_INVALID_PMKID;
704 break;
705 case WPA_DENIED_OTHER_REASON:
706 reason = WLAN_REASON_UNSPECIFIED;
707 status = WLAN_STATUS_ASSOC_DENIED_UNSPEC;
708 break;
709 }
710 if (status != WLAN_STATUS_SUCCESS) {
711 wpa_printf(MSG_DEBUG,
712 "WPA/RSN information element rejected? (res %u)",
713 res);
714 wpa_hexdump(MSG_DEBUG, "IE", ie, ielen);
715 goto fail;
716 }
717
718 if (wpa_auth_uses_mfp(sta->wpa_sm))
719 sta->flags |= WLAN_STA_MFP;
720 else
721 sta->flags &= ~WLAN_STA_MFP;
722
723 if (wpa_auth_uses_spp_amsdu(sta->wpa_sm))
724 sta->flags |= WLAN_STA_SPP_AMSDU;
725 else
726 sta->flags &= ~WLAN_STA_SPP_AMSDU;
727
728 #ifdef CONFIG_IEEE80211R_AP
729 if (sta->auth_alg == WLAN_AUTH_FT) {
730 status = wpa_ft_validate_reassoc(sta->wpa_sm, req_ies,
731 req_ies_len);
732 if (status != WLAN_STATUS_SUCCESS) {
733 if (status == WLAN_STATUS_INVALID_PMKID)
734 reason = WLAN_REASON_INVALID_IE;
735 if (status == WLAN_STATUS_INVALID_MDE)
736 reason = WLAN_REASON_INVALID_IE;
737 if (status == WLAN_STATUS_INVALID_FTE)
738 reason = WLAN_REASON_INVALID_IE;
739 goto fail;
740 }
741 }
742 #endif /* CONFIG_IEEE80211R_AP */
743 #ifdef CONFIG_SAE
744 if (hapd->conf->sae_pwe == SAE_PWE_BOTH &&
745 sta->auth_alg == WLAN_AUTH_SAE &&
746 sta->sae && !sta->sae->h2e &&
747 ieee802_11_rsnx_capab_len(elems.rsnxe, elems.rsnxe_len,
748 WLAN_RSNX_CAPAB_SAE_H2E)) {
749 if (hapd->conf->sae_accept_h2e_without_use) {
750 wpa_printf(MSG_INFO, "SAE: " MACSTR
751 " indicates support for SAE H2E, but did not use it - accepting due to sae_accept_h2e_without_use",
752 MAC2STR(sta->addr));
753 } else {
754 wpa_printf(MSG_INFO, "SAE: " MACSTR
755 " indicates support for SAE H2E, but did not use it",
756 MAC2STR(sta->addr));
757 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
758 reason = WLAN_REASON_UNSPECIFIED;
759 goto fail;
760 }
761 }
762 #endif /* CONFIG_SAE */
763
764 wpa_auth_set_ssid_protection(
765 sta->wpa_sm,
766 hapd->conf->ssid_protection &&
767 ieee802_11_rsnx_capab_len(
768 elems.rsnxe, elems.rsnxe_len,
769 WLAN_RSNX_CAPAB_SSID_PROTECTION));
770 } else if (hapd->conf->wps_state) {
771 #ifdef CONFIG_WPS
772 struct wpabuf *wps;
773
774 if (req_ies)
775 wps = ieee802_11_vendor_ie_concat(req_ies, req_ies_len,
776 WPS_IE_VENDOR_TYPE);
777 else
778 wps = NULL;
779 #ifdef CONFIG_WPS_STRICT
780 if (wps && wps_validate_assoc_req(wps) < 0) {
781 reason = WLAN_REASON_INVALID_IE;
782 status = WLAN_STATUS_INVALID_ELEMENT;
783 wpabuf_free(wps);
784 goto fail;
785 }
786 #endif /* CONFIG_WPS_STRICT */
787 if (wps) {
788 sta->flags |= WLAN_STA_WPS;
789 if (wps_is_20(wps)) {
790 wpa_printf(MSG_DEBUG,
791 "WPS: STA supports WPS 2.0");
792 sta->flags |= WLAN_STA_WPS2;
793 }
794 } else
795 sta->flags |= WLAN_STA_MAYBE_WPS;
796 wpabuf_free(wps);
797 #endif /* CONFIG_WPS */
798 }
799 #ifdef CONFIG_WPS
800 skip_wpa_check:
801 #endif /* CONFIG_WPS */
802
803 #ifdef CONFIG_MBO
804 if (hapd->conf->mbo_enabled && (hapd->conf->wpa & 2) &&
805 elems.mbo && sta->cell_capa && !(sta->flags & WLAN_STA_MFP) &&
806 hapd->conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
807 wpa_printf(MSG_INFO,
808 "MBO: Reject WPA2 association without PMF");
809 return WLAN_STATUS_UNSPECIFIED_FAILURE;
810 }
811 #endif /* CONFIG_MBO */
812
813 #ifdef CONFIG_IEEE80211R_AP
814 p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, buf, sizeof(buf),
815 sta->auth_alg, req_ies, req_ies_len,
816 !elems.rsnxe, reassoc, sta->vlan_id);
817 if (!p) {
818 wpa_printf(MSG_DEBUG, "FT: Failed to write AssocResp IEs");
819 return WLAN_STATUS_UNSPECIFIED_FAILURE;
820 }
821 #endif /* CONFIG_IEEE80211R_AP */
822
823 #ifdef CONFIG_FILS
824 if (sta->auth_alg == WLAN_AUTH_FILS_SK ||
825 sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
826 sta->auth_alg == WLAN_AUTH_FILS_PK) {
827 int delay_assoc = 0;
828
829 if (!req_ies)
830 return WLAN_STATUS_UNSPECIFIED_FAILURE;
831
832 if (!wpa_fils_validate_fils_session(sta->wpa_sm, req_ies,
833 req_ies_len,
834 sta->fils_session)) {
835 wpa_printf(MSG_DEBUG,
836 "FILS: Session validation failed");
837 return WLAN_STATUS_UNSPECIFIED_FAILURE;
838 }
839
840 res = wpa_fils_validate_key_confirm(sta->wpa_sm, req_ies,
841 req_ies_len);
842 if (res < 0) {
843 wpa_printf(MSG_DEBUG,
844 "FILS: Key Confirm validation failed");
845 return WLAN_STATUS_UNSPECIFIED_FAILURE;
846 }
847
848 if (fils_process_hlp(hapd, sta, req_ies, req_ies_len) > 0) {
849 wpa_printf(MSG_DEBUG,
850 "FILS: Delaying Assoc Response (HLP)");
851 delay_assoc = 1;
852 } else {
853 wpa_printf(MSG_DEBUG,
854 "FILS: Going ahead with Assoc Response (no HLP)");
855 }
856
857 if (sta) {
858 wpa_printf(MSG_DEBUG, "FILS: HLP callback cleanup");
859 eloop_cancel_timeout(fils_hlp_timeout, hapd, sta);
860 os_free(sta->fils_pending_assoc_req);
861 sta->fils_pending_assoc_req = NULL;
862 sta->fils_pending_assoc_req_len = 0;
863 wpabuf_free(sta->fils_hlp_resp);
864 sta->fils_hlp_resp = NULL;
865 sta->fils_drv_assoc_finish = 0;
866 }
867
868 if (sta && delay_assoc && status == WLAN_STATUS_SUCCESS) {
869 u8 *req_tmp;
870
871 req_tmp = os_malloc(req_ies_len);
872 if (!req_tmp) {
873 wpa_printf(MSG_DEBUG,
874 "FILS: buffer allocation failed for assoc req");
875 goto fail;
876 }
877 os_memcpy(req_tmp, req_ies, req_ies_len);
878 sta->fils_pending_assoc_req = req_tmp;
879 sta->fils_pending_assoc_req_len = req_ies_len;
880 sta->fils_pending_assoc_is_reassoc = reassoc;
881 sta->fils_drv_assoc_finish = 1;
882 wpa_printf(MSG_DEBUG,
883 "FILS: Waiting for HLP processing before sending (Re)Association Response frame to "
884 MACSTR, MAC2STR(sta->addr));
885 eloop_register_timeout(
886 0, hapd->conf->fils_hlp_wait_time * 1024,
887 fils_hlp_timeout, hapd, sta);
888 return 0;
889 }
890 p = hostapd_eid_assoc_fils_session(sta->wpa_sm, p,
891 elems.fils_session,
892 sta->fils_hlp_resp);
893 if (!p)
894 goto fail;
895
896 wpa_hexdump(MSG_DEBUG, "FILS Assoc Resp BUF (IEs)",
897 buf, p - buf);
898 }
899 #endif /* CONFIG_FILS */
900
901 #ifdef CONFIG_OWE
902 if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) &&
903 !(iface->drv_flags2 & WPA_DRIVER_FLAGS2_OWE_OFFLOAD_AP) &&
904 wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_OWE &&
905 elems.owe_dh) {
906 u8 *npos;
907 u16 ret_status;
908
909 npos = owe_assoc_req_process(hapd, sta,
910 elems.owe_dh, elems.owe_dh_len,
911 p, sizeof(buf) - (p - buf),
912 &ret_status);
913 status = ret_status;
914 if (npos)
915 p = npos;
916
917 if (!npos &&
918 status == WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED) {
919 hostapd_sta_assoc(hapd, addr, reassoc, ret_status, buf,
920 p - buf);
921 return 0;
922 }
923
924 if (!npos || status != WLAN_STATUS_SUCCESS)
925 goto fail;
926 }
927 #endif /* CONFIG_OWE */
928
929 #ifdef CONFIG_DPP2
930 dpp_pfs_free(sta->dpp_pfs);
931 sta->dpp_pfs = NULL;
932
933 if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) &&
934 hapd->conf->dpp_netaccesskey && sta->wpa_sm &&
935 wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_DPP &&
936 elems.owe_dh) {
937 sta->dpp_pfs = dpp_pfs_init(
938 wpabuf_head(hapd->conf->dpp_netaccesskey),
939 wpabuf_len(hapd->conf->dpp_netaccesskey));
940 if (!sta->dpp_pfs) {
941 wpa_printf(MSG_DEBUG,
942 "DPP: Could not initialize PFS");
943 /* Try to continue without PFS */
944 goto pfs_fail;
945 }
946
947 if (dpp_pfs_process(sta->dpp_pfs, elems.owe_dh,
948 elems.owe_dh_len) < 0) {
949 dpp_pfs_free(sta->dpp_pfs);
950 sta->dpp_pfs = NULL;
951 reason = WLAN_REASON_UNSPECIFIED;
952 goto fail;
953 }
954 }
955
956 wpa_auth_set_dpp_z(sta->wpa_sm, sta->dpp_pfs ?
957 sta->dpp_pfs->secret : NULL);
958 pfs_fail:
959 #endif /* CONFIG_DPP2 */
960
961 if (elems.rrm_enabled &&
962 elems.rrm_enabled_len >= sizeof(sta->rrm_enabled_capa))
963 os_memcpy(sta->rrm_enabled_capa, elems.rrm_enabled,
964 sizeof(sta->rrm_enabled_capa));
965
966 #if defined(CONFIG_IEEE80211R_AP) || defined(CONFIG_FILS) || defined(CONFIG_OWE)
967 hostapd_sta_assoc(hapd, addr, reassoc, status, buf, p - buf);
968
969 if (sta->auth_alg == WLAN_AUTH_FT ||
970 sta->auth_alg == WLAN_AUTH_FILS_SK ||
971 sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
972 sta->auth_alg == WLAN_AUTH_FILS_PK)
973 updated = ap_sta_set_authorized_flag(hapd, sta, 1);
974 #else /* CONFIG_IEEE80211R_AP || CONFIG_FILS */
975 /* Keep compiler silent about unused variables */
976 if (status) {
977 }
978 #endif /* CONFIG_IEEE80211R_AP || CONFIG_FILS */
979
980 new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;
981 sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
982 sta->flags &= ~WLAN_STA_WNM_SLEEP_MODE;
983
984 hostapd_set_sta_flags(hapd, sta);
985
986 #ifdef CONFIG_IEEE80211BE
987 if (hostapd_process_assoc_ml_info(hapd, sta, req_ies, req_ies_len,
988 !!reassoc, WLAN_STATUS_SUCCESS,
989 true, NULL)) {
990 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
991 reason = WLAN_REASON_UNSPECIFIED;
992 goto fail;
993 }
994 #endif /* CONFIG_IEEE80211BE */
995
996 if (updated)
997 ap_sta_set_authorized_event(hapd, sta, 1);
998
999 if (reassoc && (sta->auth_alg == WLAN_AUTH_FT))
1000 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT);
1001 #ifdef CONFIG_FILS
1002 else if (sta->auth_alg == WLAN_AUTH_FILS_SK ||
1003 sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
1004 sta->auth_alg == WLAN_AUTH_FILS_PK)
1005 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FILS);
1006 #endif /* CONFIG_FILS */
1007 else
1008 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
1009
1010 hostapd_new_assoc_sta(hapd, sta, !new_assoc);
1011
1012 ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
1013
1014 #ifdef CONFIG_P2P
1015 if (req_ies) {
1016 p2p_group_notif_assoc(hapd->p2p_group, sta->addr,
1017 req_ies, req_ies_len);
1018 }
1019 #endif /* CONFIG_P2P */
1020
1021 if (elems.wfa_capab)
1022 hostapd_wfa_capab(hapd, sta, elems.wfa_capab,
1023 elems.wfa_capab + elems.wfa_capab_len);
1024
1025 return 0;
1026
1027 fail:
1028 #ifdef CONFIG_IEEE80211R_AP
1029 if (status >= 0)
1030 hostapd_sta_assoc(hapd, addr, reassoc, status, buf, p - buf);
1031 #endif /* CONFIG_IEEE80211R_AP */
1032 hostapd_drv_sta_disassoc(hapd, sta->addr, reason);
1033 ap_free_sta(hapd, sta);
1034 return -1;
1035 }
1036
1037
hostapd_remove_sta(struct hostapd_data * hapd,struct sta_info * sta)1038 static void hostapd_remove_sta(struct hostapd_data *hapd, struct sta_info *sta)
1039 {
1040 ap_sta_set_authorized(hapd, sta, 0);
1041 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
1042 hostapd_set_sta_flags(hapd, sta);
1043 wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
1044 sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
1045 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
1046 ap_free_sta(hapd, sta);
1047 }
1048
1049
1050 #ifdef CONFIG_IEEE80211BE
hostapd_notif_disassoc_mld(struct hostapd_data * assoc_hapd,struct sta_info * sta,const u8 * addr)1051 void hostapd_notif_disassoc_mld(struct hostapd_data *assoc_hapd,
1052 struct sta_info *sta, const u8 *addr)
1053 {
1054 unsigned int i;
1055 struct hostapd_data *tmp_hapd;
1056 struct hapd_interfaces *interfaces = assoc_hapd->iface->interfaces;
1057
1058 /* Remove STA entry in non-assoc links */
1059 for (i = 0; i < interfaces->count; i++) {
1060 struct sta_info *tmp_sta;
1061
1062 tmp_hapd = interfaces->iface[i]->bss[0];
1063
1064 if (!tmp_hapd->conf->mld_ap ||
1065 assoc_hapd == tmp_hapd ||
1066 !hostapd_is_ml_partner(assoc_hapd, tmp_hapd))
1067 continue;
1068
1069 tmp_sta = ap_get_sta(tmp_hapd, addr);
1070 if (tmp_sta)
1071 ap_free_sta(tmp_hapd, tmp_sta);
1072 }
1073
1074 /* Remove STA in assoc link */
1075 hostapd_remove_sta(assoc_hapd, sta);
1076 }
1077 #endif /* CONFIG_IEEE80211BE */
1078
1079
hostapd_notif_disassoc(struct hostapd_data * hapd,const u8 * addr)1080 void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr)
1081 {
1082 struct sta_info *sta;
1083
1084 if (addr == NULL) {
1085 /*
1086 * This could potentially happen with unexpected event from the
1087 * driver wrapper. This was seen at least in one case where the
1088 * driver ended up reporting a station mode event while hostapd
1089 * was running, so better make sure we stop processing such an
1090 * event here.
1091 */
1092 wpa_printf(MSG_DEBUG,
1093 "hostapd_notif_disassoc: Skip event with no address");
1094 return;
1095 }
1096
1097 hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
1098 HOSTAPD_LEVEL_INFO, "disassociated");
1099
1100 sta = ap_get_sta(hapd, addr);
1101 #ifdef CONFIG_IEEE80211BE
1102 if (hostapd_is_multiple_link_mld(hapd)) {
1103 struct hostapd_data *assoc_hapd;
1104 unsigned int i;
1105
1106 if (!sta) {
1107 /* Find non-MLO cases from any of the affiliated AP
1108 * links. */
1109 for (i = 0; i < hapd->iface->interfaces->count; ++i) {
1110 struct hostapd_iface *h =
1111 hapd->iface->interfaces->iface[i];
1112 struct hostapd_data *h_hapd = h->bss[0];
1113 struct hostapd_bss_config *hconf = h_hapd->conf;
1114
1115 if (!hconf->mld_ap ||
1116 !hostapd_is_ml_partner(hapd, h_hapd))
1117 continue;
1118
1119 sta = ap_get_sta(h_hapd, addr);
1120 if (sta) {
1121 if (!sta->mld_info.mld_sta) {
1122 hapd = h_hapd;
1123 goto legacy;
1124 }
1125 break;
1126 }
1127 }
1128 } else if (!sta->mld_info.mld_sta) {
1129 goto legacy;
1130 }
1131 if (!sta) {
1132 wpa_printf(MSG_DEBUG,
1133 "Disassociation notification for unknown STA "
1134 MACSTR, MAC2STR(addr));
1135 return;
1136 }
1137 sta = hostapd_ml_get_assoc_sta(hapd, sta, &assoc_hapd);
1138 if (sta)
1139 hostapd_notif_disassoc_mld(assoc_hapd, sta, addr);
1140 return;
1141 }
1142
1143 legacy:
1144 #endif /* CONFIG_IEEE80211BE */
1145 if (sta == NULL) {
1146 wpa_printf(MSG_DEBUG,
1147 "Disassociation notification for unknown STA "
1148 MACSTR, MAC2STR(addr));
1149 return;
1150 }
1151
1152 hostapd_remove_sta(hapd, sta);
1153 }
1154
1155
hostapd_event_sta_low_ack(struct hostapd_data * hapd,const u8 * addr)1156 void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr)
1157 {
1158 struct sta_info *sta = ap_get_sta(hapd, addr);
1159 #ifdef CONFIG_IEEE80211BE
1160 struct hostapd_data *orig_hapd = hapd;
1161
1162 if (!sta && hapd->conf->mld_ap) {
1163 hapd = hostapd_find_by_sta(hapd->iface, addr, true, &sta);
1164 if (!hapd) {
1165 wpa_printf(MSG_DEBUG,
1166 "No partner link BSS found for STA " MACSTR
1167 " - fallback to received context",
1168 MAC2STR(addr));
1169 hapd = orig_hapd;
1170 }
1171 }
1172 #endif /* CONFIG_IEEE80211BE */
1173
1174 if (!sta || !hapd->conf->disassoc_low_ack || sta->agreed_to_steer)
1175 return;
1176
1177 hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
1178 HOSTAPD_LEVEL_INFO,
1179 "disconnected due to excessive missing ACKs");
1180 hostapd_drv_sta_disassoc(hapd, addr, WLAN_REASON_DISASSOC_LOW_ACK);
1181 ap_sta_disassociate(hapd, sta, WLAN_REASON_DISASSOC_LOW_ACK);
1182 }
1183
1184
hostapd_event_sta_opmode_changed(struct hostapd_data * hapd,const u8 * addr,enum smps_mode smps_mode,enum chan_width chan_width,u8 rx_nss)1185 void hostapd_event_sta_opmode_changed(struct hostapd_data *hapd, const u8 *addr,
1186 enum smps_mode smps_mode,
1187 enum chan_width chan_width, u8 rx_nss)
1188 {
1189 struct sta_info *sta = ap_get_sta(hapd, addr);
1190 const char *txt;
1191
1192 if (!sta)
1193 return;
1194
1195 switch (smps_mode) {
1196 case SMPS_AUTOMATIC:
1197 txt = "automatic";
1198 break;
1199 case SMPS_OFF:
1200 txt = "off";
1201 break;
1202 case SMPS_DYNAMIC:
1203 txt = "dynamic";
1204 break;
1205 case SMPS_STATIC:
1206 txt = "static";
1207 break;
1208 default:
1209 txt = NULL;
1210 break;
1211 }
1212 if (txt) {
1213 wpa_msg(hapd->msg_ctx, MSG_INFO, STA_OPMODE_SMPS_MODE_CHANGED
1214 MACSTR " %s", MAC2STR(addr), txt);
1215 }
1216
1217 switch (chan_width) {
1218 case CHAN_WIDTH_20_NOHT:
1219 txt = "20(no-HT)";
1220 break;
1221 case CHAN_WIDTH_20:
1222 txt = "20";
1223 break;
1224 case CHAN_WIDTH_40:
1225 txt = "40";
1226 break;
1227 case CHAN_WIDTH_80:
1228 txt = "80";
1229 break;
1230 case CHAN_WIDTH_80P80:
1231 txt = "80+80";
1232 break;
1233 case CHAN_WIDTH_160:
1234 txt = "160";
1235 break;
1236 case CHAN_WIDTH_320:
1237 txt = "320";
1238 break;
1239 default:
1240 txt = NULL;
1241 break;
1242 }
1243 if (txt) {
1244 wpa_msg(hapd->msg_ctx, MSG_INFO, STA_OPMODE_MAX_BW_CHANGED
1245 MACSTR " %s", MAC2STR(addr), txt);
1246 }
1247
1248 if (rx_nss != 0xff) {
1249 wpa_msg(hapd->msg_ctx, MSG_INFO, STA_OPMODE_N_SS_CHANGED
1250 MACSTR " %d", MAC2STR(addr), rx_nss);
1251 }
1252 }
1253
1254
hostapd_event_ch_switch(struct hostapd_data * hapd,int freq,int ht,int offset,int width,int cf1,int cf2,u16 punct_bitmap,int finished)1255 void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
1256 int offset, int width, int cf1, int cf2,
1257 u16 punct_bitmap, int finished)
1258 {
1259 #ifdef NEED_AP_MLME
1260 int channel, chwidth, is_dfs0, is_dfs;
1261 u8 seg0_idx = 0, seg1_idx = 0, op_class, chan_no;
1262 size_t i;
1263
1264 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
1265 HOSTAPD_LEVEL_INFO,
1266 "driver %s channel switch: iface->freq=%d, freq=%d, ht=%d, vht_ch=0x%x, he_ch=0x%x, eht_ch=0x%x, offset=%d, width=%d (%s), cf1=%d, cf2=%d, puncturing_bitmap=0x%x",
1267 finished ? "had" : "starting",
1268 hapd->iface->freq,
1269 freq, ht, hapd->iconf->ch_switch_vht_config,
1270 hapd->iconf->ch_switch_he_config,
1271 hapd->iconf->ch_switch_eht_config, offset,
1272 width, channel_width_to_string(width), cf1, cf2,
1273 punct_bitmap);
1274
1275 if (!hapd->iface->current_mode) {
1276 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
1277 HOSTAPD_LEVEL_WARNING,
1278 "ignore channel switch since the interface is not yet ready");
1279 return;
1280 }
1281
1282 /* Check if any of configured channels require DFS */
1283 is_dfs0 = hostapd_is_dfs_required(hapd->iface);
1284 hapd->iface->freq = freq;
1285
1286 channel = hostapd_hw_get_channel(hapd, freq);
1287 if (!channel) {
1288 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
1289 HOSTAPD_LEVEL_WARNING,
1290 "driver switched to bad channel!");
1291 return;
1292 }
1293
1294 switch (width) {
1295 case CHAN_WIDTH_80:
1296 chwidth = CONF_OPER_CHWIDTH_80MHZ;
1297 break;
1298 case CHAN_WIDTH_80P80:
1299 chwidth = CONF_OPER_CHWIDTH_80P80MHZ;
1300 break;
1301 case CHAN_WIDTH_160:
1302 chwidth = CONF_OPER_CHWIDTH_160MHZ;
1303 break;
1304 case CHAN_WIDTH_320:
1305 chwidth = CONF_OPER_CHWIDTH_320MHZ;
1306 break;
1307 case CHAN_WIDTH_20_NOHT:
1308 case CHAN_WIDTH_20:
1309 case CHAN_WIDTH_40:
1310 default:
1311 chwidth = CONF_OPER_CHWIDTH_USE_HT;
1312 break;
1313 }
1314
1315 /* The operating channel changed when CSA finished, so need to update
1316 * hw_mode for all following operations to cover the cases where the
1317 * driver changed the operating band. */
1318 if (finished && hostapd_csa_update_hwmode(hapd->iface))
1319 return;
1320
1321 switch (hapd->iface->current_mode->mode) {
1322 case HOSTAPD_MODE_IEEE80211A:
1323 if (cf1 == 5935)
1324 seg0_idx = (cf1 - 5925) / 5;
1325 else if (cf1 > 5950)
1326 seg0_idx = (cf1 - 5950) / 5;
1327 else if (cf1 > 5000)
1328 seg0_idx = (cf1 - 5000) / 5;
1329
1330 if (cf2 == 5935)
1331 seg1_idx = (cf2 - 5925) / 5;
1332 else if (cf2 > 5950)
1333 seg1_idx = (cf2 - 5950) / 5;
1334 else if (cf2 > 5000)
1335 seg1_idx = (cf2 - 5000) / 5;
1336 break;
1337 default:
1338 ieee80211_freq_to_chan(cf1, &seg0_idx);
1339 ieee80211_freq_to_chan(cf2, &seg1_idx);
1340 break;
1341 }
1342
1343 hapd->iconf->channel = channel;
1344 hapd->iconf->ieee80211n = ht;
1345 if (!ht)
1346 hapd->iconf->ieee80211ac = 0;
1347 if (hapd->iconf->ch_switch_vht_config) {
1348 /* CHAN_SWITCH VHT config */
1349 if (hapd->iconf->ch_switch_vht_config &
1350 CH_SWITCH_VHT_ENABLED)
1351 hapd->iconf->ieee80211ac = 1;
1352 else if (hapd->iconf->ch_switch_vht_config &
1353 CH_SWITCH_VHT_DISABLED)
1354 hapd->iconf->ieee80211ac = 0;
1355 }
1356 if (hapd->iconf->ch_switch_he_config) {
1357 /* CHAN_SWITCH HE config */
1358 if (hapd->iconf->ch_switch_he_config &
1359 CH_SWITCH_HE_ENABLED) {
1360 hapd->iconf->ieee80211ax = 1;
1361 if (hapd->iface->freq > 4000 &&
1362 hapd->iface->freq < 5895)
1363 hapd->iconf->ieee80211ac = 1;
1364 }
1365 else if (hapd->iconf->ch_switch_he_config &
1366 CH_SWITCH_HE_DISABLED)
1367 hapd->iconf->ieee80211ax = 0;
1368 }
1369 #ifdef CONFIG_IEEE80211BE
1370 if (hapd->iconf->ch_switch_eht_config) {
1371 /* CHAN_SWITCH EHT config */
1372 if (hapd->iconf->ch_switch_eht_config &
1373 CH_SWITCH_EHT_ENABLED) {
1374 hapd->iconf->ieee80211be = 1;
1375 hapd->iconf->ieee80211ax = 1;
1376 if (!is_6ghz_freq(hapd->iface->freq) &&
1377 hapd->iface->freq > 4000)
1378 hapd->iconf->ieee80211ac = 1;
1379 } else if (hapd->iconf->ch_switch_eht_config &
1380 CH_SWITCH_EHT_DISABLED)
1381 hapd->iconf->ieee80211be = 0;
1382 }
1383 #endif /* CONFIG_IEEE80211BE */
1384 hapd->iconf->ch_switch_vht_config = 0;
1385 hapd->iconf->ch_switch_he_config = 0;
1386 hapd->iconf->ch_switch_eht_config = 0;
1387
1388 if (width == CHAN_WIDTH_40 || width == CHAN_WIDTH_80 ||
1389 width == CHAN_WIDTH_80P80 || width == CHAN_WIDTH_160 ||
1390 width == CHAN_WIDTH_320)
1391 hapd->iconf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
1392 else if (width == CHAN_WIDTH_20 || width == CHAN_WIDTH_20_NOHT)
1393 hapd->iconf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
1394
1395 hapd->iconf->secondary_channel = offset;
1396 if (ieee80211_freq_to_channel_ext(freq, offset, chwidth,
1397 &op_class, &chan_no) !=
1398 NUM_HOSTAPD_MODES)
1399 hapd->iconf->op_class = op_class;
1400 hostapd_set_oper_chwidth(hapd->iconf, chwidth);
1401 hostapd_set_oper_centr_freq_seg0_idx(hapd->iconf, seg0_idx);
1402 hostapd_set_oper_centr_freq_seg1_idx(hapd->iconf, seg1_idx);
1403 /* Auto-detect new bw320_offset */
1404 hostapd_set_and_check_bw320_offset(hapd->iconf, 0);
1405 #ifdef CONFIG_IEEE80211BE
1406 hapd->iconf->punct_bitmap = punct_bitmap;
1407 #endif /* CONFIG_IEEE80211BE */
1408 if (hapd->iconf->ieee80211ac) {
1409 hapd->iconf->vht_capab &= ~VHT_CAP_SUPP_CHAN_WIDTH_MASK;
1410 if (chwidth == CONF_OPER_CHWIDTH_160MHZ)
1411 hapd->iconf->vht_capab |=
1412 VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
1413 else if (chwidth == CONF_OPER_CHWIDTH_80P80MHZ)
1414 hapd->iconf->vht_capab |=
1415 VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
1416 }
1417
1418 is_dfs = ieee80211_is_dfs(freq, hapd->iface->hw_features,
1419 hapd->iface->num_hw_features);
1420
1421 wpa_msg(hapd->msg_ctx, MSG_INFO,
1422 "%sfreq=%d ht_enabled=%d ch_offset=%d ch_width=%s cf1=%d cf2=%d is_dfs0=%d dfs=%d puncturing_bitmap=0x%04x",
1423 finished ? WPA_EVENT_CHANNEL_SWITCH :
1424 WPA_EVENT_CHANNEL_SWITCH_STARTED,
1425 freq, ht, offset, channel_width_to_string(width),
1426 cf1, cf2, is_dfs0, is_dfs, punct_bitmap);
1427 if (!finished)
1428 return;
1429
1430 if (hapd->csa_in_progress &&
1431 freq == hapd->cs_freq_params.freq) {
1432 hostapd_cleanup_cs_params(hapd);
1433 ieee802_11_set_beacon(hapd);
1434
1435 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED
1436 "freq=%d dfs=%d", freq, is_dfs);
1437 } else if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) {
1438 /* Complete AP configuration for the first bring up. */
1439 if (is_dfs0 > 0 &&
1440 hostapd_is_dfs_required(hapd->iface) <= 0 &&
1441 hapd->iface->state != HAPD_IFACE_ENABLED) {
1442 /* Fake a CAC start bit to skip setting channel */
1443 hapd->iface->cac_started = 1;
1444 hostapd_setup_interface_complete(hapd->iface, 0);
1445 }
1446 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED
1447 "freq=%d dfs=%d", freq, is_dfs);
1448 } else if (is_dfs &&
1449 hostapd_is_dfs_required(hapd->iface) &&
1450 !hostapd_is_dfs_chan_available(hapd->iface) &&
1451 !hapd->iface->cac_started) {
1452 hostapd_disable_iface(hapd->iface);
1453 hostapd_enable_iface(hapd->iface);
1454 }
1455
1456 for (i = 0; i < hapd->iface->num_bss; i++)
1457 hostapd_neighbor_set_own_report(hapd->iface->bss[i]);
1458
1459 #ifdef CONFIG_OCV
1460 if (hapd->conf->ocv &&
1461 !(hapd->iface->drv_flags2 &
1462 WPA_DRIVER_FLAGS2_SA_QUERY_OFFLOAD_AP)) {
1463 struct sta_info *sta;
1464 bool check_sa_query = false;
1465
1466 for (sta = hapd->sta_list; sta; sta = sta->next) {
1467 if (wpa_auth_uses_ocv(sta->wpa_sm) &&
1468 !(sta->flags & WLAN_STA_WNM_SLEEP_MODE)) {
1469 sta->post_csa_sa_query = 1;
1470 check_sa_query = true;
1471 }
1472 }
1473
1474 if (check_sa_query) {
1475 wpa_printf(MSG_DEBUG,
1476 "OCV: Check post-CSA SA Query initiation in 15 seconds");
1477 eloop_register_timeout(15, 0,
1478 hostapd_ocv_check_csa_sa_query,
1479 hapd, NULL);
1480 }
1481 }
1482 #endif /* CONFIG_OCV */
1483 #endif /* NEED_AP_MLME */
1484 }
1485
1486
hostapd_event_connect_failed_reason(struct hostapd_data * hapd,const u8 * addr,int reason_code)1487 void hostapd_event_connect_failed_reason(struct hostapd_data *hapd,
1488 const u8 *addr, int reason_code)
1489 {
1490 switch (reason_code) {
1491 case MAX_CLIENT_REACHED:
1492 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_REJECTED_MAX_STA MACSTR,
1493 MAC2STR(addr));
1494 break;
1495 case BLOCKED_CLIENT:
1496 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_REJECTED_BLOCKED_STA MACSTR,
1497 MAC2STR(addr));
1498 break;
1499 }
1500 }
1501
1502
1503 #ifdef CONFIG_ACS
hostapd_acs_channel_selected(struct hostapd_data * hapd,struct acs_selected_channels * acs_res)1504 void hostapd_acs_channel_selected(struct hostapd_data *hapd,
1505 struct acs_selected_channels *acs_res)
1506 {
1507 int ret, i;
1508 int err = 0;
1509 struct hostapd_channel_data *pri_chan;
1510
1511 #ifdef CONFIG_IEEE80211BE
1512 if (acs_res->link_id != -1) {
1513 hapd = hostapd_mld_get_link_bss(hapd, acs_res->link_id);
1514 if (!hapd) {
1515 wpa_printf(MSG_ERROR,
1516 "MLD: Failed to get link BSS for EVENT_ACS_CHANNEL_SELECTED link_id=%d",
1517 acs_res->link_id);
1518 return;
1519 }
1520 }
1521 #endif /* CONFIG_IEEE80211BE */
1522
1523 if (hapd->iconf->channel) {
1524 wpa_printf(MSG_INFO, "ACS: Channel was already set to %d",
1525 hapd->iconf->channel);
1526 return;
1527 }
1528
1529 hapd->iface->freq = acs_res->pri_freq;
1530
1531 if (!hapd->iface->current_mode) {
1532 for (i = 0; i < hapd->iface->num_hw_features; i++) {
1533 struct hostapd_hw_modes *mode =
1534 &hapd->iface->hw_features[i];
1535
1536 if (mode->mode == acs_res->hw_mode) {
1537 if (hapd->iface->freq > 0 &&
1538 !hw_mode_get_channel(mode,
1539 hapd->iface->freq,
1540 NULL))
1541 continue;
1542 hapd->iface->current_mode = mode;
1543 break;
1544 }
1545 }
1546 if (!hapd->iface->current_mode) {
1547 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
1548 HOSTAPD_LEVEL_WARNING,
1549 "driver selected to bad hw_mode");
1550 err = 1;
1551 goto out;
1552 }
1553 }
1554
1555 if (!acs_res->pri_freq) {
1556 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
1557 HOSTAPD_LEVEL_WARNING,
1558 "driver switched to bad channel");
1559 err = 1;
1560 goto out;
1561 }
1562 pri_chan = hw_get_channel_freq(hapd->iface->current_mode->mode,
1563 acs_res->pri_freq, NULL,
1564 hapd->iface->hw_features,
1565 hapd->iface->num_hw_features);
1566 if (!pri_chan) {
1567 wpa_printf(MSG_ERROR,
1568 "ACS: Could not determine primary channel number from pri_freq %u",
1569 acs_res->pri_freq);
1570 err = 1;
1571 goto out;
1572 }
1573
1574 hapd->iconf->channel = pri_chan->chan;
1575 hapd->iconf->acs = 1;
1576
1577 if (acs_res->sec_freq == 0)
1578 hapd->iconf->secondary_channel = 0;
1579 else if (acs_res->sec_freq < acs_res->pri_freq)
1580 hapd->iconf->secondary_channel = -1;
1581 else if (acs_res->sec_freq > acs_res->pri_freq)
1582 hapd->iconf->secondary_channel = 1;
1583 else {
1584 wpa_printf(MSG_ERROR, "Invalid secondary channel!");
1585 err = 1;
1586 goto out;
1587 }
1588
1589 hapd->iconf->edmg_channel = acs_res->edmg_channel;
1590
1591 if (hapd->iface->conf->ieee80211ac || hapd->iface->conf->ieee80211ax) {
1592 /* set defaults for backwards compatibility */
1593 hostapd_set_oper_centr_freq_seg1_idx(hapd->iconf, 0);
1594 hostapd_set_oper_centr_freq_seg0_idx(hapd->iconf, 0);
1595 hostapd_set_oper_chwidth(hapd->iconf, CONF_OPER_CHWIDTH_USE_HT);
1596 if (acs_res->ch_width == 40) {
1597 if (is_6ghz_freq(acs_res->pri_freq))
1598 hostapd_set_oper_centr_freq_seg0_idx(
1599 hapd->iconf,
1600 acs_res->vht_seg0_center_ch);
1601 } else if (acs_res->ch_width == 80) {
1602 hostapd_set_oper_centr_freq_seg0_idx(
1603 hapd->iconf, acs_res->vht_seg0_center_ch);
1604 if (acs_res->vht_seg1_center_ch == 0) {
1605 hostapd_set_oper_chwidth(
1606 hapd->iconf, CONF_OPER_CHWIDTH_80MHZ);
1607 } else {
1608 hostapd_set_oper_chwidth(
1609 hapd->iconf,
1610 CONF_OPER_CHWIDTH_80P80MHZ);
1611 hostapd_set_oper_centr_freq_seg1_idx(
1612 hapd->iconf,
1613 acs_res->vht_seg1_center_ch);
1614 }
1615 } else if (acs_res->ch_width == 160) {
1616 hostapd_set_oper_chwidth(hapd->iconf,
1617 CONF_OPER_CHWIDTH_160MHZ);
1618 hostapd_set_oper_centr_freq_seg0_idx(
1619 hapd->iconf, acs_res->vht_seg1_center_ch);
1620 }
1621 }
1622
1623 #ifdef CONFIG_IEEE80211BE
1624 if (hapd->iface->conf->ieee80211be && acs_res->ch_width == 320) {
1625 hostapd_set_oper_chwidth(hapd->iconf, CONF_OPER_CHWIDTH_320MHZ);
1626 hostapd_set_oper_centr_freq_seg0_idx(
1627 hapd->iconf, acs_res->vht_seg1_center_ch);
1628 hostapd_set_oper_centr_freq_seg1_idx(hapd->iconf, 0);
1629 }
1630
1631 if (hapd->iface->conf->ieee80211be && acs_res->puncture_bitmap)
1632 hapd->iconf->punct_bitmap = acs_res->puncture_bitmap;
1633 #endif /* CONFIG_IEEE80211BE */
1634
1635 out:
1636 ret = hostapd_acs_completed(hapd->iface, err);
1637 if (ret) {
1638 wpa_printf(MSG_ERROR,
1639 "ACS: Possibly channel configuration is invalid");
1640 }
1641 }
1642 #endif /* CONFIG_ACS */
1643
1644
hostapd_probe_req_rx(struct hostapd_data * hapd,const u8 * sa,const u8 * da,const u8 * bssid,const u8 * ie,size_t ie_len,int ssi_signal)1645 int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, const u8 *da,
1646 const u8 *bssid, const u8 *ie, size_t ie_len,
1647 int ssi_signal)
1648 {
1649 size_t i;
1650 int ret = 0;
1651
1652 if (sa == NULL || ie == NULL)
1653 return -1;
1654
1655 random_add_randomness(sa, ETH_ALEN);
1656 for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++) {
1657 if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx,
1658 sa, da, bssid, ie, ie_len,
1659 ssi_signal) > 0) {
1660 ret = 1;
1661 break;
1662 }
1663 }
1664 return ret;
1665 }
1666
1667
1668 #ifdef HOSTAPD
1669
1670 #ifdef CONFIG_IEEE80211R_AP
hostapd_notify_auth_ft_finish(void * ctx,const u8 * dst,u16 auth_transaction,u16 status,const u8 * ies,size_t ies_len)1671 static void hostapd_notify_auth_ft_finish(void *ctx, const u8 *dst,
1672 u16 auth_transaction, u16 status,
1673 const u8 *ies, size_t ies_len)
1674 {
1675 struct hostapd_data *hapd = ctx;
1676 struct sta_info *sta;
1677
1678 sta = ap_get_sta(hapd, dst);
1679 if (sta == NULL)
1680 return;
1681
1682 hostapd_logger(hapd, dst, HOSTAPD_MODULE_IEEE80211,
1683 HOSTAPD_LEVEL_DEBUG, "authentication OK (FT)");
1684 sta->flags |= WLAN_STA_AUTH;
1685
1686 hostapd_sta_auth(hapd, dst, auth_transaction, status, ies, ies_len);
1687 }
1688 #endif /* CONFIG_IEEE80211R_AP */
1689
1690
1691 #ifdef CONFIG_FILS
hostapd_notify_auth_fils_finish(struct hostapd_data * hapd,struct sta_info * sta,u16 resp,struct wpabuf * data,int pub)1692 static void hostapd_notify_auth_fils_finish(struct hostapd_data *hapd,
1693 struct sta_info *sta, u16 resp,
1694 struct wpabuf *data, int pub)
1695 {
1696 if (resp == WLAN_STATUS_SUCCESS) {
1697 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1698 HOSTAPD_LEVEL_DEBUG, "authentication OK (FILS)");
1699 sta->flags |= WLAN_STA_AUTH;
1700 wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
1701 sta->auth_alg = WLAN_AUTH_FILS_SK;
1702 mlme_authenticate_indication(hapd, sta);
1703 } else {
1704 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1705 HOSTAPD_LEVEL_DEBUG,
1706 "authentication failed (FILS)");
1707 }
1708
1709 hostapd_sta_auth(hapd, sta->addr, 2, resp,
1710 data ? wpabuf_head(data) : NULL,
1711 data ? wpabuf_len(data) : 0);
1712 wpabuf_free(data);
1713 }
1714 #endif /* CONFIG_FILS */
1715
1716
hostapd_notif_auth(struct hostapd_data * hapd,struct auth_info * rx_auth)1717 static void hostapd_notif_auth(struct hostapd_data *hapd,
1718 struct auth_info *rx_auth)
1719 {
1720 struct sta_info *sta;
1721 u16 status = WLAN_STATUS_SUCCESS;
1722
1723 sta = ap_get_sta(hapd, rx_auth->peer);
1724 if (!sta) {
1725 sta = ap_sta_add(hapd, rx_auth->peer);
1726 if (sta == NULL) {
1727 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1728 goto fail;
1729 }
1730 }
1731 sta->flags &= ~WLAN_STA_PREAUTH;
1732 ieee802_1x_notify_pre_auth(sta->eapol_sm, 0);
1733 #ifdef CONFIG_IEEE80211R_AP
1734 if (rx_auth->auth_type == WLAN_AUTH_FT && hapd->wpa_auth) {
1735 sta->auth_alg = WLAN_AUTH_FT;
1736 if (sta->wpa_sm == NULL)
1737 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
1738 sta->addr, NULL);
1739 if (sta->wpa_sm == NULL) {
1740 wpa_printf(MSG_DEBUG,
1741 "FT: Failed to initialize WPA state machine");
1742 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1743 goto fail;
1744 }
1745 wpa_ft_process_auth(sta->wpa_sm,
1746 rx_auth->auth_transaction, rx_auth->ies,
1747 rx_auth->ies_len,
1748 hostapd_notify_auth_ft_finish, hapd);
1749 return;
1750 }
1751 #endif /* CONFIG_IEEE80211R_AP */
1752
1753 #ifdef CONFIG_FILS
1754 if (rx_auth->auth_type == WLAN_AUTH_FILS_SK) {
1755 sta->auth_alg = WLAN_AUTH_FILS_SK;
1756 handle_auth_fils(hapd, sta, rx_auth->ies, rx_auth->ies_len,
1757 rx_auth->auth_type, rx_auth->auth_transaction,
1758 rx_auth->status_code,
1759 hostapd_notify_auth_fils_finish);
1760 return;
1761 }
1762 #endif /* CONFIG_FILS */
1763
1764 fail:
1765 hostapd_sta_auth(hapd, rx_auth->peer, rx_auth->auth_transaction + 1,
1766 status, NULL, 0);
1767 }
1768
1769
1770 #ifndef NEED_AP_MLME
hostapd_action_rx(struct hostapd_data * hapd,struct rx_mgmt * drv_mgmt)1771 static void hostapd_action_rx(struct hostapd_data *hapd,
1772 struct rx_mgmt *drv_mgmt)
1773 {
1774 struct ieee80211_mgmt *mgmt;
1775 struct sta_info *sta;
1776 size_t plen __maybe_unused;
1777 u16 fc;
1778 u8 *action __maybe_unused;
1779
1780 if (drv_mgmt->frame_len < IEEE80211_HDRLEN + 2 + 1)
1781 return;
1782
1783 plen = drv_mgmt->frame_len - IEEE80211_HDRLEN;
1784
1785 mgmt = (struct ieee80211_mgmt *) drv_mgmt->frame;
1786 fc = le_to_host16(mgmt->frame_control);
1787 if (WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_ACTION)
1788 return; /* handled by the driver */
1789
1790 action = (u8 *) &mgmt->u.action.u;
1791 wpa_printf(MSG_DEBUG, "RX_ACTION category %u action %u sa " MACSTR
1792 " da " MACSTR " plen %d",
1793 mgmt->u.action.category, *action,
1794 MAC2STR(mgmt->sa), MAC2STR(mgmt->da), (int) plen);
1795
1796 sta = ap_get_sta(hapd, mgmt->sa);
1797 if (sta == NULL) {
1798 wpa_printf(MSG_DEBUG, "%s: station not found", __func__);
1799 return;
1800 }
1801 #ifdef CONFIG_IEEE80211R_AP
1802 if (mgmt->u.action.category == WLAN_ACTION_FT) {
1803 wpa_ft_action_rx(sta->wpa_sm, (u8 *) &mgmt->u.action, plen);
1804 return;
1805 }
1806 #endif /* CONFIG_IEEE80211R_AP */
1807 if (mgmt->u.action.category == WLAN_ACTION_SA_QUERY) {
1808 ieee802_11_sa_query_action(hapd, mgmt, drv_mgmt->frame_len);
1809 return;
1810 }
1811 #ifdef CONFIG_WNM_AP
1812 if (mgmt->u.action.category == WLAN_ACTION_WNM) {
1813 ieee802_11_rx_wnm_action_ap(hapd, mgmt, drv_mgmt->frame_len);
1814 return;
1815 }
1816 #endif /* CONFIG_WNM_AP */
1817 #ifdef CONFIG_FST
1818 if (mgmt->u.action.category == WLAN_ACTION_FST && hapd->iface->fst) {
1819 fst_rx_action(hapd->iface->fst, mgmt, drv_mgmt->frame_len);
1820 return;
1821 }
1822 #endif /* CONFIG_FST */
1823 #ifdef CONFIG_DPP
1824 if (plen >= 2 + 4 &&
1825 mgmt->u.action.category == WLAN_ACTION_PUBLIC &&
1826 mgmt->u.action.u.vs_public_action.action ==
1827 WLAN_PA_VENDOR_SPECIFIC &&
1828 WPA_GET_BE24(mgmt->u.action.u.vs_public_action.oui) ==
1829 OUI_WFA &&
1830 mgmt->u.action.u.vs_public_action.variable[0] ==
1831 DPP_OUI_TYPE) {
1832 const u8 *pos, *end;
1833
1834 pos = mgmt->u.action.u.vs_public_action.oui;
1835 end = drv_mgmt->frame + drv_mgmt->frame_len;
1836 hostapd_dpp_rx_action(hapd, mgmt->sa, pos, end - pos,
1837 drv_mgmt->freq);
1838 return;
1839 }
1840 #endif /* CONFIG_DPP */
1841 #ifdef CONFIG_NAN_USD
1842 if (mgmt->u.action.category == WLAN_ACTION_PUBLIC && plen >= 5 &&
1843 mgmt->u.action.u.vs_public_action.action ==
1844 WLAN_PA_VENDOR_SPECIFIC &&
1845 WPA_GET_BE24(mgmt->u.action.u.vs_public_action.oui) ==
1846 OUI_WFA &&
1847 mgmt->u.action.u.vs_public_action.variable[0] == NAN_SDF_OUI_TYPE) {
1848 const u8 *pos, *end;
1849
1850 pos = mgmt->u.action.u.vs_public_action.variable;
1851 end = drv_mgmt->frame + drv_mgmt->frame_len;
1852 pos++;
1853 hostapd_nan_usd_rx_sdf(hapd, mgmt->sa, mgmt->bssid,
1854 drv_mgmt->freq, pos, end - pos);
1855 return;
1856 }
1857 #endif /* CONFIG_NAN_USD */
1858 }
1859 #endif /* NEED_AP_MLME */
1860
1861
1862 #ifdef NEED_AP_MLME
1863
1864 static struct hostapd_data *
switch_link_hapd(struct hostapd_data * hapd,int link_id)1865 switch_link_hapd(struct hostapd_data *hapd, int link_id)
1866 {
1867 #ifdef CONFIG_IEEE80211BE
1868 if (hapd->conf->mld_ap && link_id >= 0) {
1869 struct hostapd_data *link_bss;
1870
1871 link_bss = hostapd_mld_get_link_bss(hapd, link_id);
1872 if (link_bss)
1873 return link_bss;
1874 }
1875 #endif /* CONFIG_IEEE80211BE */
1876
1877 return hapd;
1878 }
1879
1880
1881 static struct hostapd_data *
switch_link_scan(struct hostapd_data * hapd,u64 scan_cookie)1882 switch_link_scan(struct hostapd_data *hapd, u64 scan_cookie)
1883 {
1884 #ifdef CONFIG_IEEE80211BE
1885 if (hapd->conf->mld_ap && scan_cookie != 0) {
1886 unsigned int i;
1887
1888 for (i = 0; i < hapd->iface->interfaces->count; i++) {
1889 struct hostapd_iface *h;
1890 struct hostapd_data *h_hapd;
1891
1892 h = hapd->iface->interfaces->iface[i];
1893 h_hapd = h->bss[0];
1894 if (!hostapd_is_ml_partner(hapd, h_hapd))
1895 continue;
1896
1897 if (h_hapd->scan_cookie == scan_cookie) {
1898 h_hapd->scan_cookie = 0;
1899 return h_hapd;
1900 }
1901 }
1902 }
1903 #endif /* CONFIG_IEEE80211BE */
1904
1905 return hapd;
1906 }
1907
1908
1909 #define HAPD_BROADCAST ((struct hostapd_data *) -1)
1910
get_hapd_bssid(struct hostapd_iface * iface,const u8 * bssid,int link_id)1911 static struct hostapd_data * get_hapd_bssid(struct hostapd_iface *iface,
1912 const u8 *bssid, int link_id)
1913 {
1914 size_t i;
1915
1916 if (bssid == NULL)
1917 return NULL;
1918 if (bssid[0] == 0xff && bssid[1] == 0xff && bssid[2] == 0xff &&
1919 bssid[3] == 0xff && bssid[4] == 0xff && bssid[5] == 0xff)
1920 return HAPD_BROADCAST;
1921 #ifdef CONFIG_NAN_USD
1922 if (nan_de_is_nan_network_id(bssid))
1923 return HAPD_BROADCAST; /* Process NAN Network ID like broadcast
1924 */
1925 #endif /* CONFIG_NAN_USD */
1926
1927 for (i = 0; i < iface->num_bss; i++) {
1928 struct hostapd_data *hapd;
1929 #ifdef CONFIG_IEEE80211BE
1930 struct hostapd_data *p_hapd;
1931 #endif /* CONFIG_IEEE80211BE */
1932
1933 hapd = iface->bss[i];
1934 if (ether_addr_equal(bssid, hapd->own_addr))
1935 return hapd;
1936
1937 #ifdef CONFIG_IEEE80211BE
1938 if (ether_addr_equal(bssid, hapd->own_addr) ||
1939 (hapd->conf->mld_ap &&
1940 ether_addr_equal(bssid, hapd->mld->mld_addr) &&
1941 link_id == hapd->mld_link_id))
1942 return hapd;
1943
1944 if (!hapd->conf->mld_ap)
1945 continue;
1946
1947 for_each_mld_link(p_hapd, hapd) {
1948 if (p_hapd == hapd)
1949 continue;
1950
1951 if (ether_addr_equal(bssid, p_hapd->own_addr) ||
1952 (ether_addr_equal(bssid, p_hapd->mld->mld_addr) &&
1953 link_id == p_hapd->mld_link_id))
1954 return p_hapd;
1955 }
1956 #endif /* CONFIG_IEEE80211BE */
1957 }
1958
1959 return NULL;
1960 }
1961
1962
hostapd_rx_from_unknown_sta(struct hostapd_data * hapd,const u8 * bssid,const u8 * addr,int wds)1963 static void hostapd_rx_from_unknown_sta(struct hostapd_data *hapd,
1964 const u8 *bssid, const u8 *addr,
1965 int wds)
1966 {
1967 hapd = get_hapd_bssid(hapd->iface, bssid, -1);
1968 if (hapd == NULL || hapd == HAPD_BROADCAST)
1969 return;
1970
1971 ieee802_11_rx_from_unknown(hapd, addr, wds);
1972 }
1973
1974
hostapd_mgmt_rx(struct hostapd_data * hapd,struct rx_mgmt * rx_mgmt)1975 static int hostapd_mgmt_rx(struct hostapd_data *hapd, struct rx_mgmt *rx_mgmt)
1976 {
1977 struct hostapd_iface *iface;
1978 const struct ieee80211_hdr *hdr;
1979 const u8 *bssid;
1980 struct hostapd_frame_info fi;
1981 int ret;
1982
1983 if (rx_mgmt->ctx)
1984 hapd = rx_mgmt->ctx;
1985 hapd = switch_link_hapd(hapd, rx_mgmt->link_id);
1986 iface = hapd->iface;
1987
1988 #ifdef CONFIG_TESTING_OPTIONS
1989 if (hapd->ext_mgmt_frame_handling) {
1990 size_t hex_len = 2 * rx_mgmt->frame_len + 1;
1991 char *hex = os_malloc(hex_len);
1992
1993 if (hex) {
1994 wpa_snprintf_hex(hex, hex_len, rx_mgmt->frame,
1995 rx_mgmt->frame_len);
1996 wpa_msg(hapd->msg_ctx, MSG_INFO, "MGMT-RX %s", hex);
1997 os_free(hex);
1998 }
1999 return 1;
2000 }
2001 #endif /* CONFIG_TESTING_OPTIONS */
2002
2003 hdr = (const struct ieee80211_hdr *) rx_mgmt->frame;
2004 bssid = get_hdr_bssid(hdr, rx_mgmt->frame_len);
2005 if (bssid == NULL)
2006 return 0;
2007
2008 hapd = get_hapd_bssid(iface, bssid, rx_mgmt->link_id);
2009
2010 if (!hapd) {
2011 u16 fc = le_to_host16(hdr->frame_control);
2012
2013 /*
2014 * Drop frames to unknown BSSIDs except for Beacon frames which
2015 * could be used to update neighbor information.
2016 */
2017 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
2018 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
2019 hapd = iface->bss[0];
2020 else
2021 return 0;
2022 }
2023
2024 os_memset(&fi, 0, sizeof(fi));
2025 fi.freq = rx_mgmt->freq;
2026 fi.datarate = rx_mgmt->datarate;
2027 fi.ssi_signal = rx_mgmt->ssi_signal;
2028
2029 if (hapd == HAPD_BROADCAST) {
2030 size_t i;
2031
2032 ret = 0;
2033 for (i = 0; i < iface->num_bss; i++) {
2034 /* if bss is set, driver will call this function for
2035 * each bss individually. */
2036 if (rx_mgmt->drv_priv &&
2037 (iface->bss[i]->drv_priv != rx_mgmt->drv_priv))
2038 continue;
2039
2040 if (ieee802_11_mgmt(iface->bss[i], rx_mgmt->frame,
2041 rx_mgmt->frame_len, &fi) > 0)
2042 ret = 1;
2043 }
2044 } else
2045 ret = ieee802_11_mgmt(hapd, rx_mgmt->frame, rx_mgmt->frame_len,
2046 &fi);
2047
2048 random_add_randomness(&fi, sizeof(fi));
2049
2050 return ret;
2051 }
2052
2053
hostapd_mgmt_tx_cb(struct hostapd_data * hapd,const u8 * buf,size_t len,u16 stype,int ok,int link_id)2054 static void hostapd_mgmt_tx_cb(struct hostapd_data *hapd, const u8 *buf,
2055 size_t len, u16 stype, int ok, int link_id)
2056 {
2057 struct ieee80211_hdr *hdr;
2058 struct hostapd_data *orig_hapd, *tmp_hapd;
2059 const u8 *bssid;
2060
2061 orig_hapd = hapd;
2062
2063 hdr = (struct ieee80211_hdr *) buf;
2064 hapd = switch_link_hapd(hapd, link_id);
2065 bssid = get_hdr_bssid(hdr, len);
2066 tmp_hapd = get_hapd_bssid(hapd->iface, bssid, link_id);
2067 if (tmp_hapd) {
2068 hapd = tmp_hapd;
2069 #ifdef CONFIG_IEEE80211BE
2070 } else if (hapd->conf->mld_ap && bssid &&
2071 ether_addr_equal(hapd->mld->mld_addr, bssid)) {
2072 /* AP MLD address match - use hapd pointer as-is */
2073 #endif /* CONFIG_IEEE80211BE */
2074 } else {
2075 return;
2076 }
2077
2078 if (hapd == HAPD_BROADCAST) {
2079 if (stype != WLAN_FC_STYPE_ACTION || len <= 25 ||
2080 buf[24] != WLAN_ACTION_PUBLIC)
2081 return;
2082 hapd = get_hapd_bssid(orig_hapd->iface, hdr->addr2, link_id);
2083 if (!hapd || hapd == HAPD_BROADCAST)
2084 return;
2085 /*
2086 * Allow processing of TX status for a Public Action frame that
2087 * used wildcard BBSID.
2088 */
2089 }
2090 ieee802_11_mgmt_cb(hapd, buf, len, stype, ok);
2091 }
2092
2093 #endif /* NEED_AP_MLME */
2094
2095
hostapd_event_new_sta(struct hostapd_data * hapd,const u8 * addr)2096 static int hostapd_event_new_sta(struct hostapd_data *hapd, const u8 *addr)
2097 {
2098 struct sta_info *sta = ap_get_sta(hapd, addr);
2099
2100 if (sta)
2101 return 0;
2102
2103 wpa_printf(MSG_DEBUG, "Data frame from unknown STA " MACSTR
2104 " - adding a new STA", MAC2STR(addr));
2105 sta = ap_sta_add(hapd, addr);
2106 if (sta) {
2107 hostapd_new_assoc_sta(hapd, sta, 0);
2108 } else {
2109 wpa_printf(MSG_DEBUG, "Failed to add STA entry for " MACSTR,
2110 MAC2STR(addr));
2111 return -1;
2112 }
2113
2114 return 0;
2115 }
2116
2117
hostapd_event_eapol_rx(struct hostapd_data * hapd,const u8 * src,const u8 * data,size_t data_len,enum frame_encryption encrypted,int link_id)2118 static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src,
2119 const u8 *data, size_t data_len,
2120 enum frame_encryption encrypted,
2121 int link_id)
2122 {
2123 struct hostapd_data *orig_hapd = hapd;
2124
2125 #ifdef CONFIG_IEEE80211BE
2126 hapd = switch_link_hapd(hapd, link_id);
2127 hapd = hostapd_find_by_sta(hapd->iface, src, true, NULL);
2128 #else /* CONFIG_IEEE80211BE */
2129 hapd = hostapd_find_by_sta(hapd->iface, src, false, NULL);
2130 #endif /* CONFIG_IEEE80211BE */
2131
2132 if (!hapd) {
2133 /* WLAN cases need to have an existing association, but non-WLAN
2134 * cases (mainly, wired IEEE 802.1X) need to be able to process
2135 * EAPOL frames from new devices that do not yet have a STA
2136 * entry and as such, do not get a match in
2137 * hostapd_find_by_sta(). */
2138 wpa_printf(MSG_DEBUG,
2139 "No STA-specific hostapd instance for EAPOL RX found - fall back to initial context");
2140 hapd = orig_hapd;
2141 }
2142
2143 ieee802_1x_receive(hapd, src, data, data_len, encrypted);
2144 }
2145
2146 #endif /* HOSTAPD */
2147
2148
2149 static struct hostapd_channel_data *
hostapd_get_mode_chan(struct hostapd_hw_modes * mode,unsigned int freq)2150 hostapd_get_mode_chan(struct hostapd_hw_modes *mode, unsigned int freq)
2151 {
2152 int i;
2153 struct hostapd_channel_data *chan;
2154
2155 for (i = 0; i < mode->num_channels; i++) {
2156 chan = &mode->channels[i];
2157 if ((unsigned int) chan->freq == freq)
2158 return chan;
2159 }
2160
2161 return NULL;
2162 }
2163
2164
hostapd_get_mode_channel(struct hostapd_iface * iface,unsigned int freq)2165 static struct hostapd_channel_data * hostapd_get_mode_channel(
2166 struct hostapd_iface *iface, unsigned int freq)
2167 {
2168 int i;
2169 struct hostapd_channel_data *chan;
2170
2171 for (i = 0; i < iface->num_hw_features; i++) {
2172 if (hostapd_hw_skip_mode(iface, &iface->hw_features[i]))
2173 continue;
2174 chan = hostapd_get_mode_chan(&iface->hw_features[i], freq);
2175 if (chan)
2176 return chan;
2177 }
2178
2179 return NULL;
2180 }
2181
2182
hostapd_update_nf(struct hostapd_iface * iface,struct hostapd_channel_data * chan,struct freq_survey * survey)2183 static void hostapd_update_nf(struct hostapd_iface *iface,
2184 struct hostapd_channel_data *chan,
2185 struct freq_survey *survey)
2186 {
2187 if (!iface->chans_surveyed) {
2188 chan->min_nf = survey->nf;
2189 iface->lowest_nf = survey->nf;
2190 } else {
2191 if (dl_list_empty(&chan->survey_list))
2192 chan->min_nf = survey->nf;
2193 else if (survey->nf < chan->min_nf)
2194 chan->min_nf = survey->nf;
2195 if (survey->nf < iface->lowest_nf)
2196 iface->lowest_nf = survey->nf;
2197 }
2198 }
2199
2200
hostapd_single_channel_get_survey(struct hostapd_iface * iface,struct survey_results * survey_res)2201 static void hostapd_single_channel_get_survey(struct hostapd_iface *iface,
2202 struct survey_results *survey_res)
2203 {
2204 struct hostapd_channel_data *chan;
2205 struct freq_survey *survey;
2206 u64 divisor, dividend;
2207
2208 survey = dl_list_first(&survey_res->survey_list, struct freq_survey,
2209 list);
2210 if (!survey || !survey->freq)
2211 return;
2212
2213 chan = hostapd_get_mode_channel(iface, survey->freq);
2214 if (!chan || chan->flag & HOSTAPD_CHAN_DISABLED)
2215 return;
2216
2217 wpa_printf(MSG_DEBUG,
2218 "Single Channel Survey: (freq=%d channel_time=%ld channel_time_busy=%ld)",
2219 survey->freq,
2220 (unsigned long int) survey->channel_time,
2221 (unsigned long int) survey->channel_time_busy);
2222
2223 if (survey->channel_time > iface->last_channel_time &&
2224 survey->channel_time > survey->channel_time_busy) {
2225 dividend = survey->channel_time_busy -
2226 iface->last_channel_time_busy;
2227 divisor = survey->channel_time - iface->last_channel_time;
2228
2229 iface->channel_utilization = dividend * 255 / divisor;
2230 wpa_printf(MSG_DEBUG, "Channel Utilization: %d",
2231 iface->channel_utilization);
2232 }
2233 iface->last_channel_time = survey->channel_time;
2234 iface->last_channel_time_busy = survey->channel_time_busy;
2235 }
2236
2237
hostapd_event_get_survey(struct hostapd_iface * iface,struct survey_results * survey_results)2238 void hostapd_event_get_survey(struct hostapd_iface *iface,
2239 struct survey_results *survey_results)
2240 {
2241 struct freq_survey *survey, *tmp;
2242 struct hostapd_channel_data *chan;
2243
2244 if (dl_list_empty(&survey_results->survey_list)) {
2245 wpa_printf(MSG_DEBUG, "No survey data received");
2246 return;
2247 }
2248
2249 if (survey_results->freq_filter) {
2250 hostapd_single_channel_get_survey(iface, survey_results);
2251 return;
2252 }
2253
2254 dl_list_for_each_safe(survey, tmp, &survey_results->survey_list,
2255 struct freq_survey, list) {
2256 chan = hostapd_get_mode_channel(iface, survey->freq);
2257 if (!chan)
2258 continue;
2259 if (chan->flag & HOSTAPD_CHAN_DISABLED)
2260 continue;
2261 if (!(chan->flag & HOSTAPD_CHAN_SURVEY_LIST_INITIALIZED))
2262 continue;
2263
2264 dl_list_del(&survey->list);
2265 dl_list_add_tail(&chan->survey_list, &survey->list);
2266
2267 hostapd_update_nf(iface, chan, survey);
2268
2269 iface->chans_surveyed++;
2270 }
2271 }
2272
2273
2274 #ifdef HOSTAPD
2275 #ifdef NEED_AP_MLME
2276
hostapd_event_iface_unavailable(struct hostapd_data * hapd)2277 static void hostapd_event_iface_unavailable(struct hostapd_data *hapd)
2278 {
2279 wpa_printf(MSG_DEBUG, "Interface %s is unavailable -- stopped",
2280 hapd->conf->iface);
2281
2282 if (hapd->csa_in_progress) {
2283 wpa_printf(MSG_INFO, "CSA failed (%s was stopped)",
2284 hapd->conf->iface);
2285 hostapd_switch_channel_fallback(hapd->iface,
2286 &hapd->cs_freq_params);
2287 }
2288
2289 /* Clear beacon_set_done so that the RNR and other beacon parameters
2290 * are properly updated. */
2291 hapd->beacon_set_done = 0;
2292 }
2293
2294
hostapd_event_dfs_radar_detected(struct hostapd_data * hapd,struct dfs_event * radar)2295 static void hostapd_event_dfs_radar_detected(struct hostapd_data *hapd,
2296 struct dfs_event *radar)
2297 {
2298 wpa_printf(MSG_DEBUG, "DFS radar detected on %d MHz", radar->freq);
2299 hostapd_dfs_radar_detected(hapd->iface, radar->freq, radar->ht_enabled,
2300 radar->chan_offset, radar->chan_width,
2301 radar->cf1, radar->cf2);
2302 }
2303
2304
hostapd_event_dfs_pre_cac_expired(struct hostapd_data * hapd,struct dfs_event * radar)2305 static void hostapd_event_dfs_pre_cac_expired(struct hostapd_data *hapd,
2306 struct dfs_event *radar)
2307 {
2308 wpa_printf(MSG_DEBUG, "DFS Pre-CAC expired on %d MHz", radar->freq);
2309 hostapd_dfs_pre_cac_expired(hapd->iface, radar->freq, radar->ht_enabled,
2310 radar->chan_offset, radar->chan_width,
2311 radar->cf1, radar->cf2);
2312 }
2313
2314
hostapd_event_dfs_cac_finished(struct hostapd_data * hapd,struct dfs_event * radar)2315 static void hostapd_event_dfs_cac_finished(struct hostapd_data *hapd,
2316 struct dfs_event *radar)
2317 {
2318 wpa_printf(MSG_DEBUG, "DFS CAC finished on %d MHz", radar->freq);
2319 hostapd_dfs_complete_cac(hapd->iface, 1, radar->freq, radar->ht_enabled,
2320 radar->chan_offset, radar->chan_width,
2321 radar->cf1, radar->cf2);
2322 }
2323
2324
hostapd_event_dfs_cac_aborted(struct hostapd_data * hapd,struct dfs_event * radar)2325 static void hostapd_event_dfs_cac_aborted(struct hostapd_data *hapd,
2326 struct dfs_event *radar)
2327 {
2328 wpa_printf(MSG_DEBUG, "DFS CAC aborted on %d MHz", radar->freq);
2329 hostapd_dfs_complete_cac(hapd->iface, 0, radar->freq, radar->ht_enabled,
2330 radar->chan_offset, radar->chan_width,
2331 radar->cf1, radar->cf2);
2332 }
2333
2334
hostapd_event_dfs_nop_finished(struct hostapd_data * hapd,struct dfs_event * radar)2335 static void hostapd_event_dfs_nop_finished(struct hostapd_data *hapd,
2336 struct dfs_event *radar)
2337 {
2338 wpa_printf(MSG_DEBUG, "DFS NOP finished on %d MHz", radar->freq);
2339 hostapd_dfs_nop_finished(hapd->iface, radar->freq, radar->ht_enabled,
2340 radar->chan_offset, radar->chan_width,
2341 radar->cf1, radar->cf2);
2342 }
2343
2344
hostapd_event_dfs_cac_started(struct hostapd_data * hapd,struct dfs_event * radar)2345 static void hostapd_event_dfs_cac_started(struct hostapd_data *hapd,
2346 struct dfs_event *radar)
2347 {
2348 wpa_printf(MSG_DEBUG, "DFS offload CAC started on %d MHz", radar->freq);
2349 hostapd_dfs_start_cac(hapd, radar->freq, radar->ht_enabled,
2350 radar->chan_offset, radar->chan_width,
2351 radar->cf1, radar->cf2);
2352 }
2353
2354
hostapd_event_incumbt_sig_intf_detected(struct hostapd_data * hapd,struct incumbt_sig_intf_event * intf_info)2355 static void hostapd_event_incumbt_sig_intf_detected(
2356 struct hostapd_data *hapd, struct incumbt_sig_intf_event *intf_info)
2357 {
2358 wpa_printf(MSG_DEBUG, "Interference due to incumbent signal detected on %d MHz with intf bitmap 0x%x on link_id %d",
2359 intf_info->freq, intf_info->chan_bw_interference_bitmap,
2360 intf_info->link_id);
2361 if (hostapd_incumbt_sig_intf_detected(
2362 hapd->iface, intf_info->freq, intf_info->chan_width,
2363 intf_info->cf1, intf_info->cf2,
2364 intf_info->chan_bw_interference_bitmap))
2365 wpa_printf(MSG_INFO,
2366 "Failed to handle incumbent signal interference");
2367 }
2368
2369 #endif /* NEED_AP_MLME */
2370
2371
hostapd_event_wds_sta_interface_status(struct hostapd_data * hapd,int istatus,const char * ifname,const u8 * addr)2372 static void hostapd_event_wds_sta_interface_status(struct hostapd_data *hapd,
2373 int istatus,
2374 const char *ifname,
2375 const u8 *addr)
2376 {
2377 struct sta_info *sta = ap_get_sta(hapd, addr);
2378
2379 if (sta) {
2380 os_free(sta->ifname_wds);
2381 if (istatus == INTERFACE_ADDED)
2382 sta->ifname_wds = os_strdup(ifname);
2383 else
2384 sta->ifname_wds = NULL;
2385 }
2386
2387 wpa_msg(hapd->msg_ctx, MSG_INFO, "%sifname=%s sta_addr=" MACSTR,
2388 istatus == INTERFACE_ADDED ?
2389 WDS_STA_INTERFACE_ADDED : WDS_STA_INTERFACE_REMOVED,
2390 ifname, MAC2STR(addr));
2391 }
2392
2393
2394 #ifdef CONFIG_OWE
hostapd_notif_update_dh_ie(struct hostapd_data * hapd,const u8 * peer,const u8 * ie,size_t ie_len,const u8 * link_addr)2395 static int hostapd_notif_update_dh_ie(struct hostapd_data *hapd,
2396 const u8 *peer, const u8 *ie,
2397 size_t ie_len, const u8 *link_addr)
2398 {
2399 u16 status;
2400 struct sta_info *sta;
2401 struct ieee802_11_elems elems;
2402
2403 if (!hapd || !hapd->wpa_auth) {
2404 wpa_printf(MSG_DEBUG, "OWE: Invalid hapd context");
2405 return -1;
2406 }
2407 if (!peer) {
2408 wpa_printf(MSG_DEBUG, "OWE: Peer unknown");
2409 return -1;
2410 }
2411 if (!(hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE)) {
2412 wpa_printf(MSG_DEBUG, "OWE: No OWE AKM configured");
2413 status = WLAN_STATUS_INVALID_AKMP;
2414 goto err;
2415 }
2416 if (ieee802_11_parse_elems(ie, ie_len, &elems, 1) == ParseFailed) {
2417 wpa_printf(MSG_DEBUG, "OWE: Failed to parse OWE IE for "
2418 MACSTR, MAC2STR(peer));
2419 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
2420 goto err;
2421 }
2422 status = owe_validate_request(hapd, peer, elems.rsn_ie,
2423 elems.rsn_ie_len,
2424 elems.owe_dh, elems.owe_dh_len);
2425 if (status != WLAN_STATUS_SUCCESS)
2426 goto err;
2427
2428 sta = ap_get_sta(hapd, peer);
2429 if (sta) {
2430 ap_sta_no_session_timeout(hapd, sta);
2431 accounting_sta_stop(hapd, sta);
2432
2433 /*
2434 * Make sure that the previously registered inactivity timer
2435 * will not remove the STA immediately.
2436 */
2437 sta->timeout_next = STA_NULLFUNC;
2438 } else {
2439 sta = ap_sta_add(hapd, peer);
2440 if (!sta) {
2441 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
2442 goto err;
2443 }
2444 }
2445 sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2);
2446
2447 #ifdef CONFIG_IEEE80211BE
2448 if (link_addr) {
2449 struct mld_info *info = &sta->mld_info;
2450 u8 link_id = hapd->mld_link_id;
2451
2452 ap_sta_set_mld(sta, true);
2453 sta->mld_assoc_link_id = link_id;
2454 os_memcpy(info->common_info.mld_addr, peer, ETH_ALEN);
2455 info->links[link_id].valid = true;
2456 os_memcpy(info->links[link_id].local_addr, hapd->own_addr,
2457 ETH_ALEN);
2458 os_memcpy(info->links[link_id].peer_addr, link_addr, ETH_ALEN);
2459 }
2460 #endif /* CONFIG_IEEE80211BE */
2461
2462 status = owe_process_rsn_ie(hapd, sta, elems.rsn_ie,
2463 elems.rsn_ie_len, elems.owe_dh,
2464 elems.owe_dh_len, link_addr);
2465 if (status != WLAN_STATUS_SUCCESS)
2466 ap_free_sta(hapd, sta);
2467
2468 return 0;
2469 err:
2470 hostapd_drv_update_dh_ie(hapd, link_addr ? link_addr : peer, status,
2471 NULL, 0);
2472 return 0;
2473 }
2474 #endif /* CONFIG_OWE */
2475
2476
2477 #ifdef NEED_AP_MLME
hostapd_eapol_tx_status(struct hostapd_data * hapd,const u8 * dst,const u8 * data,size_t len,int ack,int link_id)2478 static void hostapd_eapol_tx_status(struct hostapd_data *hapd, const u8 *dst,
2479 const u8 *data, size_t len, int ack,
2480 int link_id)
2481 {
2482 struct sta_info *sta;
2483
2484 hapd = switch_link_hapd(hapd, link_id);
2485 hapd = hostapd_find_by_sta(hapd->iface, dst, false, &sta);
2486
2487 if (!sta) {
2488 wpa_printf(MSG_DEBUG, "Ignore TX status for Data frame to STA "
2489 MACSTR " that is not currently associated",
2490 MAC2STR(dst));
2491 return;
2492 }
2493
2494 ieee802_1x_eapol_tx_status(hapd, sta, data, len, ack);
2495 }
2496 #endif /* NEED_AP_MLME */
2497
2498
2499 #ifdef CONFIG_IEEE80211AX
hostapd_event_color_change(struct hostapd_data * hapd,bool success)2500 static void hostapd_event_color_change(struct hostapd_data *hapd, bool success)
2501 {
2502 struct hostapd_data *bss;
2503 size_t i;
2504
2505 for (i = 0; i < hapd->iface->num_bss; i++) {
2506 bss = hapd->iface->bss[i];
2507 if (bss->cca_color == 0)
2508 continue;
2509
2510 if (success) {
2511 hapd->iface->conf->he_op.he_bss_color = bss->cca_color;
2512 /* Clear the disabled flag set during CCA so that
2513 * subsequent beacon rebuilds advertise the new color
2514 * as enabled.
2515 */
2516 hapd->iface->conf->he_op.he_bss_color_disabled = 0;
2517 }
2518
2519 bss->cca_in_progress = 0;
2520 if (ieee802_11_set_beacon(bss)) {
2521 wpa_printf(MSG_ERROR, "Failed to remove BCCA element");
2522 bss->cca_in_progress = 1;
2523 } else {
2524 hostapd_cleanup_cca_params(bss);
2525 }
2526 }
2527 }
2528 #endif /* CONFIG_IEEE80211AX */
2529
2530
hostapd_iface_enable(struct hostapd_data * hapd)2531 static void hostapd_iface_enable(struct hostapd_data *hapd)
2532 {
2533 wpa_msg(hapd->msg_ctx, MSG_INFO, INTERFACE_ENABLED);
2534 if (hapd->disabled && hapd->started) {
2535 hapd->disabled = 0;
2536 /*
2537 * Try to re-enable interface if the driver stopped it
2538 * when the interface got disabled.
2539 */
2540 if (hapd->wpa_auth)
2541 wpa_auth_reconfig_group_keys(hapd->wpa_auth);
2542 else
2543 hostapd_reconfig_encryption(hapd);
2544 hapd->reenable_beacon = 1;
2545 ieee802_11_set_beacon(hapd);
2546 #ifdef NEED_AP_MLME
2547 } else if (hapd->disabled && hapd->iface->cac_started) {
2548 wpa_printf(MSG_DEBUG, "DFS: restarting pending CAC");
2549 hostapd_handle_dfs(hapd->iface);
2550 #endif /* NEED_AP_MLME */
2551 }
2552 }
2553
2554
hostapd_iface_disable(struct hostapd_data * hapd)2555 static void hostapd_iface_disable(struct hostapd_data *hapd)
2556 {
2557 hostapd_free_stas(hapd);
2558 wpa_msg(hapd->msg_ctx, MSG_INFO, INTERFACE_DISABLED);
2559 hapd->disabled = 1;
2560 }
2561
2562
2563 #ifdef CONFIG_IEEE80211BE
2564
hostapd_mld_iface_enable(struct hostapd_data * hapd)2565 static void hostapd_mld_iface_enable(struct hostapd_data *hapd)
2566 {
2567 struct hostapd_data *first_link, *link_bss;
2568
2569 first_link = hostapd_mld_is_first_bss(hapd) ? hapd :
2570 hostapd_mld_get_first_bss(hapd);
2571
2572 /* Links have been removed. Re-add all links and enable them, but
2573 * enable the first link BSS before doing that. */
2574 if (hostapd_drv_link_add(first_link, first_link->mld_link_id,
2575 first_link->own_addr)) {
2576 wpa_printf(MSG_ERROR, "MLD: Failed to re-add link %d in MLD %s",
2577 first_link->mld_link_id, first_link->conf->iface);
2578 return;
2579 }
2580
2581 hostapd_iface_enable(first_link);
2582
2583 /* Add other affiliated links */
2584 for_each_mld_link(link_bss, first_link) {
2585 if (link_bss == first_link)
2586 continue;
2587
2588 if (hostapd_drv_link_add(link_bss, link_bss->mld_link_id,
2589 link_bss->own_addr)) {
2590 wpa_printf(MSG_ERROR,
2591 "MLD: Failed to re-add link %d in MLD %s",
2592 link_bss->mld_link_id,
2593 link_bss->conf->iface);
2594 continue;
2595 }
2596
2597 hostapd_iface_enable(link_bss);
2598 }
2599 }
2600
2601
hostapd_mld_iface_disable(struct hostapd_data * hapd)2602 static void hostapd_mld_iface_disable(struct hostapd_data *hapd)
2603 {
2604 struct hostapd_data *link_bss;
2605
2606 for_each_mld_link(link_bss, hapd)
2607 hostapd_iface_disable(link_bss);
2608 }
2609
2610 #endif /* CONFIG_IEEE80211BE */
2611
2612
wpa_supplicant_event(void * ctx,enum wpa_event_type event,union wpa_event_data * data)2613 void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
2614 union wpa_event_data *data)
2615 {
2616 struct hostapd_data *hapd = ctx;
2617 struct sta_info *sta;
2618 #ifndef CONFIG_NO_STDOUT_DEBUG
2619 int level = MSG_DEBUG;
2620
2621 if (event == EVENT_RX_MGMT && data->rx_mgmt.frame &&
2622 data->rx_mgmt.frame_len >= 24) {
2623 const struct ieee80211_hdr *hdr;
2624 u16 fc;
2625
2626 hdr = (const struct ieee80211_hdr *) data->rx_mgmt.frame;
2627 fc = le_to_host16(hdr->frame_control);
2628 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
2629 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
2630 level = MSG_EXCESSIVE;
2631 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
2632 WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_REQ)
2633 level = MSG_EXCESSIVE;
2634 }
2635
2636 wpa_dbg(hapd->msg_ctx, level, "Event %s (%d) received",
2637 event_to_string(event), event);
2638 #endif /* CONFIG_NO_STDOUT_DEBUG */
2639
2640 switch (event) {
2641 case EVENT_MICHAEL_MIC_FAILURE:
2642 michael_mic_failure(hapd, data->michael_mic_failure.src, 1);
2643 break;
2644 case EVENT_SCAN_RESULTS:
2645 #ifdef NEED_AP_MLME
2646 if (data)
2647 hapd = switch_link_scan(hapd,
2648 data->scan_info.scan_cookie);
2649 #endif /* NEED_AP_MLME */
2650 if (hapd->iface->scan_cb)
2651 hapd->iface->scan_cb(hapd->iface);
2652 #ifdef CONFIG_IEEE80211BE
2653 if (!hapd->iface->scan_cb && hapd->conf->mld_ap) {
2654 /* Other links may be waiting for HT scan result */
2655 unsigned int i;
2656
2657 for (i = 0; i < hapd->iface->interfaces->count; i++) {
2658 struct hostapd_iface *h =
2659 hapd->iface->interfaces->iface[i];
2660 struct hostapd_data *h_hapd = h->bss[0];
2661
2662 if (hostapd_is_ml_partner(hapd, h_hapd) &&
2663 h_hapd->iface->scan_cb)
2664 h_hapd->iface->scan_cb(h_hapd->iface);
2665 }
2666 }
2667 #endif /* CONFIG_IEEE80211BE */
2668 break;
2669 case EVENT_WPS_BUTTON_PUSHED:
2670 hostapd_wps_button_pushed(hapd, NULL);
2671 break;
2672 #ifdef NEED_AP_MLME
2673 case EVENT_TX_STATUS:
2674 switch (data->tx_status.type) {
2675 case WLAN_FC_TYPE_MGMT:
2676 hostapd_mgmt_tx_cb(hapd, data->tx_status.data,
2677 data->tx_status.data_len,
2678 data->tx_status.stype,
2679 data->tx_status.ack,
2680 data->tx_status.link_id);
2681 break;
2682 case WLAN_FC_TYPE_DATA:
2683 hostapd_tx_status(hapd, data->tx_status.dst,
2684 data->tx_status.data,
2685 data->tx_status.data_len,
2686 data->tx_status.ack);
2687 break;
2688 }
2689 break;
2690 case EVENT_EAPOL_TX_STATUS:
2691 hostapd_eapol_tx_status(hapd, data->eapol_tx_status.dst,
2692 data->eapol_tx_status.data,
2693 data->eapol_tx_status.data_len,
2694 data->eapol_tx_status.ack,
2695 data->eapol_tx_status.link_id);
2696 break;
2697 case EVENT_DRIVER_CLIENT_POLL_OK:
2698 hostapd_client_poll_ok(hapd, data->client_poll.addr);
2699 break;
2700 case EVENT_RX_FROM_UNKNOWN:
2701 hapd = switch_link_hapd(hapd, data->rx_from_unknown.link_id);
2702 hostapd_rx_from_unknown_sta(hapd, data->rx_from_unknown.bssid,
2703 data->rx_from_unknown.addr,
2704 data->rx_from_unknown.wds);
2705 break;
2706 #endif /* NEED_AP_MLME */
2707 case EVENT_RX_MGMT:
2708 if (!data->rx_mgmt.frame)
2709 break;
2710 #ifdef NEED_AP_MLME
2711 hostapd_mgmt_rx(hapd, &data->rx_mgmt);
2712 #else /* NEED_AP_MLME */
2713 hostapd_action_rx(hapd, &data->rx_mgmt);
2714 #endif /* NEED_AP_MLME */
2715 break;
2716 case EVENT_RX_PROBE_REQ:
2717 if (data->rx_probe_req.sa == NULL ||
2718 data->rx_probe_req.ie == NULL)
2719 break;
2720 hostapd_probe_req_rx(hapd, data->rx_probe_req.sa,
2721 data->rx_probe_req.da,
2722 data->rx_probe_req.bssid,
2723 data->rx_probe_req.ie,
2724 data->rx_probe_req.ie_len,
2725 data->rx_probe_req.ssi_signal);
2726 break;
2727 case EVENT_NEW_STA:
2728 hostapd_event_new_sta(hapd, data->new_sta.addr);
2729 break;
2730 case EVENT_EAPOL_RX:
2731 hostapd_event_eapol_rx(hapd, data->eapol_rx.src,
2732 data->eapol_rx.data,
2733 data->eapol_rx.data_len,
2734 data->eapol_rx.encrypted,
2735 data->eapol_rx.link_id);
2736 break;
2737 case EVENT_ASSOC:
2738 if (!data)
2739 return;
2740 #ifdef CONFIG_IEEE80211BE
2741 if (data->assoc_info.assoc_link_id != -1) {
2742 hapd = hostapd_mld_get_link_bss(
2743 hapd, data->assoc_info.assoc_link_id);
2744 if (!hapd) {
2745 wpa_printf(MSG_ERROR,
2746 "MLD: Failed to get link BSS for EVENT_ASSOC");
2747 return;
2748 }
2749 }
2750 #endif /* CONFIG_IEEE80211BE */
2751 hostapd_notif_assoc(hapd, data->assoc_info.addr,
2752 data->assoc_info.req_ies,
2753 data->assoc_info.req_ies_len,
2754 data->assoc_info.resp_ies,
2755 data->assoc_info.resp_ies_len,
2756 data->assoc_info.link_addr,
2757 data->assoc_info.reassoc);
2758 break;
2759 case EVENT_PORT_AUTHORIZED:
2760 /* Port authorized event for an associated STA */
2761 sta = ap_get_sta(hapd, data->port_authorized.sta_addr);
2762 if (sta)
2763 ap_sta_set_authorized(hapd, sta, 1);
2764 else
2765 wpa_printf(MSG_DEBUG,
2766 "No STA info matching port authorized event found");
2767 break;
2768 #ifdef CONFIG_OWE
2769 case EVENT_UPDATE_DH:
2770 if (!data)
2771 return;
2772 #ifdef CONFIG_IEEE80211BE
2773 if (data->update_dh.assoc_link_id != -1) {
2774 hapd = hostapd_mld_get_link_bss(
2775 hapd, data->update_dh.assoc_link_id);
2776 if (!hapd) {
2777 wpa_printf(MSG_ERROR,
2778 "MLD: Failed to get link BSS for EVENT_UPDATE_DH assoc_link_id=%d",
2779 data->update_dh.assoc_link_id);
2780 return;
2781 }
2782 }
2783 #endif /* CONFIG_IEEE80211BE */
2784 hostapd_notif_update_dh_ie(hapd, data->update_dh.peer,
2785 data->update_dh.ie,
2786 data->update_dh.ie_len,
2787 data->update_dh.link_addr);
2788 break;
2789 #endif /* CONFIG_OWE */
2790 case EVENT_DISASSOC:
2791 if (data)
2792 hostapd_notif_disassoc(hapd, data->disassoc_info.addr);
2793 break;
2794 case EVENT_DEAUTH:
2795 if (data)
2796 hostapd_notif_disassoc(hapd, data->deauth_info.addr);
2797 break;
2798 case EVENT_STATION_LOW_ACK:
2799 if (!data)
2800 break;
2801 hostapd_event_sta_low_ack(hapd, data->low_ack.addr);
2802 break;
2803 case EVENT_AUTH:
2804 hostapd_notif_auth(hapd, &data->auth);
2805 break;
2806 case EVENT_CH_SWITCH_STARTED:
2807 case EVENT_CH_SWITCH:
2808 if (!data)
2809 break;
2810 #ifdef CONFIG_IEEE80211BE
2811 if (data->ch_switch.link_id != -1) {
2812 hapd = hostapd_mld_get_link_bss(
2813 hapd, data->ch_switch.link_id);
2814 if (!hapd) {
2815 wpa_printf(MSG_ERROR,
2816 "MLD: Failed to get link (ID %d) BSS for EVENT_CH_SWITCH/EVENT_CH_SWITCH_STARTED",
2817 data->ch_switch.link_id);
2818 break;
2819 }
2820 }
2821 #endif /* CONFIG_IEEE80211BE */
2822 hostapd_event_ch_switch(hapd, data->ch_switch.freq,
2823 data->ch_switch.ht_enabled,
2824 data->ch_switch.ch_offset,
2825 data->ch_switch.ch_width,
2826 data->ch_switch.cf1,
2827 data->ch_switch.cf2,
2828 data->ch_switch.punct_bitmap,
2829 event == EVENT_CH_SWITCH);
2830 break;
2831 case EVENT_CONNECT_FAILED_REASON:
2832 if (!data)
2833 break;
2834 hostapd_event_connect_failed_reason(
2835 hapd, data->connect_failed_reason.addr,
2836 data->connect_failed_reason.code);
2837 break;
2838 case EVENT_SURVEY:
2839 hostapd_event_get_survey(hapd->iface, &data->survey_results);
2840 break;
2841 #ifdef NEED_AP_MLME
2842 case EVENT_INTERFACE_UNAVAILABLE:
2843 hostapd_event_iface_unavailable(hapd);
2844 /* Update beacon information in all other interfaces to cover
2845 * removal/disabling of this BSS. */
2846 hostapd_refresh_all_iface_beacons(hapd->iface);
2847 break;
2848 case EVENT_DFS_RADAR_DETECTED:
2849 if (!data)
2850 break;
2851 hapd = switch_link_hapd(hapd, data->dfs_event.link_id);
2852 hostapd_event_dfs_radar_detected(hapd, &data->dfs_event);
2853 break;
2854 case EVENT_DFS_PRE_CAC_EXPIRED:
2855 if (!data)
2856 break;
2857 hapd = switch_link_hapd(hapd, data->dfs_event.link_id);
2858 hostapd_event_dfs_pre_cac_expired(hapd, &data->dfs_event);
2859 break;
2860 case EVENT_DFS_CAC_FINISHED:
2861 if (!data)
2862 break;
2863 hapd = switch_link_hapd(hapd, data->dfs_event.link_id);
2864 hostapd_event_dfs_cac_finished(hapd, &data->dfs_event);
2865 break;
2866 case EVENT_DFS_CAC_ABORTED:
2867 if (!data)
2868 break;
2869 hapd = switch_link_hapd(hapd, data->dfs_event.link_id);
2870 hostapd_event_dfs_cac_aborted(hapd, &data->dfs_event);
2871 break;
2872 case EVENT_DFS_NOP_FINISHED:
2873 if (!data)
2874 break;
2875 hapd = switch_link_hapd(hapd, data->dfs_event.link_id);
2876 hostapd_event_dfs_nop_finished(hapd, &data->dfs_event);
2877 break;
2878 case EVENT_CHANNEL_LIST_CHANGED:
2879 /* channel list changed (regulatory?), update channel list */
2880 /* TODO: check this. hostapd_get_hw_features() initializes
2881 * too much stuff. */
2882 /* hostapd_get_hw_features(hapd->iface); */
2883 hostapd_channel_list_updated(
2884 hapd->iface, data->channel_list_changed.initiator);
2885 break;
2886 case EVENT_DFS_CAC_STARTED:
2887 if (!data)
2888 break;
2889 hapd = switch_link_hapd(hapd, data->dfs_event.link_id);
2890 hostapd_event_dfs_cac_started(hapd, &data->dfs_event);
2891 break;
2892 case EVENT_INCUMBT_SIG_INTF_DETECTED:
2893 if (!data)
2894 break;
2895 hapd = switch_link_hapd(hapd,
2896 data->incumbt_sig_intf_event.link_id);
2897 hostapd_event_incumbt_sig_intf_detected(
2898 hapd, &data->incumbt_sig_intf_event);
2899 break;
2900 #endif /* NEED_AP_MLME */
2901 case EVENT_INTERFACE_ENABLED:
2902 #ifdef CONFIG_IEEE80211BE
2903 if (hapd->conf->mld_ap) {
2904 hostapd_mld_iface_enable(hapd);
2905 break;
2906 }
2907 #endif /* CONFIG_IEEE80211BE */
2908 hostapd_iface_enable(hapd);
2909 break;
2910 case EVENT_INTERFACE_DISABLED:
2911 #ifdef CONFIG_IEEE80211BE
2912 if (hapd->conf->mld_ap) {
2913 hostapd_mld_iface_disable(hapd);
2914 break;
2915 }
2916 #endif /* CONFIG_IEEE80211BE */
2917 hostapd_iface_disable(hapd);
2918 break;
2919 #ifdef CONFIG_ACS
2920 case EVENT_ACS_CHANNEL_SELECTED:
2921 hostapd_acs_channel_selected(hapd,
2922 &data->acs_selected_channels);
2923 break;
2924 #endif /* CONFIG_ACS */
2925 case EVENT_STATION_OPMODE_CHANGED:
2926 hostapd_event_sta_opmode_changed(hapd, data->sta_opmode.addr,
2927 data->sta_opmode.smps_mode,
2928 data->sta_opmode.chan_width,
2929 data->sta_opmode.rx_nss);
2930 break;
2931 case EVENT_WDS_STA_INTERFACE_STATUS:
2932 hostapd_event_wds_sta_interface_status(
2933 hapd, data->wds_sta_interface.istatus,
2934 data->wds_sta_interface.ifname,
2935 data->wds_sta_interface.sta_addr);
2936 break;
2937 #ifdef CONFIG_IEEE80211AX
2938 case EVENT_BSS_COLOR_COLLISION:
2939 /* The BSS color is shared amongst all BBSs on a specific phy.
2940 * Therefore we always start the color change on the primary
2941 * BSS. */
2942 hapd = switch_link_hapd(hapd,
2943 data->bss_color_collision.link_id);
2944 wpa_printf(MSG_DEBUG, "BSS color collision on %s",
2945 hapd->conf->iface);
2946 hostapd_switch_color(hapd->iface->bss[0],
2947 data->bss_color_collision.bitmap);
2948 break;
2949 case EVENT_CCA_STARTED_NOTIFY:
2950 hapd = switch_link_hapd(hapd,
2951 data->bss_color_collision.link_id);
2952 wpa_printf(MSG_DEBUG, "CCA started on %s",
2953 hapd->conf->iface);
2954 break;
2955 case EVENT_CCA_ABORTED_NOTIFY:
2956 hapd = switch_link_hapd(hapd,
2957 data->bss_color_collision.link_id);
2958 wpa_printf(MSG_DEBUG, "CCA aborted on %s",
2959 hapd->conf->iface);
2960 hostapd_event_color_change(hapd, false);
2961 break;
2962 case EVENT_CCA_NOTIFY:
2963 hapd = switch_link_hapd(hapd,
2964 data->bss_color_collision.link_id);
2965 wpa_printf(MSG_DEBUG, "CCA finished on %s",
2966 hapd->conf->iface);
2967 hostapd_event_color_change(hapd, true);
2968 break;
2969 #endif /* CONFIG_IEEE80211AX */
2970 #ifdef CONFIG_IEEE80211BE
2971 case EVENT_MLD_INTERFACE_FREED:
2972 wpa_printf(MSG_DEBUG, "MLD: Interface %s freed",
2973 hapd->conf->iface);
2974 hostapd_mld_interface_freed(hapd);
2975 break;
2976 #endif /* CONFIG_IEEE80211BE */
2977 default:
2978 wpa_printf(MSG_DEBUG, "Unknown event %d", event);
2979 break;
2980 }
2981 }
2982
2983
wpa_supplicant_event_global(void * ctx,enum wpa_event_type event,union wpa_event_data * data)2984 void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event,
2985 union wpa_event_data *data)
2986 {
2987 struct hapd_interfaces *interfaces = ctx;
2988 struct hostapd_data *hapd;
2989
2990 if (event != EVENT_INTERFACE_STATUS)
2991 return;
2992
2993 hapd = hostapd_get_iface(interfaces, data->interface_status.ifname);
2994 if (hapd && hapd->driver && hapd->driver->get_ifindex &&
2995 hapd->drv_priv) {
2996 unsigned int ifindex;
2997
2998 ifindex = hapd->driver->get_ifindex(hapd->drv_priv);
2999 if (ifindex != data->interface_status.ifindex) {
3000 wpa_dbg(hapd->msg_ctx, MSG_DEBUG,
3001 "interface status ifindex %d mismatch (%d)",
3002 ifindex, data->interface_status.ifindex);
3003 return;
3004 }
3005 }
3006 if (hapd)
3007 wpa_supplicant_event(hapd, event, data);
3008 }
3009
3010 #endif /* HOSTAPD */
3011