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