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