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 "crypto/random.h"
20#include "p2p/p2p.h"
21#include "wps/wps.h"
22#include "fst/fst.h"
23#include "wnm_ap.h"
24#include "hostapd.h"
25#include "ieee802_11.h"
26#include "ieee802_11_auth.h"
27#include "sta_info.h"
28#include "accounting.h"
29#include "tkip_countermeasures.h"
30#include "ieee802_1x.h"
31#include "wpa_auth.h"
32#include "wps_hostapd.h"
33#include "ap_drv_ops.h"
34#include "ap_config.h"
35#include "ap_mlme.h"
36#include "hw_features.h"
37#include "dfs.h"
38#include "beacon.h"
39#include "mbo_ap.h"
40#include "dpp_hostapd.h"
41#include "fils_hlp.h"
42#include "neighbor_db.h"
43
44
45#ifdef CONFIG_FILS
46void hostapd_notify_assoc_fils_finish(struct hostapd_data *hapd,
47				      struct sta_info *sta)
48{
49	u16 reply_res = WLAN_STATUS_SUCCESS;
50	struct ieee802_11_elems elems;
51	u8 buf[IEEE80211_MAX_MMPDU_SIZE], *p = buf;
52	int new_assoc;
53
54	wpa_printf(MSG_DEBUG, "%s FILS: Finish association with " MACSTR,
55		   __func__, MAC2STR(sta->addr));
56	eloop_cancel_timeout(fils_hlp_timeout, hapd, sta);
57	if (!sta->fils_pending_assoc_req)
58		return;
59
60	ieee802_11_parse_elems(sta->fils_pending_assoc_req,
61			       sta->fils_pending_assoc_req_len, &elems, 0);
62	if (!elems.fils_session) {
63		wpa_printf(MSG_DEBUG, "%s failed to find FILS Session element",
64			   __func__);
65		return;
66	}
67
68	p = hostapd_eid_assoc_fils_session(sta->wpa_sm, p,
69					   elems.fils_session,
70					   sta->fils_hlp_resp);
71
72	reply_res = hostapd_sta_assoc(hapd, sta->addr,
73				      sta->fils_pending_assoc_is_reassoc,
74				      WLAN_STATUS_SUCCESS,
75				      buf, p - buf);
76	ap_sta_set_authorized(hapd, sta, 1);
77	new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;
78	sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
79	sta->flags &= ~WLAN_STA_WNM_SLEEP_MODE;
80	hostapd_set_sta_flags(hapd, sta);
81	wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FILS);
82	ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
83	hostapd_new_assoc_sta(hapd, sta, !new_assoc);
84	os_free(sta->fils_pending_assoc_req);
85	sta->fils_pending_assoc_req = NULL;
86	sta->fils_pending_assoc_req_len = 0;
87	wpabuf_free(sta->fils_hlp_resp);
88	sta->fils_hlp_resp = NULL;
89	wpabuf_free(sta->hlp_dhcp_discover);
90	sta->hlp_dhcp_discover = NULL;
91	fils_hlp_deinit(hapd);
92
93	/*
94	 * Remove the station in case transmission of a success response fails
95	 * (the STA was added associated to the driver) or if the station was
96	 * previously added unassociated.
97	 */
98	if (reply_res != WLAN_STATUS_SUCCESS || sta->added_unassoc) {
99		hostapd_drv_sta_remove(hapd, sta->addr);
100		sta->added_unassoc = 0;
101	}
102}
103#endif /* CONFIG_FILS */
104
105
106int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
107			const u8 *req_ies, size_t req_ies_len, int reassoc)
108{
109	struct sta_info *sta;
110	int new_assoc, res;
111	struct ieee802_11_elems elems;
112	const u8 *ie;
113	size_t ielen;
114#if defined(CONFIG_IEEE80211R_AP) || defined(CONFIG_IEEE80211W) || defined(CONFIG_FILS) || defined(CONFIG_OWE)
115	u8 buf[sizeof(struct ieee80211_mgmt) + 1024];
116	u8 *p = buf;
117#endif /* CONFIG_IEEE80211R_AP || CONFIG_IEEE80211W || CONFIG_FILS || CONFIG_OWE */
118	u16 reason = WLAN_REASON_UNSPECIFIED;
119	u16 status = WLAN_STATUS_SUCCESS;
120	const u8 *p2p_dev_addr = NULL;
121
122	if (addr == NULL) {
123		/*
124		 * This could potentially happen with unexpected event from the
125		 * driver wrapper. This was seen at least in one case where the
126		 * driver ended up being set to station mode while hostapd was
127		 * running, so better make sure we stop processing such an
128		 * event here.
129		 */
130		wpa_printf(MSG_DEBUG,
131			   "hostapd_notif_assoc: Skip event with no address");
132		return -1;
133	}
134
135	if (is_multicast_ether_addr(addr) ||
136	    is_zero_ether_addr(addr) ||
137	    os_memcmp(addr, hapd->own_addr, ETH_ALEN) == 0) {
138		/* Do not process any frames with unexpected/invalid SA so that
139		 * we do not add any state for unexpected STA addresses or end
140		 * up sending out frames to unexpected destination. */
141		wpa_printf(MSG_DEBUG, "%s: Invalid SA=" MACSTR
142			   " in received indication - ignore this indication silently",
143			   __func__, MAC2STR(addr));
144		return 0;
145	}
146
147	random_add_randomness(addr, ETH_ALEN);
148
149	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
150		       HOSTAPD_LEVEL_INFO, "associated");
151
152	ieee802_11_parse_elems(req_ies, req_ies_len, &elems, 0);
153	if (elems.wps_ie) {
154		ie = elems.wps_ie - 2;
155		ielen = elems.wps_ie_len + 2;
156		wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)AssocReq");
157	} else if (elems.rsn_ie) {
158		ie = elems.rsn_ie - 2;
159		ielen = elems.rsn_ie_len + 2;
160		wpa_printf(MSG_DEBUG, "STA included RSN IE in (Re)AssocReq");
161	} else if (elems.wpa_ie) {
162		ie = elems.wpa_ie - 2;
163		ielen = elems.wpa_ie_len + 2;
164		wpa_printf(MSG_DEBUG, "STA included WPA IE in (Re)AssocReq");
165#ifdef CONFIG_HS20
166	} else if (elems.osen) {
167		ie = elems.osen - 2;
168		ielen = elems.osen_len + 2;
169		wpa_printf(MSG_DEBUG, "STA included OSEN IE in (Re)AssocReq");
170#endif /* CONFIG_HS20 */
171	} else {
172		ie = NULL;
173		ielen = 0;
174		wpa_printf(MSG_DEBUG,
175			   "STA did not include WPS/RSN/WPA IE in (Re)AssocReq");
176	}
177
178	sta = ap_get_sta(hapd, addr);
179	if (sta) {
180		ap_sta_no_session_timeout(hapd, sta);
181		accounting_sta_stop(hapd, sta);
182
183		/*
184		 * Make sure that the previously registered inactivity timer
185		 * will not remove the STA immediately.
186		 */
187		sta->timeout_next = STA_NULLFUNC;
188	} else {
189		sta = ap_sta_add(hapd, addr);
190		if (sta == NULL) {
191			hostapd_drv_sta_disassoc(hapd, addr,
192						 WLAN_REASON_DISASSOC_AP_BUSY);
193			return -1;
194		}
195	}
196	sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2);
197
198	/*
199	 * ACL configurations to the drivers (implementing AP SME and ACL
200	 * offload) without hostapd's knowledge, can result in a disconnection
201	 * though the driver accepts the connection. Skip the hostapd check for
202	 * ACL if the driver supports ACL offload to avoid potentially
203	 * conflicting ACL rules.
204	 */
205	if (hapd->iface->drv_max_acl_mac_addrs == 0 &&
206	    hostapd_check_acl(hapd, addr, NULL) != HOSTAPD_ACL_ACCEPT) {
207		wpa_printf(MSG_INFO, "STA " MACSTR " not allowed to connect",
208			   MAC2STR(addr));
209		reason = WLAN_REASON_UNSPECIFIED;
210		goto fail;
211	}
212
213#ifdef CONFIG_P2P
214	if (elems.p2p) {
215		wpabuf_free(sta->p2p_ie);
216		sta->p2p_ie = ieee802_11_vendor_ie_concat(req_ies, req_ies_len,
217							  P2P_IE_VENDOR_TYPE);
218		if (sta->p2p_ie)
219			p2p_dev_addr = p2p_get_go_dev_addr(sta->p2p_ie);
220	}
221#endif /* CONFIG_P2P */
222
223#ifdef CONFIG_IEEE80211N
224#ifdef NEED_AP_MLME
225	if (elems.ht_capabilities &&
226	    (hapd->iface->conf->ht_capab &
227	     HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) {
228		struct ieee80211_ht_capabilities *ht_cap =
229			(struct ieee80211_ht_capabilities *)
230			elems.ht_capabilities;
231
232		if (le_to_host16(ht_cap->ht_capabilities_info) &
233		    HT_CAP_INFO_40MHZ_INTOLERANT)
234			ht40_intolerant_add(hapd->iface, sta);
235	}
236#endif /* NEED_AP_MLME */
237#endif /* CONFIG_IEEE80211N */
238
239#ifdef CONFIG_INTERWORKING
240	if (elems.ext_capab && elems.ext_capab_len > 4) {
241		if (elems.ext_capab[4] & 0x01)
242			sta->qos_map_enabled = 1;
243	}
244#endif /* CONFIG_INTERWORKING */
245
246#ifdef CONFIG_HS20
247	wpabuf_free(sta->hs20_ie);
248	if (elems.hs20 && elems.hs20_len > 4) {
249		sta->hs20_ie = wpabuf_alloc_copy(elems.hs20 + 4,
250						 elems.hs20_len - 4);
251	} else
252		sta->hs20_ie = NULL;
253
254	wpabuf_free(sta->roaming_consortium);
255	if (elems.roaming_cons_sel)
256		sta->roaming_consortium = wpabuf_alloc_copy(
257			elems.roaming_cons_sel + 4,
258			elems.roaming_cons_sel_len - 4);
259	else
260		sta->roaming_consortium = NULL;
261#endif /* CONFIG_HS20 */
262
263#ifdef CONFIG_FST
264	wpabuf_free(sta->mb_ies);
265	if (hapd->iface->fst)
266		sta->mb_ies = mb_ies_by_info(&elems.mb_ies);
267	else
268		sta->mb_ies = NULL;
269#endif /* CONFIG_FST */
270
271	mbo_ap_check_sta_assoc(hapd, sta, &elems);
272
273	ap_copy_sta_supp_op_classes(sta, elems.supp_op_classes,
274				    elems.supp_op_classes_len);
275
276	if (hapd->conf->wpa) {
277		if (ie == NULL || ielen == 0) {
278#ifdef CONFIG_WPS
279			if (hapd->conf->wps_state) {
280				wpa_printf(MSG_DEBUG,
281					   "STA did not include WPA/RSN IE in (Re)Association Request - possible WPS use");
282				sta->flags |= WLAN_STA_MAYBE_WPS;
283				goto skip_wpa_check;
284			}
285#endif /* CONFIG_WPS */
286
287			wpa_printf(MSG_DEBUG, "No WPA/RSN IE from STA");
288			reason = WLAN_REASON_INVALID_IE;
289			status = WLAN_STATUS_INVALID_IE;
290			goto fail;
291		}
292#ifdef CONFIG_WPS
293		if (hapd->conf->wps_state && ie[0] == 0xdd && ie[1] >= 4 &&
294		    os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) {
295			struct wpabuf *wps;
296
297			sta->flags |= WLAN_STA_WPS;
298			wps = ieee802_11_vendor_ie_concat(ie, ielen,
299							  WPS_IE_VENDOR_TYPE);
300			if (wps) {
301				if (wps_is_20(wps)) {
302					wpa_printf(MSG_DEBUG,
303						   "WPS: STA supports WPS 2.0");
304					sta->flags |= WLAN_STA_WPS2;
305				}
306				wpabuf_free(wps);
307			}
308			goto skip_wpa_check;
309		}
310#endif /* CONFIG_WPS */
311
312		if (sta->wpa_sm == NULL)
313			sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
314							sta->addr,
315							p2p_dev_addr);
316		if (sta->wpa_sm == NULL) {
317			wpa_printf(MSG_ERROR,
318				   "Failed to initialize WPA state machine");
319			return -1;
320		}
321		res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
322					  hapd->iface->freq,
323					  ie, ielen,
324					  elems.mdie, elems.mdie_len,
325					  elems.owe_dh, elems.owe_dh_len);
326		if (res != WPA_IE_OK) {
327			wpa_printf(MSG_DEBUG,
328				   "WPA/RSN information element rejected? (res %u)",
329				   res);
330			wpa_hexdump(MSG_DEBUG, "IE", ie, ielen);
331			if (res == WPA_INVALID_GROUP) {
332				reason = WLAN_REASON_GROUP_CIPHER_NOT_VALID;
333				status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
334			} else if (res == WPA_INVALID_PAIRWISE) {
335				reason = WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID;
336				status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
337			} else if (res == WPA_INVALID_AKMP) {
338				reason = WLAN_REASON_AKMP_NOT_VALID;
339				status = WLAN_STATUS_AKMP_NOT_VALID;
340			}
341#ifdef CONFIG_IEEE80211W
342			else if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION) {
343				reason = WLAN_REASON_INVALID_IE;
344				status = WLAN_STATUS_INVALID_IE;
345			} else if (res == WPA_INVALID_MGMT_GROUP_CIPHER) {
346				reason = WLAN_REASON_CIPHER_SUITE_REJECTED;
347				status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
348			}
349#endif /* CONFIG_IEEE80211W */
350			else {
351				reason = WLAN_REASON_INVALID_IE;
352				status = WLAN_STATUS_INVALID_IE;
353			}
354			goto fail;
355		}
356#ifdef CONFIG_IEEE80211W
357		if ((sta->flags & (WLAN_STA_ASSOC | WLAN_STA_MFP)) ==
358		    (WLAN_STA_ASSOC | WLAN_STA_MFP) &&
359		    !sta->sa_query_timed_out &&
360		    sta->sa_query_count > 0)
361			ap_check_sa_query_timeout(hapd, sta);
362		if ((sta->flags & (WLAN_STA_ASSOC | WLAN_STA_MFP)) ==
363		    (WLAN_STA_ASSOC | WLAN_STA_MFP) &&
364		    !sta->sa_query_timed_out &&
365		    (sta->auth_alg != WLAN_AUTH_FT)) {
366			/*
367			 * STA has already been associated with MFP and SA
368			 * Query timeout has not been reached. Reject the
369			 * association attempt temporarily and start SA Query,
370			 * if one is not pending.
371			 */
372
373			if (sta->sa_query_count == 0)
374				ap_sta_start_sa_query(hapd, sta);
375
376			status = WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY;
377
378			p = hostapd_eid_assoc_comeback_time(hapd, sta, p);
379
380			hostapd_sta_assoc(hapd, addr, reassoc, status, buf,
381					  p - buf);
382			return 0;
383		}
384
385		if (wpa_auth_uses_mfp(sta->wpa_sm))
386			sta->flags |= WLAN_STA_MFP;
387		else
388			sta->flags &= ~WLAN_STA_MFP;
389#endif /* CONFIG_IEEE80211W */
390
391#ifdef CONFIG_IEEE80211R_AP
392		if (sta->auth_alg == WLAN_AUTH_FT) {
393			status = wpa_ft_validate_reassoc(sta->wpa_sm, req_ies,
394							 req_ies_len);
395			if (status != WLAN_STATUS_SUCCESS) {
396				if (status == WLAN_STATUS_INVALID_PMKID)
397					reason = WLAN_REASON_INVALID_IE;
398				if (status == WLAN_STATUS_INVALID_MDIE)
399					reason = WLAN_REASON_INVALID_IE;
400				if (status == WLAN_STATUS_INVALID_FTIE)
401					reason = WLAN_REASON_INVALID_IE;
402				goto fail;
403			}
404		}
405#endif /* CONFIG_IEEE80211R_AP */
406	} else if (hapd->conf->wps_state) {
407#ifdef CONFIG_WPS
408		struct wpabuf *wps;
409
410		if (req_ies)
411			wps = ieee802_11_vendor_ie_concat(req_ies, req_ies_len,
412							  WPS_IE_VENDOR_TYPE);
413		else
414			wps = NULL;
415#ifdef CONFIG_WPS_STRICT
416		if (wps && wps_validate_assoc_req(wps) < 0) {
417			reason = WLAN_REASON_INVALID_IE;
418			status = WLAN_STATUS_INVALID_IE;
419			wpabuf_free(wps);
420			goto fail;
421		}
422#endif /* CONFIG_WPS_STRICT */
423		if (wps) {
424			sta->flags |= WLAN_STA_WPS;
425			if (wps_is_20(wps)) {
426				wpa_printf(MSG_DEBUG,
427					   "WPS: STA supports WPS 2.0");
428				sta->flags |= WLAN_STA_WPS2;
429			}
430		} else
431			sta->flags |= WLAN_STA_MAYBE_WPS;
432		wpabuf_free(wps);
433#endif /* CONFIG_WPS */
434#ifdef CONFIG_HS20
435	} else if (hapd->conf->osen) {
436		if (elems.osen == NULL) {
437			hostapd_logger(
438				hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
439				HOSTAPD_LEVEL_INFO,
440				"No HS 2.0 OSEN element in association request");
441			return WLAN_STATUS_INVALID_IE;
442		}
443
444		wpa_printf(MSG_DEBUG, "HS 2.0: OSEN association");
445		if (sta->wpa_sm == NULL)
446			sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
447							sta->addr, NULL);
448		if (sta->wpa_sm == NULL) {
449			wpa_printf(MSG_WARNING,
450				   "Failed to initialize WPA state machine");
451			return WLAN_STATUS_UNSPECIFIED_FAILURE;
452		}
453		if (wpa_validate_osen(hapd->wpa_auth, sta->wpa_sm,
454				      elems.osen - 2, elems.osen_len + 2) < 0)
455			return WLAN_STATUS_INVALID_IE;
456#endif /* CONFIG_HS20 */
457	}
458
459#ifdef CONFIG_MBO
460	if (hapd->conf->mbo_enabled && (hapd->conf->wpa & 2) &&
461	    elems.mbo && sta->cell_capa && !(sta->flags & WLAN_STA_MFP) &&
462	    hapd->conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
463		wpa_printf(MSG_INFO,
464			   "MBO: Reject WPA2 association without PMF");
465		return WLAN_STATUS_UNSPECIFIED_FAILURE;
466	}
467#endif /* CONFIG_MBO */
468
469#ifdef CONFIG_WPS
470skip_wpa_check:
471#endif /* CONFIG_WPS */
472
473#ifdef CONFIG_IEEE80211R_AP
474	p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, buf, sizeof(buf),
475					sta->auth_alg, req_ies, req_ies_len);
476	if (!p) {
477		wpa_printf(MSG_DEBUG, "FT: Failed to write AssocResp IEs");
478		return WLAN_STATUS_UNSPECIFIED_FAILURE;
479	}
480#endif /* CONFIG_IEEE80211R_AP */
481
482#ifdef CONFIG_FILS
483	if (sta->auth_alg == WLAN_AUTH_FILS_SK ||
484	    sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
485	    sta->auth_alg == WLAN_AUTH_FILS_PK) {
486		int delay_assoc = 0;
487
488		if (!req_ies)
489			return WLAN_STATUS_UNSPECIFIED_FAILURE;
490
491		if (!wpa_fils_validate_fils_session(sta->wpa_sm, req_ies,
492						    req_ies_len,
493						    sta->fils_session)) {
494			wpa_printf(MSG_DEBUG,
495				   "FILS: Session validation failed");
496			return WLAN_STATUS_UNSPECIFIED_FAILURE;
497		}
498
499		res = wpa_fils_validate_key_confirm(sta->wpa_sm, req_ies,
500						    req_ies_len);
501		if (res < 0) {
502			wpa_printf(MSG_DEBUG,
503				   "FILS: Key Confirm validation failed");
504			return WLAN_STATUS_UNSPECIFIED_FAILURE;
505		}
506
507		if (fils_process_hlp(hapd, sta, req_ies, req_ies_len) > 0) {
508			wpa_printf(MSG_DEBUG,
509				   "FILS: Delaying Assoc Response (HLP)");
510			delay_assoc = 1;
511		} else {
512			wpa_printf(MSG_DEBUG,
513				   "FILS: Going ahead with Assoc Response (no HLP)");
514		}
515
516		if (sta) {
517			wpa_printf(MSG_DEBUG, "FILS: HLP callback cleanup");
518			eloop_cancel_timeout(fils_hlp_timeout, hapd, sta);
519			os_free(sta->fils_pending_assoc_req);
520			sta->fils_pending_assoc_req = NULL;
521			sta->fils_pending_assoc_req_len = 0;
522			wpabuf_free(sta->fils_hlp_resp);
523			sta->fils_hlp_resp = NULL;
524			sta->fils_drv_assoc_finish = 0;
525		}
526
527		if (sta && delay_assoc && status == WLAN_STATUS_SUCCESS) {
528			u8 *req_tmp;
529
530			req_tmp = os_malloc(req_ies_len);
531			if (!req_tmp) {
532				wpa_printf(MSG_DEBUG,
533					   "FILS: buffer allocation failed for assoc req");
534				goto fail;
535			}
536			os_memcpy(req_tmp, req_ies, req_ies_len);
537			sta->fils_pending_assoc_req = req_tmp;
538			sta->fils_pending_assoc_req_len = req_ies_len;
539			sta->fils_pending_assoc_is_reassoc = reassoc;
540			sta->fils_drv_assoc_finish = 1;
541			wpa_printf(MSG_DEBUG,
542				   "FILS: Waiting for HLP processing before sending (Re)Association Response frame to "
543				   MACSTR, MAC2STR(sta->addr));
544			eloop_register_timeout(
545				0, hapd->conf->fils_hlp_wait_time * 1024,
546				fils_hlp_timeout, hapd, sta);
547			return 0;
548		}
549		p = hostapd_eid_assoc_fils_session(sta->wpa_sm, p,
550						   elems.fils_session,
551						   sta->fils_hlp_resp);
552		wpa_hexdump(MSG_DEBUG, "FILS Assoc Resp BUF (IEs)",
553			    buf, p - buf);
554	}
555#endif /* CONFIG_FILS */
556
557#ifdef CONFIG_OWE
558	if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) &&
559	    wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_OWE &&
560	    elems.owe_dh) {
561		u8 *npos;
562
563		npos = owe_assoc_req_process(hapd, sta,
564					     elems.owe_dh, elems.owe_dh_len,
565					     p, sizeof(buf) - (p - buf),
566					     &reason);
567		if (npos)
568			p = npos;
569		if (!npos &&
570		    reason == WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED) {
571			status = WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
572			hostapd_sta_assoc(hapd, addr, reassoc, status, buf,
573					  p - buf);
574			return 0;
575		}
576
577		if (!npos || reason != WLAN_STATUS_SUCCESS)
578			goto fail;
579	}
580#endif /* CONFIG_OWE */
581
582#ifdef CONFIG_DPP2
583		dpp_pfs_free(sta->dpp_pfs);
584		sta->dpp_pfs = NULL;
585
586		if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) &&
587		    hapd->conf->dpp_netaccesskey && sta->wpa_sm &&
588		    wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_DPP &&
589		    elems.owe_dh) {
590			sta->dpp_pfs = dpp_pfs_init(
591				wpabuf_head(hapd->conf->dpp_netaccesskey),
592				wpabuf_len(hapd->conf->dpp_netaccesskey));
593			if (!sta->dpp_pfs) {
594				wpa_printf(MSG_DEBUG,
595					   "DPP: Could not initialize PFS");
596				/* Try to continue without PFS */
597				goto pfs_fail;
598			}
599
600			if (dpp_pfs_process(sta->dpp_pfs, elems.owe_dh,
601					    elems.owe_dh_len) < 0) {
602				dpp_pfs_free(sta->dpp_pfs);
603				sta->dpp_pfs = NULL;
604				reason = WLAN_REASON_UNSPECIFIED;
605				goto fail;
606			}
607		}
608
609		wpa_auth_set_dpp_z(sta->wpa_sm, sta->dpp_pfs ?
610				   sta->dpp_pfs->secret : NULL);
611	pfs_fail:
612#endif /* CONFIG_DPP2 */
613
614#if defined(CONFIG_IEEE80211R_AP) || defined(CONFIG_FILS) || defined(CONFIG_OWE)
615	hostapd_sta_assoc(hapd, addr, reassoc, status, buf, p - buf);
616
617	if (sta->auth_alg == WLAN_AUTH_FT ||
618	    sta->auth_alg == WLAN_AUTH_FILS_SK ||
619	    sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
620	    sta->auth_alg == WLAN_AUTH_FILS_PK)
621		ap_sta_set_authorized(hapd, sta, 1);
622#else /* CONFIG_IEEE80211R_AP || CONFIG_FILS */
623	/* Keep compiler silent about unused variables */
624	if (status) {
625	}
626#endif /* CONFIG_IEEE80211R_AP || CONFIG_FILS */
627
628	new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;
629	sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
630	sta->flags &= ~WLAN_STA_WNM_SLEEP_MODE;
631
632	hostapd_set_sta_flags(hapd, sta);
633
634	if (reassoc && (sta->auth_alg == WLAN_AUTH_FT))
635		wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT);
636#ifdef CONFIG_FILS
637	else if (sta->auth_alg == WLAN_AUTH_FILS_SK ||
638		 sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
639		 sta->auth_alg == WLAN_AUTH_FILS_PK)
640		wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FILS);
641#endif /* CONFIG_FILS */
642	else
643		wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
644
645	hostapd_new_assoc_sta(hapd, sta, !new_assoc);
646
647	ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
648
649#ifdef CONFIG_P2P
650	if (req_ies) {
651		p2p_group_notif_assoc(hapd->p2p_group, sta->addr,
652				      req_ies, req_ies_len);
653	}
654#endif /* CONFIG_P2P */
655
656	return 0;
657
658fail:
659#ifdef CONFIG_IEEE80211R_AP
660	hostapd_sta_assoc(hapd, addr, reassoc, status, buf, p - buf);
661#endif /* CONFIG_IEEE80211R_AP */
662	hostapd_drv_sta_disassoc(hapd, sta->addr, reason);
663	ap_free_sta(hapd, sta);
664	return -1;
665}
666
667
668void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr)
669{
670	struct sta_info *sta;
671
672	if (addr == NULL) {
673		/*
674		 * This could potentially happen with unexpected event from the
675		 * driver wrapper. This was seen at least in one case where the
676		 * driver ended up reporting a station mode event while hostapd
677		 * was running, so better make sure we stop processing such an
678		 * event here.
679		 */
680		wpa_printf(MSG_DEBUG,
681			   "hostapd_notif_disassoc: Skip event with no address");
682		return;
683	}
684
685	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
686		       HOSTAPD_LEVEL_INFO, "disassociated");
687
688	sta = ap_get_sta(hapd, addr);
689	if (sta == NULL) {
690		wpa_printf(MSG_DEBUG,
691			   "Disassociation notification for unknown STA "
692			   MACSTR, MAC2STR(addr));
693		return;
694	}
695
696	ap_sta_set_authorized(hapd, sta, 0);
697	sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
698	wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
699	sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
700	ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
701	ap_free_sta(hapd, sta);
702}
703
704
705void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr)
706{
707	struct sta_info *sta = ap_get_sta(hapd, addr);
708
709	if (!sta || !hapd->conf->disassoc_low_ack || sta->agreed_to_steer)
710		return;
711
712	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
713		       HOSTAPD_LEVEL_INFO,
714		       "disconnected due to excessive missing ACKs");
715	hostapd_drv_sta_disassoc(hapd, addr, WLAN_REASON_DISASSOC_LOW_ACK);
716	ap_sta_disassociate(hapd, sta, WLAN_REASON_DISASSOC_LOW_ACK);
717}
718
719
720void hostapd_event_sta_opmode_changed(struct hostapd_data *hapd, const u8 *addr,
721				      enum smps_mode smps_mode,
722				      enum chan_width chan_width, u8 rx_nss)
723{
724	struct sta_info *sta = ap_get_sta(hapd, addr);
725	const char *txt;
726
727	if (!sta)
728		return;
729
730	switch (smps_mode) {
731	case SMPS_AUTOMATIC:
732		txt = "automatic";
733		break;
734	case SMPS_OFF:
735		txt = "off";
736		break;
737	case SMPS_DYNAMIC:
738		txt = "dynamic";
739		break;
740	case SMPS_STATIC:
741		txt = "static";
742		break;
743	default:
744		txt = NULL;
745		break;
746	}
747	if (txt) {
748		wpa_msg(hapd->msg_ctx, MSG_INFO, STA_OPMODE_SMPS_MODE_CHANGED
749			MACSTR " %s", MAC2STR(addr), txt);
750	}
751
752	switch (chan_width) {
753	case CHAN_WIDTH_20_NOHT:
754		txt = "20(no-HT)";
755		break;
756	case CHAN_WIDTH_20:
757		txt = "20";
758		break;
759	case CHAN_WIDTH_40:
760		txt = "40";
761		break;
762	case CHAN_WIDTH_80:
763		txt = "80";
764		break;
765	case CHAN_WIDTH_80P80:
766		txt = "80+80";
767		break;
768	case CHAN_WIDTH_160:
769		txt = "160";
770		break;
771	default:
772		txt = NULL;
773		break;
774	}
775	if (txt) {
776		wpa_msg(hapd->msg_ctx, MSG_INFO, STA_OPMODE_MAX_BW_CHANGED
777			MACSTR " %s", MAC2STR(addr), txt);
778	}
779
780	if (rx_nss != 0xff) {
781		wpa_msg(hapd->msg_ctx, MSG_INFO, STA_OPMODE_N_SS_CHANGED
782			MACSTR " %d", MAC2STR(addr), rx_nss);
783	}
784}
785
786
787void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
788			     int offset, int width, int cf1, int cf2,
789			     int finished)
790{
791	/* TODO: If OCV is enabled deauth STAs that don't perform a SA Query */
792
793#ifdef NEED_AP_MLME
794	int channel, chwidth, is_dfs;
795	u8 seg0_idx = 0, seg1_idx = 0;
796	size_t i;
797
798	hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
799		       HOSTAPD_LEVEL_INFO,
800		       "driver %s channel switch: freq=%d, ht=%d, vht_ch=0x%x, offset=%d, width=%d (%s), cf1=%d, cf2=%d",
801		       finished ? "had" : "starting",
802		       freq, ht, hapd->iconf->ch_switch_vht_config, offset,
803		       width, channel_width_to_string(width), cf1, cf2);
804
805	if (!hapd->iface->current_mode) {
806		hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
807			       HOSTAPD_LEVEL_WARNING,
808			       "ignore channel switch since the interface is not yet ready");
809		return;
810	}
811
812	hapd->iface->freq = freq;
813
814	channel = hostapd_hw_get_channel(hapd, freq);
815	if (!channel) {
816		hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
817			       HOSTAPD_LEVEL_WARNING,
818			       "driver switched to bad channel!");
819		return;
820	}
821
822	switch (width) {
823	case CHAN_WIDTH_80:
824		chwidth = CHANWIDTH_80MHZ;
825		break;
826	case CHAN_WIDTH_80P80:
827		chwidth = CHANWIDTH_80P80MHZ;
828		break;
829	case CHAN_WIDTH_160:
830		chwidth = CHANWIDTH_160MHZ;
831		break;
832	case CHAN_WIDTH_20_NOHT:
833	case CHAN_WIDTH_20:
834	case CHAN_WIDTH_40:
835	default:
836		chwidth = CHANWIDTH_USE_HT;
837		break;
838	}
839
840	switch (hapd->iface->current_mode->mode) {
841	case HOSTAPD_MODE_IEEE80211A:
842		if (cf1 > 5000)
843			seg0_idx = (cf1 - 5000) / 5;
844		if (cf2 > 5000)
845			seg1_idx = (cf2 - 5000) / 5;
846		break;
847	default:
848		ieee80211_freq_to_chan(cf1, &seg0_idx);
849		ieee80211_freq_to_chan(cf2, &seg1_idx);
850		break;
851	}
852
853	hapd->iconf->channel = channel;
854	hapd->iconf->ieee80211n = ht;
855	if (!ht) {
856		hapd->iconf->ieee80211ac = 0;
857	} else if (hapd->iconf->ch_switch_vht_config) {
858		/* CHAN_SWITCH VHT config */
859		if (hapd->iconf->ch_switch_vht_config &
860		    CH_SWITCH_VHT_ENABLED)
861			hapd->iconf->ieee80211ac = 1;
862		else if (hapd->iconf->ch_switch_vht_config &
863			 CH_SWITCH_VHT_DISABLED)
864			hapd->iconf->ieee80211ac = 0;
865	}
866	hapd->iconf->ch_switch_vht_config = 0;
867
868	hapd->iconf->secondary_channel = offset;
869	hostapd_set_oper_chwidth(hapd->iconf, chwidth);
870	hostapd_set_oper_centr_freq_seg0_idx(hapd->iconf, seg0_idx);
871	hostapd_set_oper_centr_freq_seg1_idx(hapd->iconf, seg1_idx);
872
873	is_dfs = ieee80211_is_dfs(freq, hapd->iface->hw_features,
874				  hapd->iface->num_hw_features);
875
876	wpa_msg(hapd->msg_ctx, MSG_INFO,
877		"%sfreq=%d ht_enabled=%d ch_offset=%d ch_width=%s cf1=%d cf2=%d dfs=%d",
878		finished ? WPA_EVENT_CHANNEL_SWITCH :
879		WPA_EVENT_CHANNEL_SWITCH_STARTED,
880		freq, ht, offset, channel_width_to_string(width),
881		cf1, cf2, is_dfs);
882	if (!finished)
883		return;
884
885	if (hapd->csa_in_progress &&
886	    freq == hapd->cs_freq_params.freq) {
887		hostapd_cleanup_cs_params(hapd);
888		ieee802_11_set_beacon(hapd);
889
890		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED
891			"freq=%d dfs=%d", freq, is_dfs);
892	} else if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) {
893		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED
894			"freq=%d dfs=%d", freq, is_dfs);
895	}
896
897	for (i = 0; i < hapd->iface->num_bss; i++)
898		hostapd_neighbor_set_own_report(hapd->iface->bss[i]);
899#endif /* NEED_AP_MLME */
900}
901
902
903void hostapd_event_connect_failed_reason(struct hostapd_data *hapd,
904					 const u8 *addr, int reason_code)
905{
906	switch (reason_code) {
907	case MAX_CLIENT_REACHED:
908		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_REJECTED_MAX_STA MACSTR,
909			MAC2STR(addr));
910		break;
911	case BLOCKED_CLIENT:
912		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_REJECTED_BLOCKED_STA MACSTR,
913			MAC2STR(addr));
914		break;
915	}
916}
917
918
919#ifdef CONFIG_ACS
920void hostapd_acs_channel_selected(struct hostapd_data *hapd,
921				  struct acs_selected_channels *acs_res)
922{
923	int ret, i;
924	int err = 0;
925
926	if (hapd->iconf->channel) {
927		wpa_printf(MSG_INFO, "ACS: Channel was already set to %d",
928			   hapd->iconf->channel);
929		return;
930	}
931
932	if (!hapd->iface->current_mode) {
933		for (i = 0; i < hapd->iface->num_hw_features; i++) {
934			struct hostapd_hw_modes *mode =
935				&hapd->iface->hw_features[i];
936
937			if (mode->mode == acs_res->hw_mode) {
938				hapd->iface->current_mode = mode;
939				break;
940			}
941		}
942		if (!hapd->iface->current_mode) {
943			hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
944				       HOSTAPD_LEVEL_WARNING,
945				       "driver selected to bad hw_mode");
946			err = 1;
947			goto out;
948		}
949	}
950
951	hapd->iface->freq = hostapd_hw_get_freq(hapd, acs_res->pri_channel);
952
953	if (!acs_res->pri_channel) {
954		hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
955			       HOSTAPD_LEVEL_WARNING,
956			       "driver switched to bad channel");
957		err = 1;
958		goto out;
959	}
960
961	hapd->iconf->channel = acs_res->pri_channel;
962	hapd->iconf->acs = 1;
963
964	if (acs_res->sec_channel == 0)
965		hapd->iconf->secondary_channel = 0;
966	else if (acs_res->sec_channel < acs_res->pri_channel)
967		hapd->iconf->secondary_channel = -1;
968	else if (acs_res->sec_channel > acs_res->pri_channel)
969		hapd->iconf->secondary_channel = 1;
970	else {
971		wpa_printf(MSG_ERROR, "Invalid secondary channel!");
972		err = 1;
973		goto out;
974	}
975
976	if (hapd->iface->conf->ieee80211ac || hapd->iface->conf->ieee80211ax) {
977		/* set defaults for backwards compatibility */
978		hostapd_set_oper_centr_freq_seg1_idx(hapd->iconf, 0);
979		hostapd_set_oper_centr_freq_seg0_idx(hapd->iconf, 0);
980		hostapd_set_oper_chwidth(hapd->iconf, CHANWIDTH_USE_HT);
981		if (acs_res->ch_width == 80) {
982			hostapd_set_oper_centr_freq_seg0_idx(
983				hapd->iconf, acs_res->vht_seg0_center_ch);
984			hostapd_set_oper_chwidth(hapd->iconf, CHANWIDTH_80MHZ);
985		} else if (acs_res->ch_width == 160) {
986			if (acs_res->vht_seg1_center_ch == 0) {
987				hostapd_set_oper_centr_freq_seg0_idx(
988					hapd->iconf,
989					acs_res->vht_seg0_center_ch);
990				hostapd_set_oper_chwidth(hapd->iconf,
991							 CHANWIDTH_160MHZ);
992			} else {
993				hostapd_set_oper_centr_freq_seg0_idx(
994					hapd->iconf,
995					acs_res->vht_seg0_center_ch);
996				hostapd_set_oper_centr_freq_seg1_idx(
997					hapd->iconf,
998					acs_res->vht_seg1_center_ch);
999				hostapd_set_oper_chwidth(hapd->iconf,
1000							 CHANWIDTH_80P80MHZ);
1001			}
1002		}
1003	}
1004
1005out:
1006	ret = hostapd_acs_completed(hapd->iface, err);
1007	if (ret) {
1008		wpa_printf(MSG_ERROR,
1009			   "ACS: Possibly channel configuration is invalid");
1010	}
1011}
1012#endif /* CONFIG_ACS */
1013
1014
1015int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, const u8 *da,
1016			 const u8 *bssid, const u8 *ie, size_t ie_len,
1017			 int ssi_signal)
1018{
1019	size_t i;
1020	int ret = 0;
1021
1022	if (sa == NULL || ie == NULL)
1023		return -1;
1024
1025	random_add_randomness(sa, ETH_ALEN);
1026	for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++) {
1027		if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx,
1028					    sa, da, bssid, ie, ie_len,
1029					    ssi_signal) > 0) {
1030			ret = 1;
1031			break;
1032		}
1033	}
1034	return ret;
1035}
1036
1037
1038#ifdef HOSTAPD
1039
1040#ifdef CONFIG_IEEE80211R_AP
1041static void hostapd_notify_auth_ft_finish(void *ctx, const u8 *dst,
1042					  const u8 *bssid,
1043					  u16 auth_transaction, u16 status,
1044					  const u8 *ies, size_t ies_len)
1045{
1046	struct hostapd_data *hapd = ctx;
1047	struct sta_info *sta;
1048
1049	sta = ap_get_sta(hapd, dst);
1050	if (sta == NULL)
1051		return;
1052
1053	hostapd_logger(hapd, dst, HOSTAPD_MODULE_IEEE80211,
1054		       HOSTAPD_LEVEL_DEBUG, "authentication OK (FT)");
1055	sta->flags |= WLAN_STA_AUTH;
1056
1057	hostapd_sta_auth(hapd, dst, auth_transaction, status, ies, ies_len);
1058}
1059#endif /* CONFIG_IEEE80211R_AP */
1060
1061
1062#ifdef CONFIG_FILS
1063static void hostapd_notify_auth_fils_finish(struct hostapd_data *hapd,
1064					    struct sta_info *sta, u16 resp,
1065					    struct wpabuf *data, int pub)
1066{
1067	if (resp == WLAN_STATUS_SUCCESS) {
1068		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1069			       HOSTAPD_LEVEL_DEBUG, "authentication OK (FILS)");
1070		sta->flags |= WLAN_STA_AUTH;
1071		wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
1072		sta->auth_alg = WLAN_AUTH_FILS_SK;
1073		mlme_authenticate_indication(hapd, sta);
1074	} else {
1075		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1076			       HOSTAPD_LEVEL_DEBUG,
1077			       "authentication failed (FILS)");
1078	}
1079
1080	hostapd_sta_auth(hapd, sta->addr, 2, resp,
1081			 data ? wpabuf_head(data) : NULL,
1082			 data ? wpabuf_len(data) : 0);
1083	wpabuf_free(data);
1084}
1085#endif /* CONFIG_FILS */
1086
1087
1088static void hostapd_notif_auth(struct hostapd_data *hapd,
1089			       struct auth_info *rx_auth)
1090{
1091	struct sta_info *sta;
1092	u16 status = WLAN_STATUS_SUCCESS;
1093	u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
1094	size_t resp_ies_len = 0;
1095
1096	sta = ap_get_sta(hapd, rx_auth->peer);
1097	if (!sta) {
1098		sta = ap_sta_add(hapd, rx_auth->peer);
1099		if (sta == NULL) {
1100			status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1101			goto fail;
1102		}
1103	}
1104	sta->flags &= ~WLAN_STA_PREAUTH;
1105	ieee802_1x_notify_pre_auth(sta->eapol_sm, 0);
1106#ifdef CONFIG_IEEE80211R_AP
1107	if (rx_auth->auth_type == WLAN_AUTH_FT && hapd->wpa_auth) {
1108		sta->auth_alg = WLAN_AUTH_FT;
1109		if (sta->wpa_sm == NULL)
1110			sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
1111							sta->addr, NULL);
1112		if (sta->wpa_sm == NULL) {
1113			wpa_printf(MSG_DEBUG,
1114				   "FT: Failed to initialize WPA state machine");
1115			status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1116			goto fail;
1117		}
1118		wpa_ft_process_auth(sta->wpa_sm, rx_auth->bssid,
1119				    rx_auth->auth_transaction, rx_auth->ies,
1120				    rx_auth->ies_len,
1121				    hostapd_notify_auth_ft_finish, hapd);
1122		return;
1123	}
1124#endif /* CONFIG_IEEE80211R_AP */
1125
1126#ifdef CONFIG_FILS
1127	if (rx_auth->auth_type == WLAN_AUTH_FILS_SK) {
1128		sta->auth_alg = WLAN_AUTH_FILS_SK;
1129		handle_auth_fils(hapd, sta, rx_auth->ies, rx_auth->ies_len,
1130				 rx_auth->auth_type, rx_auth->auth_transaction,
1131				 rx_auth->status_code,
1132				 hostapd_notify_auth_fils_finish);
1133		return;
1134	}
1135#endif /* CONFIG_FILS */
1136
1137fail:
1138	hostapd_sta_auth(hapd, rx_auth->peer, rx_auth->auth_transaction + 1,
1139			 status, resp_ies, resp_ies_len);
1140}
1141
1142
1143#ifndef NEED_AP_MLME
1144static void hostapd_action_rx(struct hostapd_data *hapd,
1145			      struct rx_mgmt *drv_mgmt)
1146{
1147	struct ieee80211_mgmt *mgmt;
1148	struct sta_info *sta;
1149	size_t plen __maybe_unused;
1150	u16 fc;
1151	u8 *action __maybe_unused;
1152
1153	if (drv_mgmt->frame_len < IEEE80211_HDRLEN + 2 + 1)
1154		return;
1155
1156	plen = drv_mgmt->frame_len - IEEE80211_HDRLEN;
1157
1158	mgmt = (struct ieee80211_mgmt *) drv_mgmt->frame;
1159	fc = le_to_host16(mgmt->frame_control);
1160	if (WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_ACTION)
1161		return; /* handled by the driver */
1162
1163	action = (u8 *) &mgmt->u.action.u;
1164	wpa_printf(MSG_DEBUG, "RX_ACTION category %u action %u sa " MACSTR
1165		   " da " MACSTR " plen %d",
1166		   mgmt->u.action.category, *action,
1167		   MAC2STR(mgmt->sa), MAC2STR(mgmt->da), (int) plen);
1168
1169	sta = ap_get_sta(hapd, mgmt->sa);
1170	if (sta == NULL) {
1171		wpa_printf(MSG_DEBUG, "%s: station not found", __func__);
1172		return;
1173	}
1174#ifdef CONFIG_IEEE80211R_AP
1175	if (mgmt->u.action.category == WLAN_ACTION_FT) {
1176		wpa_ft_action_rx(sta->wpa_sm, (u8 *) &mgmt->u.action, plen);
1177		return;
1178	}
1179#endif /* CONFIG_IEEE80211R_AP */
1180#ifdef CONFIG_IEEE80211W
1181	if (mgmt->u.action.category == WLAN_ACTION_SA_QUERY) {
1182		ieee802_11_sa_query_action(hapd, mgmt, drv_mgmt->frame_len);
1183		return;
1184	}
1185#endif /* CONFIG_IEEE80211W */
1186#ifdef CONFIG_WNM_AP
1187	if (mgmt->u.action.category == WLAN_ACTION_WNM) {
1188		ieee802_11_rx_wnm_action_ap(hapd, mgmt, drv_mgmt->frame_len);
1189		return;
1190	}
1191#endif /* CONFIG_WNM_AP */
1192#ifdef CONFIG_FST
1193	if (mgmt->u.action.category == WLAN_ACTION_FST && hapd->iface->fst) {
1194		fst_rx_action(hapd->iface->fst, mgmt, drv_mgmt->frame_len);
1195		return;
1196	}
1197#endif /* CONFIG_FST */
1198#ifdef CONFIG_DPP
1199	if (plen >= 2 + 4 &&
1200	    mgmt->u.action.u.vs_public_action.action ==
1201	    WLAN_PA_VENDOR_SPECIFIC &&
1202	    WPA_GET_BE24(mgmt->u.action.u.vs_public_action.oui) ==
1203	    OUI_WFA &&
1204	    mgmt->u.action.u.vs_public_action.variable[0] ==
1205	    DPP_OUI_TYPE) {
1206		const u8 *pos, *end;
1207
1208		pos = mgmt->u.action.u.vs_public_action.oui;
1209		end = drv_mgmt->frame + drv_mgmt->frame_len;
1210		hostapd_dpp_rx_action(hapd, mgmt->sa, pos, end - pos,
1211				      drv_mgmt->freq);
1212		return;
1213	}
1214#endif /* CONFIG_DPP */
1215}
1216#endif /* NEED_AP_MLME */
1217
1218
1219#ifdef NEED_AP_MLME
1220
1221#define HAPD_BROADCAST ((struct hostapd_data *) -1)
1222
1223static struct hostapd_data * get_hapd_bssid(struct hostapd_iface *iface,
1224					    const u8 *bssid)
1225{
1226	size_t i;
1227
1228	if (bssid == NULL)
1229		return NULL;
1230	if (bssid[0] == 0xff && bssid[1] == 0xff && bssid[2] == 0xff &&
1231	    bssid[3] == 0xff && bssid[4] == 0xff && bssid[5] == 0xff)
1232		return HAPD_BROADCAST;
1233
1234	for (i = 0; i < iface->num_bss; i++) {
1235		if (os_memcmp(bssid, iface->bss[i]->own_addr, ETH_ALEN) == 0)
1236			return iface->bss[i];
1237	}
1238
1239	return NULL;
1240}
1241
1242
1243static void hostapd_rx_from_unknown_sta(struct hostapd_data *hapd,
1244					const u8 *bssid, const u8 *addr,
1245					int wds)
1246{
1247	hapd = get_hapd_bssid(hapd->iface, bssid);
1248	if (hapd == NULL || hapd == HAPD_BROADCAST)
1249		return;
1250
1251	ieee802_11_rx_from_unknown(hapd, addr, wds);
1252}
1253
1254
1255static int hostapd_mgmt_rx(struct hostapd_data *hapd, struct rx_mgmt *rx_mgmt)
1256{
1257	struct hostapd_iface *iface = hapd->iface;
1258	const struct ieee80211_hdr *hdr;
1259	const u8 *bssid;
1260	struct hostapd_frame_info fi;
1261	int ret;
1262
1263#ifdef CONFIG_TESTING_OPTIONS
1264	if (hapd->ext_mgmt_frame_handling) {
1265		size_t hex_len = 2 * rx_mgmt->frame_len + 1;
1266		char *hex = os_malloc(hex_len);
1267
1268		if (hex) {
1269			wpa_snprintf_hex(hex, hex_len, rx_mgmt->frame,
1270					 rx_mgmt->frame_len);
1271			wpa_msg(hapd->msg_ctx, MSG_INFO, "MGMT-RX %s", hex);
1272			os_free(hex);
1273		}
1274		return 1;
1275	}
1276#endif /* CONFIG_TESTING_OPTIONS */
1277
1278	hdr = (const struct ieee80211_hdr *) rx_mgmt->frame;
1279	bssid = get_hdr_bssid(hdr, rx_mgmt->frame_len);
1280	if (bssid == NULL)
1281		return 0;
1282
1283	hapd = get_hapd_bssid(iface, bssid);
1284	if (hapd == NULL) {
1285		u16 fc = le_to_host16(hdr->frame_control);
1286
1287		/*
1288		 * Drop frames to unknown BSSIDs except for Beacon frames which
1289		 * could be used to update neighbor information.
1290		 */
1291		if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
1292		    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
1293			hapd = iface->bss[0];
1294		else
1295			return 0;
1296	}
1297
1298	os_memset(&fi, 0, sizeof(fi));
1299	fi.freq = rx_mgmt->freq;
1300	fi.datarate = rx_mgmt->datarate;
1301	fi.ssi_signal = rx_mgmt->ssi_signal;
1302
1303	if (hapd == HAPD_BROADCAST) {
1304		size_t i;
1305
1306		ret = 0;
1307		for (i = 0; i < iface->num_bss; i++) {
1308			/* if bss is set, driver will call this function for
1309			 * each bss individually. */
1310			if (rx_mgmt->drv_priv &&
1311			    (iface->bss[i]->drv_priv != rx_mgmt->drv_priv))
1312				continue;
1313
1314			if (ieee802_11_mgmt(iface->bss[i], rx_mgmt->frame,
1315					    rx_mgmt->frame_len, &fi) > 0)
1316				ret = 1;
1317		}
1318	} else
1319		ret = ieee802_11_mgmt(hapd, rx_mgmt->frame, rx_mgmt->frame_len,
1320				      &fi);
1321
1322	random_add_randomness(&fi, sizeof(fi));
1323
1324	return ret;
1325}
1326
1327
1328static void hostapd_mgmt_tx_cb(struct hostapd_data *hapd, const u8 *buf,
1329			       size_t len, u16 stype, int ok)
1330{
1331	struct ieee80211_hdr *hdr;
1332	struct hostapd_data *orig_hapd = hapd;
1333
1334	hdr = (struct ieee80211_hdr *) buf;
1335	hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len));
1336	if (!hapd)
1337		return;
1338	if (hapd == HAPD_BROADCAST) {
1339		if (stype != WLAN_FC_STYPE_ACTION || len <= 25 ||
1340		    buf[24] != WLAN_ACTION_PUBLIC)
1341			return;
1342		hapd = get_hapd_bssid(orig_hapd->iface, hdr->addr2);
1343		if (!hapd || hapd == HAPD_BROADCAST)
1344			return;
1345		/*
1346		 * Allow processing of TX status for a Public Action frame that
1347		 * used wildcard BBSID.
1348		 */
1349	}
1350	ieee802_11_mgmt_cb(hapd, buf, len, stype, ok);
1351}
1352
1353#endif /* NEED_AP_MLME */
1354
1355
1356static int hostapd_event_new_sta(struct hostapd_data *hapd, const u8 *addr)
1357{
1358	struct sta_info *sta = ap_get_sta(hapd, addr);
1359
1360	if (sta)
1361		return 0;
1362
1363	wpa_printf(MSG_DEBUG, "Data frame from unknown STA " MACSTR
1364		   " - adding a new STA", MAC2STR(addr));
1365	sta = ap_sta_add(hapd, addr);
1366	if (sta) {
1367		hostapd_new_assoc_sta(hapd, sta, 0);
1368	} else {
1369		wpa_printf(MSG_DEBUG, "Failed to add STA entry for " MACSTR,
1370			   MAC2STR(addr));
1371		return -1;
1372	}
1373
1374	return 0;
1375}
1376
1377
1378static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src,
1379				   const u8 *data, size_t data_len)
1380{
1381	struct hostapd_iface *iface = hapd->iface;
1382	struct sta_info *sta;
1383	size_t j;
1384
1385	for (j = 0; j < iface->num_bss; j++) {
1386		sta = ap_get_sta(iface->bss[j], src);
1387		if (sta && sta->flags & WLAN_STA_ASSOC) {
1388			hapd = iface->bss[j];
1389			break;
1390		}
1391	}
1392
1393	ieee802_1x_receive(hapd, src, data, data_len);
1394}
1395
1396#endif /* HOSTAPD */
1397
1398
1399static struct hostapd_channel_data * hostapd_get_mode_channel(
1400	struct hostapd_iface *iface, unsigned int freq)
1401{
1402	int i;
1403	struct hostapd_channel_data *chan;
1404
1405	for (i = 0; i < iface->current_mode->num_channels; i++) {
1406		chan = &iface->current_mode->channels[i];
1407		if ((unsigned int) chan->freq == freq)
1408			return chan;
1409	}
1410
1411	return NULL;
1412}
1413
1414
1415static void hostapd_update_nf(struct hostapd_iface *iface,
1416			      struct hostapd_channel_data *chan,
1417			      struct freq_survey *survey)
1418{
1419	if (!iface->chans_surveyed) {
1420		chan->min_nf = survey->nf;
1421		iface->lowest_nf = survey->nf;
1422	} else {
1423		if (dl_list_empty(&chan->survey_list))
1424			chan->min_nf = survey->nf;
1425		else if (survey->nf < chan->min_nf)
1426			chan->min_nf = survey->nf;
1427		if (survey->nf < iface->lowest_nf)
1428			iface->lowest_nf = survey->nf;
1429	}
1430}
1431
1432
1433static void hostapd_single_channel_get_survey(struct hostapd_iface *iface,
1434					      struct survey_results *survey_res)
1435{
1436	struct hostapd_channel_data *chan;
1437	struct freq_survey *survey;
1438	u64 divisor, dividend;
1439
1440	survey = dl_list_first(&survey_res->survey_list, struct freq_survey,
1441			       list);
1442	if (!survey || !survey->freq)
1443		return;
1444
1445	chan = hostapd_get_mode_channel(iface, survey->freq);
1446	if (!chan || chan->flag & HOSTAPD_CHAN_DISABLED)
1447		return;
1448
1449	wpa_printf(MSG_DEBUG,
1450		   "Single Channel Survey: (freq=%d channel_time=%ld channel_time_busy=%ld)",
1451		   survey->freq,
1452		   (unsigned long int) survey->channel_time,
1453		   (unsigned long int) survey->channel_time_busy);
1454
1455	if (survey->channel_time > iface->last_channel_time &&
1456	    survey->channel_time > survey->channel_time_busy) {
1457		dividend = survey->channel_time_busy -
1458			iface->last_channel_time_busy;
1459		divisor = survey->channel_time - iface->last_channel_time;
1460
1461		iface->channel_utilization = dividend * 255 / divisor;
1462		wpa_printf(MSG_DEBUG, "Channel Utilization: %d",
1463			   iface->channel_utilization);
1464	}
1465	iface->last_channel_time = survey->channel_time;
1466	iface->last_channel_time_busy = survey->channel_time_busy;
1467}
1468
1469
1470void hostapd_event_get_survey(struct hostapd_iface *iface,
1471			      struct survey_results *survey_results)
1472{
1473	struct freq_survey *survey, *tmp;
1474	struct hostapd_channel_data *chan;
1475
1476	if (dl_list_empty(&survey_results->survey_list)) {
1477		wpa_printf(MSG_DEBUG, "No survey data received");
1478		return;
1479	}
1480
1481	if (survey_results->freq_filter) {
1482		hostapd_single_channel_get_survey(iface, survey_results);
1483		return;
1484	}
1485
1486	dl_list_for_each_safe(survey, tmp, &survey_results->survey_list,
1487			      struct freq_survey, list) {
1488		chan = hostapd_get_mode_channel(iface, survey->freq);
1489		if (!chan)
1490			continue;
1491		if (chan->flag & HOSTAPD_CHAN_DISABLED)
1492			continue;
1493
1494		dl_list_del(&survey->list);
1495		dl_list_add_tail(&chan->survey_list, &survey->list);
1496
1497		hostapd_update_nf(iface, chan, survey);
1498
1499		iface->chans_surveyed++;
1500	}
1501}
1502
1503
1504#ifdef HOSTAPD
1505#ifdef NEED_AP_MLME
1506
1507static void hostapd_event_iface_unavailable(struct hostapd_data *hapd)
1508{
1509	wpa_printf(MSG_DEBUG, "Interface %s is unavailable -- stopped",
1510		   hapd->conf->iface);
1511
1512	if (hapd->csa_in_progress) {
1513		wpa_printf(MSG_INFO, "CSA failed (%s was stopped)",
1514			   hapd->conf->iface);
1515		hostapd_switch_channel_fallback(hapd->iface,
1516						&hapd->cs_freq_params);
1517	}
1518}
1519
1520
1521static void hostapd_event_dfs_radar_detected(struct hostapd_data *hapd,
1522					     struct dfs_event *radar)
1523{
1524	wpa_printf(MSG_DEBUG, "DFS radar detected on %d MHz", radar->freq);
1525	hostapd_dfs_radar_detected(hapd->iface, radar->freq, radar->ht_enabled,
1526				   radar->chan_offset, radar->chan_width,
1527				   radar->cf1, radar->cf2);
1528}
1529
1530
1531static void hostapd_event_dfs_pre_cac_expired(struct hostapd_data *hapd,
1532					      struct dfs_event *radar)
1533{
1534	wpa_printf(MSG_DEBUG, "DFS Pre-CAC expired on %d MHz", radar->freq);
1535	hostapd_dfs_pre_cac_expired(hapd->iface, radar->freq, radar->ht_enabled,
1536				    radar->chan_offset, radar->chan_width,
1537				    radar->cf1, radar->cf2);
1538}
1539
1540
1541static void hostapd_event_dfs_cac_finished(struct hostapd_data *hapd,
1542					   struct dfs_event *radar)
1543{
1544	wpa_printf(MSG_DEBUG, "DFS CAC finished on %d MHz", radar->freq);
1545	hostapd_dfs_complete_cac(hapd->iface, 1, radar->freq, radar->ht_enabled,
1546				 radar->chan_offset, radar->chan_width,
1547				 radar->cf1, radar->cf2);
1548}
1549
1550
1551static void hostapd_event_dfs_cac_aborted(struct hostapd_data *hapd,
1552					  struct dfs_event *radar)
1553{
1554	wpa_printf(MSG_DEBUG, "DFS CAC aborted on %d MHz", radar->freq);
1555	hostapd_dfs_complete_cac(hapd->iface, 0, radar->freq, radar->ht_enabled,
1556				 radar->chan_offset, radar->chan_width,
1557				 radar->cf1, radar->cf2);
1558}
1559
1560
1561static void hostapd_event_dfs_nop_finished(struct hostapd_data *hapd,
1562					   struct dfs_event *radar)
1563{
1564	wpa_printf(MSG_DEBUG, "DFS NOP finished on %d MHz", radar->freq);
1565	hostapd_dfs_nop_finished(hapd->iface, radar->freq, radar->ht_enabled,
1566				 radar->chan_offset, radar->chan_width,
1567				 radar->cf1, radar->cf2);
1568}
1569
1570
1571static void hostapd_event_dfs_cac_started(struct hostapd_data *hapd,
1572					  struct dfs_event *radar)
1573{
1574	wpa_printf(MSG_DEBUG, "DFS offload CAC started on %d MHz", radar->freq);
1575	hostapd_dfs_start_cac(hapd->iface, radar->freq, radar->ht_enabled,
1576			      radar->chan_offset, radar->chan_width,
1577			      radar->cf1, radar->cf2);
1578}
1579
1580#endif /* NEED_AP_MLME */
1581
1582
1583static void hostapd_event_wds_sta_interface_status(struct hostapd_data *hapd,
1584						   int istatus,
1585						   const char *ifname,
1586						   const u8 *addr)
1587{
1588	struct sta_info *sta = ap_get_sta(hapd, addr);
1589
1590	if (sta) {
1591		os_free(sta->ifname_wds);
1592		if (istatus == INTERFACE_ADDED)
1593			sta->ifname_wds = os_strdup(ifname);
1594		else
1595			sta->ifname_wds = NULL;
1596	}
1597
1598	wpa_msg(hapd->msg_ctx, MSG_INFO, "%sifname=%s sta_addr=" MACSTR,
1599		istatus == INTERFACE_ADDED ?
1600		WDS_STA_INTERFACE_ADDED : WDS_STA_INTERFACE_REMOVED,
1601		ifname, MAC2STR(addr));
1602}
1603
1604
1605#ifdef CONFIG_OWE
1606static int hostapd_notif_update_dh_ie(struct hostapd_data *hapd,
1607				      const u8 *peer, const u8 *ie,
1608				      size_t ie_len)
1609{
1610	u16 status;
1611	struct sta_info *sta;
1612	struct ieee802_11_elems elems;
1613
1614	if (!hapd || !hapd->wpa_auth) {
1615		wpa_printf(MSG_DEBUG, "OWE: Invalid hapd context");
1616		return -1;
1617	}
1618	if (!peer) {
1619		wpa_printf(MSG_DEBUG, "OWE: Peer unknown");
1620		return -1;
1621	}
1622	if (!(hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE)) {
1623		wpa_printf(MSG_DEBUG, "OWE: No OWE AKM configured");
1624		status = WLAN_STATUS_AKMP_NOT_VALID;
1625		goto err;
1626	}
1627	if (ieee802_11_parse_elems(ie, ie_len, &elems, 1) == ParseFailed) {
1628		wpa_printf(MSG_DEBUG, "OWE: Failed to parse OWE IE for "
1629			   MACSTR, MAC2STR(peer));
1630		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1631		goto err;
1632	}
1633	status = owe_validate_request(hapd, peer, elems.rsn_ie,
1634				      elems.rsn_ie_len,
1635				      elems.owe_dh, elems.owe_dh_len);
1636	if (status != WLAN_STATUS_SUCCESS)
1637		goto err;
1638
1639	sta = ap_get_sta(hapd, peer);
1640	if (sta) {
1641		ap_sta_no_session_timeout(hapd, sta);
1642		accounting_sta_stop(hapd, sta);
1643
1644		/*
1645		 * Make sure that the previously registered inactivity timer
1646		 * will not remove the STA immediately.
1647		 */
1648		sta->timeout_next = STA_NULLFUNC;
1649	} else {
1650		sta = ap_sta_add(hapd, peer);
1651		if (!sta) {
1652			status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1653			goto err;
1654		}
1655	}
1656	sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2);
1657
1658	status = owe_process_rsn_ie(hapd, sta, elems.rsn_ie,
1659				    elems.rsn_ie_len, elems.owe_dh,
1660				    elems.owe_dh_len);
1661	if (status != WLAN_STATUS_SUCCESS)
1662		ap_free_sta(hapd, sta);
1663
1664	return 0;
1665err:
1666	hostapd_drv_update_dh_ie(hapd, peer, status, NULL, 0);
1667	return 0;
1668}
1669#endif /* CONFIG_OWE */
1670
1671
1672void wpa_supplicant_event_hapd(void *ctx, enum wpa_event_type event,
1673			  union wpa_event_data *data)
1674{
1675	struct hostapd_data *hapd = ctx;
1676#ifndef CONFIG_NO_STDOUT_DEBUG
1677	int level = MSG_DEBUG;
1678
1679	if (event == EVENT_RX_MGMT && data->rx_mgmt.frame &&
1680	    data->rx_mgmt.frame_len >= 24) {
1681		const struct ieee80211_hdr *hdr;
1682		u16 fc;
1683
1684		hdr = (const struct ieee80211_hdr *) data->rx_mgmt.frame;
1685		fc = le_to_host16(hdr->frame_control);
1686		if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
1687		    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
1688			level = MSG_EXCESSIVE;
1689		if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
1690		    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_REQ)
1691			level = MSG_EXCESSIVE;
1692	}
1693
1694	wpa_dbg(hapd->msg_ctx, level, "Event %s (%d) received",
1695		event_to_string(event), event);
1696#endif /* CONFIG_NO_STDOUT_DEBUG */
1697
1698	switch (event) {
1699	case EVENT_MICHAEL_MIC_FAILURE:
1700		michael_mic_failure(hapd, data->michael_mic_failure.src, 1);
1701		break;
1702	case EVENT_SCAN_RESULTS:
1703		if (hapd->iface->scan_cb)
1704			hapd->iface->scan_cb(hapd->iface);
1705		break;
1706	case EVENT_WPS_BUTTON_PUSHED:
1707		hostapd_wps_button_pushed(hapd, NULL);
1708		break;
1709#ifdef NEED_AP_MLME
1710	case EVENT_TX_STATUS:
1711		switch (data->tx_status.type) {
1712		case WLAN_FC_TYPE_MGMT:
1713			hostapd_mgmt_tx_cb(hapd, data->tx_status.data,
1714					   data->tx_status.data_len,
1715					   data->tx_status.stype,
1716					   data->tx_status.ack);
1717			break;
1718		case WLAN_FC_TYPE_DATA:
1719			hostapd_tx_status(hapd, data->tx_status.dst,
1720					  data->tx_status.data,
1721					  data->tx_status.data_len,
1722					  data->tx_status.ack);
1723			break;
1724		}
1725		break;
1726	case EVENT_EAPOL_TX_STATUS:
1727		hostapd_eapol_tx_status(hapd, data->eapol_tx_status.dst,
1728					data->eapol_tx_status.data,
1729					data->eapol_tx_status.data_len,
1730					data->eapol_tx_status.ack);
1731		break;
1732	case EVENT_DRIVER_CLIENT_POLL_OK:
1733		hostapd_client_poll_ok(hapd, data->client_poll.addr);
1734		break;
1735	case EVENT_RX_FROM_UNKNOWN:
1736		hostapd_rx_from_unknown_sta(hapd, data->rx_from_unknown.bssid,
1737					    data->rx_from_unknown.addr,
1738					    data->rx_from_unknown.wds);
1739		break;
1740#endif /* NEED_AP_MLME */
1741	case EVENT_RX_MGMT:
1742		if (!data->rx_mgmt.frame)
1743			break;
1744#ifdef NEED_AP_MLME
1745		hostapd_mgmt_rx(hapd, &data->rx_mgmt);
1746#else /* NEED_AP_MLME */
1747		hostapd_action_rx(hapd, &data->rx_mgmt);
1748#endif /* NEED_AP_MLME */
1749		break;
1750	case EVENT_RX_PROBE_REQ:
1751		if (data->rx_probe_req.sa == NULL ||
1752		    data->rx_probe_req.ie == NULL)
1753			break;
1754		hostapd_probe_req_rx(hapd, data->rx_probe_req.sa,
1755				     data->rx_probe_req.da,
1756				     data->rx_probe_req.bssid,
1757				     data->rx_probe_req.ie,
1758				     data->rx_probe_req.ie_len,
1759				     data->rx_probe_req.ssi_signal);
1760		break;
1761	case EVENT_NEW_STA:
1762		hostapd_event_new_sta(hapd, data->new_sta.addr);
1763		break;
1764	case EVENT_EAPOL_RX:
1765		hostapd_event_eapol_rx(hapd, data->eapol_rx.src,
1766				       data->eapol_rx.data,
1767				       data->eapol_rx.data_len);
1768		break;
1769	case EVENT_ASSOC:
1770		if (!data)
1771			return;
1772		hostapd_notif_assoc(hapd, data->assoc_info.addr,
1773				    data->assoc_info.req_ies,
1774				    data->assoc_info.req_ies_len,
1775				    data->assoc_info.reassoc);
1776		break;
1777#ifdef CONFIG_OWE
1778	case EVENT_UPDATE_DH:
1779		if (!data)
1780			return;
1781		hostapd_notif_update_dh_ie(hapd, data->update_dh.peer,
1782					   data->update_dh.ie,
1783					   data->update_dh.ie_len);
1784		break;
1785#endif /* CONFIG_OWE */
1786	case EVENT_DISASSOC:
1787		if (data)
1788			hostapd_notif_disassoc(hapd, data->disassoc_info.addr);
1789		break;
1790	case EVENT_DEAUTH:
1791		if (data)
1792			hostapd_notif_disassoc(hapd, data->deauth_info.addr);
1793		break;
1794	case EVENT_STATION_LOW_ACK:
1795		if (!data)
1796			break;
1797		hostapd_event_sta_low_ack(hapd, data->low_ack.addr);
1798		break;
1799	case EVENT_AUTH:
1800		hostapd_notif_auth(hapd, &data->auth);
1801		break;
1802	case EVENT_CH_SWITCH_STARTED:
1803	case EVENT_CH_SWITCH:
1804		if (!data)
1805			break;
1806		hostapd_event_ch_switch(hapd, data->ch_switch.freq,
1807					data->ch_switch.ht_enabled,
1808					data->ch_switch.ch_offset,
1809					data->ch_switch.ch_width,
1810					data->ch_switch.cf1,
1811					data->ch_switch.cf2,
1812					event == EVENT_CH_SWITCH);
1813		break;
1814	case EVENT_CONNECT_FAILED_REASON:
1815		if (!data)
1816			break;
1817		hostapd_event_connect_failed_reason(
1818			hapd, data->connect_failed_reason.addr,
1819			data->connect_failed_reason.code);
1820		break;
1821	case EVENT_SURVEY:
1822		hostapd_event_get_survey(hapd->iface, &data->survey_results);
1823		break;
1824#ifdef NEED_AP_MLME
1825	case EVENT_INTERFACE_UNAVAILABLE:
1826		hostapd_event_iface_unavailable(hapd);
1827		break;
1828	case EVENT_DFS_RADAR_DETECTED:
1829		if (!data)
1830			break;
1831		hostapd_event_dfs_radar_detected(hapd, &data->dfs_event);
1832		break;
1833	case EVENT_DFS_PRE_CAC_EXPIRED:
1834		if (!data)
1835			break;
1836		hostapd_event_dfs_pre_cac_expired(hapd, &data->dfs_event);
1837		break;
1838	case EVENT_DFS_CAC_FINISHED:
1839		if (!data)
1840			break;
1841		hostapd_event_dfs_cac_finished(hapd, &data->dfs_event);
1842		break;
1843	case EVENT_DFS_CAC_ABORTED:
1844		if (!data)
1845			break;
1846		hostapd_event_dfs_cac_aborted(hapd, &data->dfs_event);
1847		break;
1848	case EVENT_DFS_NOP_FINISHED:
1849		if (!data)
1850			break;
1851		hostapd_event_dfs_nop_finished(hapd, &data->dfs_event);
1852		break;
1853	case EVENT_CHANNEL_LIST_CHANGED:
1854		/* channel list changed (regulatory?), update channel list */
1855		/* TODO: check this. hostapd_get_hw_features() initializes
1856		 * too much stuff. */
1857		/* hostapd_get_hw_features(hapd->iface); */
1858		hostapd_channel_list_updated(
1859			hapd->iface, data->channel_list_changed.initiator);
1860		break;
1861	case EVENT_DFS_CAC_STARTED:
1862		if (!data)
1863			break;
1864		hostapd_event_dfs_cac_started(hapd, &data->dfs_event);
1865		break;
1866#endif /* NEED_AP_MLME */
1867	case EVENT_INTERFACE_ENABLED:
1868		wpa_msg(hapd->msg_ctx, MSG_INFO, INTERFACE_ENABLED);
1869		if (hapd->disabled && hapd->started) {
1870			hapd->disabled = 0;
1871			/*
1872			 * Try to re-enable interface if the driver stopped it
1873			 * when the interface got disabled.
1874			 */
1875			if (hapd->wpa_auth)
1876				wpa_auth_reconfig_group_keys(hapd->wpa_auth);
1877			else
1878				hostapd_reconfig_encryption(hapd);
1879			hapd->reenable_beacon = 1;
1880			ieee802_11_set_beacon(hapd);
1881#ifdef NEED_AP_MLME
1882		} else if (hapd->disabled && hapd->iface->cac_started) {
1883			wpa_printf(MSG_DEBUG, "DFS: restarting pending CAC");
1884			hostapd_handle_dfs(hapd->iface);
1885#endif /* NEED_AP_MLME */
1886		}
1887		break;
1888	case EVENT_INTERFACE_DISABLED:
1889		hostapd_free_stas(hapd);
1890		wpa_msg(hapd->msg_ctx, MSG_INFO, INTERFACE_DISABLED);
1891		hapd->disabled = 1;
1892		break;
1893#ifdef CONFIG_ACS
1894	case EVENT_ACS_CHANNEL_SELECTED:
1895		hostapd_acs_channel_selected(hapd,
1896					     &data->acs_selected_channels);
1897		break;
1898#endif /* CONFIG_ACS */
1899	case EVENT_STATION_OPMODE_CHANGED:
1900		hostapd_event_sta_opmode_changed(hapd, data->sta_opmode.addr,
1901						 data->sta_opmode.smps_mode,
1902						 data->sta_opmode.chan_width,
1903						 data->sta_opmode.rx_nss);
1904		break;
1905	case EVENT_WDS_STA_INTERFACE_STATUS:
1906		hostapd_event_wds_sta_interface_status(
1907			hapd, data->wds_sta_interface.istatus,
1908			data->wds_sta_interface.ifname,
1909			data->wds_sta_interface.sta_addr);
1910		break;
1911	default:
1912		wpa_printf(MSG_DEBUG, "Unknown event %d", event);
1913		break;
1914	}
1915}
1916
1917
1918void wpa_supplicant_event_global_hapd(void *ctx, enum wpa_event_type event,
1919				 union wpa_event_data *data)
1920{
1921	struct hapd_interfaces *interfaces = ctx;
1922	struct hostapd_data *hapd;
1923
1924	if (event != EVENT_INTERFACE_STATUS)
1925		return;
1926
1927	hapd = hostapd_get_iface(interfaces, data->interface_status.ifname);
1928	if (hapd && hapd->driver && hapd->driver->get_ifindex &&
1929	    hapd->drv_priv) {
1930		unsigned int ifindex;
1931
1932		ifindex = hapd->driver->get_ifindex(hapd->drv_priv);
1933		if (ifindex != data->interface_status.ifindex) {
1934			wpa_dbg(hapd->msg_ctx, MSG_DEBUG,
1935				"interface status ifindex %d mismatch (%d)",
1936				ifindex, data->interface_status.ifindex);
1937			return;
1938		}
1939	}
1940	if (hapd)
1941		wpa_supplicant_event_hapd(hapd, event, data);
1942}
1943
1944#endif /* HOSTAPD */
1945