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