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