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 "crypto/random.h"
19#include "p2p/p2p.h"
20#include "wps/wps.h"
21#include "fst/fst.h"
22#include "wnm_ap.h"
23#include "hostapd.h"
24#include "ieee802_11.h"
25#include "ieee802_11_auth.h"
26#include "sta_info.h"
27#include "accounting.h"
28#include "tkip_countermeasures.h"
29#include "ieee802_1x.h"
30#include "wpa_auth.h"
31#include "wps_hostapd.h"
32#include "ap_drv_ops.h"
33#include "ap_config.h"
34#include "hw_features.h"
35#include "dfs.h"
36#include "beacon.h"
37#include "mbo_ap.h"
38
39
40int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
41			const u8 *req_ies, size_t req_ies_len, int reassoc)
42{
43	struct sta_info *sta;
44	int new_assoc, res;
45	struct ieee802_11_elems elems;
46	const u8 *ie;
47	size_t ielen;
48#if defined(CONFIG_IEEE80211R) || defined(CONFIG_IEEE80211W)
49	u8 buf[sizeof(struct ieee80211_mgmt) + 1024];
50	u8 *p = buf;
51#endif /* CONFIG_IEEE80211R || CONFIG_IEEE80211W */
52	u16 reason = WLAN_REASON_UNSPECIFIED;
53	u16 status = WLAN_STATUS_SUCCESS;
54	const u8 *p2p_dev_addr = NULL;
55
56	if (addr == NULL) {
57		/*
58		 * This could potentially happen with unexpected event from the
59		 * driver wrapper. This was seen at least in one case where the
60		 * driver ended up being set to station mode while hostapd was
61		 * running, so better make sure we stop processing such an
62		 * event here.
63		 */
64		wpa_printf(MSG_DEBUG,
65			   "hostapd_notif_assoc: Skip event with no address");
66		return -1;
67	}
68	random_add_randomness(addr, ETH_ALEN);
69
70	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
71		       HOSTAPD_LEVEL_INFO, "associated");
72
73	ieee802_11_parse_elems(req_ies, req_ies_len, &elems, 0);
74	if (elems.wps_ie) {
75		ie = elems.wps_ie - 2;
76		ielen = elems.wps_ie_len + 2;
77		wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)AssocReq");
78	} else if (elems.rsn_ie) {
79		ie = elems.rsn_ie - 2;
80		ielen = elems.rsn_ie_len + 2;
81		wpa_printf(MSG_DEBUG, "STA included RSN IE in (Re)AssocReq");
82	} else if (elems.wpa_ie) {
83		ie = elems.wpa_ie - 2;
84		ielen = elems.wpa_ie_len + 2;
85		wpa_printf(MSG_DEBUG, "STA included WPA IE in (Re)AssocReq");
86#ifdef CONFIG_HS20
87	} else if (elems.osen) {
88		ie = elems.osen - 2;
89		ielen = elems.osen_len + 2;
90		wpa_printf(MSG_DEBUG, "STA included OSEN IE in (Re)AssocReq");
91#endif /* CONFIG_HS20 */
92	} else {
93		ie = NULL;
94		ielen = 0;
95		wpa_printf(MSG_DEBUG,
96			   "STA did not include WPS/RSN/WPA IE in (Re)AssocReq");
97	}
98
99	sta = ap_get_sta(hapd, addr);
100	if (sta) {
101		ap_sta_no_session_timeout(hapd, sta);
102		accounting_sta_stop(hapd, sta);
103
104		/*
105		 * Make sure that the previously registered inactivity timer
106		 * will not remove the STA immediately.
107		 */
108		sta->timeout_next = STA_NULLFUNC;
109	} else {
110		sta = ap_sta_add(hapd, addr);
111		if (sta == NULL) {
112			hostapd_drv_sta_disassoc(hapd, addr,
113						 WLAN_REASON_DISASSOC_AP_BUSY);
114			return -1;
115		}
116	}
117	sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2);
118
119	res = hostapd_check_acl(hapd, addr, NULL);
120	if (res != HOSTAPD_ACL_ACCEPT) {
121		wpa_printf(MSG_INFO, "STA " MACSTR " not allowed to connect",
122			   MAC2STR(addr));
123		reason = WLAN_REASON_UNSPECIFIED;
124		goto fail;
125	}
126
127#ifdef CONFIG_P2P
128	if (elems.p2p) {
129		wpabuf_free(sta->p2p_ie);
130		sta->p2p_ie = ieee802_11_vendor_ie_concat(req_ies, req_ies_len,
131							  P2P_IE_VENDOR_TYPE);
132		if (sta->p2p_ie)
133			p2p_dev_addr = p2p_get_go_dev_addr(sta->p2p_ie);
134	}
135#endif /* CONFIG_P2P */
136
137#ifdef CONFIG_IEEE80211N
138#ifdef NEED_AP_MLME
139	if (elems.ht_capabilities &&
140	    (hapd->iface->conf->ht_capab &
141	     HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) {
142		struct ieee80211_ht_capabilities *ht_cap =
143			(struct ieee80211_ht_capabilities *)
144			elems.ht_capabilities;
145
146		if (le_to_host16(ht_cap->ht_capabilities_info) &
147		    HT_CAP_INFO_40MHZ_INTOLERANT)
148			ht40_intolerant_add(hapd->iface, sta);
149	}
150#endif /* NEED_AP_MLME */
151#endif /* CONFIG_IEEE80211N */
152
153#ifdef CONFIG_INTERWORKING
154	if (elems.ext_capab && elems.ext_capab_len > 4) {
155		if (elems.ext_capab[4] & 0x01)
156			sta->qos_map_enabled = 1;
157	}
158#endif /* CONFIG_INTERWORKING */
159
160#ifdef CONFIG_HS20
161	wpabuf_free(sta->hs20_ie);
162	if (elems.hs20 && elems.hs20_len > 4) {
163		sta->hs20_ie = wpabuf_alloc_copy(elems.hs20 + 4,
164						 elems.hs20_len - 4);
165	} else
166		sta->hs20_ie = NULL;
167#endif /* CONFIG_HS20 */
168
169#ifdef CONFIG_FST
170	wpabuf_free(sta->mb_ies);
171	if (hapd->iface->fst)
172		sta->mb_ies = mb_ies_by_info(&elems.mb_ies);
173	else
174		sta->mb_ies = NULL;
175#endif /* CONFIG_FST */
176
177	mbo_ap_check_sta_assoc(hapd, sta, &elems);
178
179	ap_copy_sta_supp_op_classes(sta, elems.supp_op_classes,
180				    elems.supp_op_classes_len);
181
182	if (hapd->conf->wpa) {
183		if (ie == NULL || ielen == 0) {
184#ifdef CONFIG_WPS
185			if (hapd->conf->wps_state) {
186				wpa_printf(MSG_DEBUG,
187					   "STA did not include WPA/RSN IE in (Re)Association Request - possible WPS use");
188				sta->flags |= WLAN_STA_MAYBE_WPS;
189				goto skip_wpa_check;
190			}
191#endif /* CONFIG_WPS */
192
193			wpa_printf(MSG_DEBUG, "No WPA/RSN IE from STA");
194			return -1;
195		}
196#ifdef CONFIG_WPS
197		if (hapd->conf->wps_state && ie[0] == 0xdd && ie[1] >= 4 &&
198		    os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) {
199			struct wpabuf *wps;
200
201			sta->flags |= WLAN_STA_WPS;
202			wps = ieee802_11_vendor_ie_concat(ie, ielen,
203							  WPS_IE_VENDOR_TYPE);
204			if (wps) {
205				if (wps_is_20(wps)) {
206					wpa_printf(MSG_DEBUG,
207						   "WPS: STA supports WPS 2.0");
208					sta->flags |= WLAN_STA_WPS2;
209				}
210				wpabuf_free(wps);
211			}
212			goto skip_wpa_check;
213		}
214#endif /* CONFIG_WPS */
215
216		if (sta->wpa_sm == NULL)
217			sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
218							sta->addr,
219							p2p_dev_addr);
220		if (sta->wpa_sm == NULL) {
221			wpa_printf(MSG_ERROR,
222				   "Failed to initialize WPA state machine");
223			return -1;
224		}
225		res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
226					  ie, ielen,
227					  elems.mdie, elems.mdie_len);
228		if (res != WPA_IE_OK) {
229			wpa_printf(MSG_DEBUG,
230				   "WPA/RSN information element rejected? (res %u)",
231				   res);
232			wpa_hexdump(MSG_DEBUG, "IE", ie, ielen);
233			if (res == WPA_INVALID_GROUP) {
234				reason = WLAN_REASON_GROUP_CIPHER_NOT_VALID;
235				status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
236			} else if (res == WPA_INVALID_PAIRWISE) {
237				reason = WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID;
238				status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
239			} else if (res == WPA_INVALID_AKMP) {
240				reason = WLAN_REASON_AKMP_NOT_VALID;
241				status = WLAN_STATUS_AKMP_NOT_VALID;
242			}
243#ifdef CONFIG_IEEE80211W
244			else if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION) {
245				reason = WLAN_REASON_INVALID_IE;
246				status = WLAN_STATUS_INVALID_IE;
247			} else if (res == WPA_INVALID_MGMT_GROUP_CIPHER) {
248				reason = WLAN_REASON_GROUP_CIPHER_NOT_VALID;
249				status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
250			}
251#endif /* CONFIG_IEEE80211W */
252			else {
253				reason = WLAN_REASON_INVALID_IE;
254				status = WLAN_STATUS_INVALID_IE;
255			}
256			goto fail;
257		}
258#ifdef CONFIG_IEEE80211W
259		if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out &&
260		    sta->sa_query_count > 0)
261			ap_check_sa_query_timeout(hapd, sta);
262		if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out &&
263		    (sta->auth_alg != WLAN_AUTH_FT)) {
264			/*
265			 * STA has already been associated with MFP and SA
266			 * Query timeout has not been reached. Reject the
267			 * association attempt temporarily and start SA Query,
268			 * if one is not pending.
269			 */
270
271			if (sta->sa_query_count == 0)
272				ap_sta_start_sa_query(hapd, sta);
273
274			status = WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY;
275
276			p = hostapd_eid_assoc_comeback_time(hapd, sta, p);
277
278			hostapd_sta_assoc(hapd, addr, reassoc, status, buf,
279					  p - buf);
280			return 0;
281		}
282
283		if (wpa_auth_uses_mfp(sta->wpa_sm))
284			sta->flags |= WLAN_STA_MFP;
285		else
286			sta->flags &= ~WLAN_STA_MFP;
287#endif /* CONFIG_IEEE80211W */
288
289#ifdef CONFIG_IEEE80211R
290		if (sta->auth_alg == WLAN_AUTH_FT) {
291			status = wpa_ft_validate_reassoc(sta->wpa_sm, req_ies,
292							 req_ies_len);
293			if (status != WLAN_STATUS_SUCCESS) {
294				if (status == WLAN_STATUS_INVALID_PMKID)
295					reason = WLAN_REASON_INVALID_IE;
296				if (status == WLAN_STATUS_INVALID_MDIE)
297					reason = WLAN_REASON_INVALID_IE;
298				if (status == WLAN_STATUS_INVALID_FTIE)
299					reason = WLAN_REASON_INVALID_IE;
300				goto fail;
301			}
302		}
303#endif /* CONFIG_IEEE80211R */
304	} else if (hapd->conf->wps_state) {
305#ifdef CONFIG_WPS
306		struct wpabuf *wps;
307
308		if (req_ies)
309			wps = ieee802_11_vendor_ie_concat(req_ies, req_ies_len,
310							  WPS_IE_VENDOR_TYPE);
311		else
312			wps = NULL;
313#ifdef CONFIG_WPS_STRICT
314		if (wps && wps_validate_assoc_req(wps) < 0) {
315			reason = WLAN_REASON_INVALID_IE;
316			status = WLAN_STATUS_INVALID_IE;
317			wpabuf_free(wps);
318			goto fail;
319		}
320#endif /* CONFIG_WPS_STRICT */
321		if (wps) {
322			sta->flags |= WLAN_STA_WPS;
323			if (wps_is_20(wps)) {
324				wpa_printf(MSG_DEBUG,
325					   "WPS: STA supports WPS 2.0");
326				sta->flags |= WLAN_STA_WPS2;
327			}
328		} else
329			sta->flags |= WLAN_STA_MAYBE_WPS;
330		wpabuf_free(wps);
331#endif /* CONFIG_WPS */
332#ifdef CONFIG_HS20
333	} else if (hapd->conf->osen) {
334		if (elems.osen == NULL) {
335			hostapd_logger(
336				hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
337				HOSTAPD_LEVEL_INFO,
338				"No HS 2.0 OSEN element in association request");
339			return WLAN_STATUS_INVALID_IE;
340		}
341
342		wpa_printf(MSG_DEBUG, "HS 2.0: OSEN association");
343		if (sta->wpa_sm == NULL)
344			sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
345							sta->addr, NULL);
346		if (sta->wpa_sm == NULL) {
347			wpa_printf(MSG_WARNING,
348				   "Failed to initialize WPA state machine");
349			return WLAN_STATUS_UNSPECIFIED_FAILURE;
350		}
351		if (wpa_validate_osen(hapd->wpa_auth, sta->wpa_sm,
352				      elems.osen - 2, elems.osen_len + 2) < 0)
353			return WLAN_STATUS_INVALID_IE;
354#endif /* CONFIG_HS20 */
355	}
356
357#ifdef CONFIG_MBO
358	if (hapd->conf->mbo_enabled && (hapd->conf->wpa & 2) &&
359	    elems.mbo && sta->cell_capa && !(sta->flags & WLAN_STA_MFP) &&
360	    hapd->conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
361		wpa_printf(MSG_INFO,
362			   "MBO: Reject WPA2 association without PMF");
363		return WLAN_STATUS_UNSPECIFIED_FAILURE;
364	}
365#endif /* CONFIG_MBO */
366
367#ifdef CONFIG_WPS
368skip_wpa_check:
369#endif /* CONFIG_WPS */
370
371#ifdef CONFIG_IEEE80211R
372	p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, buf, sizeof(buf),
373					sta->auth_alg, req_ies, req_ies_len);
374
375	hostapd_sta_assoc(hapd, addr, reassoc, status, buf, p - buf);
376
377	if (sta->auth_alg == WLAN_AUTH_FT)
378		ap_sta_set_authorized(hapd, sta, 1);
379#else /* CONFIG_IEEE80211R */
380	/* Keep compiler silent about unused variables */
381	if (status) {
382	}
383#endif /* CONFIG_IEEE80211R */
384
385	new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;
386	sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
387	sta->flags &= ~WLAN_STA_WNM_SLEEP_MODE;
388
389	hostapd_set_sta_flags(hapd, sta);
390
391	if (reassoc && (sta->auth_alg == WLAN_AUTH_FT))
392		wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT);
393	else
394		wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
395
396	hostapd_new_assoc_sta(hapd, sta, !new_assoc);
397
398	ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
399
400#ifdef CONFIG_P2P
401	if (req_ies) {
402		p2p_group_notif_assoc(hapd->p2p_group, sta->addr,
403				      req_ies, req_ies_len);
404	}
405#endif /* CONFIG_P2P */
406
407	return 0;
408
409fail:
410#ifdef CONFIG_IEEE80211R
411	hostapd_sta_assoc(hapd, addr, reassoc, status, buf, p - buf);
412#endif /* CONFIG_IEEE80211R */
413	hostapd_drv_sta_disassoc(hapd, sta->addr, reason);
414	ap_free_sta(hapd, sta);
415	return -1;
416}
417
418
419void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr)
420{
421	struct sta_info *sta;
422
423	if (addr == NULL) {
424		/*
425		 * This could potentially happen with unexpected event from the
426		 * driver wrapper. This was seen at least in one case where the
427		 * driver ended up reporting a station mode event while hostapd
428		 * was running, so better make sure we stop processing such an
429		 * event here.
430		 */
431		wpa_printf(MSG_DEBUG,
432			   "hostapd_notif_disassoc: Skip event with no address");
433		return;
434	}
435
436	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
437		       HOSTAPD_LEVEL_INFO, "disassociated");
438
439	sta = ap_get_sta(hapd, addr);
440	if (sta == NULL) {
441		wpa_printf(MSG_DEBUG,
442			   "Disassociation notification for unknown STA "
443			   MACSTR, MAC2STR(addr));
444		return;
445	}
446
447	ap_sta_set_authorized(hapd, sta, 0);
448	sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
449	wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
450	sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
451	ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
452	ap_free_sta(hapd, sta);
453}
454
455
456void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr)
457{
458	struct sta_info *sta = ap_get_sta(hapd, addr);
459
460	if (!sta || !hapd->conf->disassoc_low_ack)
461		return;
462
463	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
464		       HOSTAPD_LEVEL_INFO,
465		       "disconnected due to excessive missing ACKs");
466	hostapd_drv_sta_disassoc(hapd, addr, WLAN_REASON_DISASSOC_LOW_ACK);
467	if (sta)
468		ap_sta_disassociate(hapd, sta, WLAN_REASON_DISASSOC_LOW_ACK);
469}
470
471
472void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
473			     int offset, int width, int cf1, int cf2)
474{
475#ifdef NEED_AP_MLME
476	int channel, chwidth, is_dfs;
477	u8 seg0_idx = 0, seg1_idx = 0;
478
479	hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
480		       HOSTAPD_LEVEL_INFO,
481		       "driver had channel switch: freq=%d, ht=%d, offset=%d, width=%d (%s), cf1=%d, cf2=%d",
482		       freq, ht, offset, width, channel_width_to_string(width),
483		       cf1, cf2);
484
485	hapd->iface->freq = freq;
486
487	channel = hostapd_hw_get_channel(hapd, freq);
488	if (!channel) {
489		hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
490			       HOSTAPD_LEVEL_WARNING,
491			       "driver switched to bad channel!");
492		return;
493	}
494
495	switch (width) {
496	case CHAN_WIDTH_80:
497		chwidth = VHT_CHANWIDTH_80MHZ;
498		break;
499	case CHAN_WIDTH_80P80:
500		chwidth = VHT_CHANWIDTH_80P80MHZ;
501		break;
502	case CHAN_WIDTH_160:
503		chwidth = VHT_CHANWIDTH_160MHZ;
504		break;
505	case CHAN_WIDTH_20_NOHT:
506	case CHAN_WIDTH_20:
507	case CHAN_WIDTH_40:
508	default:
509		chwidth = VHT_CHANWIDTH_USE_HT;
510		break;
511	}
512
513	switch (hapd->iface->current_mode->mode) {
514	case HOSTAPD_MODE_IEEE80211A:
515		if (cf1 > 5000)
516			seg0_idx = (cf1 - 5000) / 5;
517		if (cf2 > 5000)
518			seg1_idx = (cf2 - 5000) / 5;
519		break;
520	default:
521		ieee80211_freq_to_chan(cf1, &seg0_idx);
522		ieee80211_freq_to_chan(cf2, &seg1_idx);
523		break;
524	}
525
526	hapd->iconf->channel = channel;
527	hapd->iconf->ieee80211n = ht;
528	if (!ht)
529		hapd->iconf->ieee80211ac = 0;
530	hapd->iconf->secondary_channel = offset;
531	hapd->iconf->vht_oper_chwidth = chwidth;
532	hapd->iconf->vht_oper_centr_freq_seg0_idx = seg0_idx;
533	hapd->iconf->vht_oper_centr_freq_seg1_idx = seg1_idx;
534
535	is_dfs = ieee80211_is_dfs(freq);
536
537	if (hapd->csa_in_progress &&
538	    freq == hapd->cs_freq_params.freq) {
539		hostapd_cleanup_cs_params(hapd);
540		ieee802_11_set_beacon(hapd);
541
542		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED
543			"freq=%d dfs=%d", freq, is_dfs);
544	} else if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) {
545		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_CSA_FINISHED
546			"freq=%d dfs=%d", freq, is_dfs);
547	}
548#endif /* NEED_AP_MLME */
549}
550
551
552void hostapd_event_connect_failed_reason(struct hostapd_data *hapd,
553					 const u8 *addr, int reason_code)
554{
555	switch (reason_code) {
556	case MAX_CLIENT_REACHED:
557		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_REJECTED_MAX_STA MACSTR,
558			MAC2STR(addr));
559		break;
560	case BLOCKED_CLIENT:
561		wpa_msg(hapd->msg_ctx, MSG_INFO, AP_REJECTED_BLOCKED_STA MACSTR,
562			MAC2STR(addr));
563		break;
564	}
565}
566
567
568#ifdef CONFIG_ACS
569void hostapd_acs_channel_selected(struct hostapd_data *hapd,
570				  struct acs_selected_channels *acs_res)
571{
572	int ret, i;
573	int err = 0;
574
575	if (hapd->iconf->channel) {
576		wpa_printf(MSG_INFO, "ACS: Channel was already set to %d",
577			   hapd->iconf->channel);
578		return;
579	}
580
581	if (!hapd->iface->current_mode) {
582		for (i = 0; i < hapd->iface->num_hw_features; i++) {
583			struct hostapd_hw_modes *mode =
584				&hapd->iface->hw_features[i];
585
586			if (mode->mode == acs_res->hw_mode) {
587				hapd->iface->current_mode = mode;
588				break;
589			}
590		}
591		if (!hapd->iface->current_mode) {
592			hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
593				       HOSTAPD_LEVEL_WARNING,
594				       "driver selected to bad hw_mode");
595			err = 1;
596			goto out;
597		}
598	}
599
600	hapd->iface->freq = hostapd_hw_get_freq(hapd, acs_res->pri_channel);
601
602	if (!acs_res->pri_channel) {
603		hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
604			       HOSTAPD_LEVEL_WARNING,
605			       "driver switched to bad channel");
606		err = 1;
607		goto out;
608	}
609
610	hapd->iconf->channel = acs_res->pri_channel;
611	hapd->iconf->acs = 1;
612
613	if (acs_res->sec_channel == 0)
614		hapd->iconf->secondary_channel = 0;
615	else if (acs_res->sec_channel < acs_res->pri_channel)
616		hapd->iconf->secondary_channel = -1;
617	else if (acs_res->sec_channel > acs_res->pri_channel)
618		hapd->iconf->secondary_channel = 1;
619	else {
620		wpa_printf(MSG_ERROR, "Invalid secondary channel!");
621		err = 1;
622		goto out;
623	}
624
625	if (hapd->iface->conf->ieee80211ac) {
626		/* set defaults for backwards compatibility */
627		hapd->iconf->vht_oper_centr_freq_seg1_idx = 0;
628		hapd->iconf->vht_oper_centr_freq_seg0_idx = 0;
629		hapd->iconf->vht_oper_chwidth = VHT_CHANWIDTH_USE_HT;
630		if (acs_res->ch_width == 80) {
631			hapd->iconf->vht_oper_centr_freq_seg0_idx =
632				acs_res->vht_seg0_center_ch;
633			hapd->iconf->vht_oper_chwidth = VHT_CHANWIDTH_80MHZ;
634		} else if (acs_res->ch_width == 160) {
635			if (acs_res->vht_seg1_center_ch == 0) {
636				hapd->iconf->vht_oper_centr_freq_seg0_idx =
637					acs_res->vht_seg0_center_ch;
638				hapd->iconf->vht_oper_chwidth =
639					VHT_CHANWIDTH_160MHZ;
640			} else {
641				hapd->iconf->vht_oper_centr_freq_seg0_idx =
642					acs_res->vht_seg0_center_ch;
643				hapd->iconf->vht_oper_centr_freq_seg1_idx =
644					acs_res->vht_seg1_center_ch;
645				hapd->iconf->vht_oper_chwidth =
646					VHT_CHANWIDTH_80P80MHZ;
647			}
648		}
649	}
650
651out:
652	ret = hostapd_acs_completed(hapd->iface, err);
653	if (ret) {
654		wpa_printf(MSG_ERROR,
655			   "ACS: Possibly channel configuration is invalid");
656	}
657}
658#endif /* CONFIG_ACS */
659
660
661int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, const u8 *da,
662			 const u8 *bssid, const u8 *ie, size_t ie_len,
663			 int ssi_signal)
664{
665	size_t i;
666	int ret = 0;
667
668	if (sa == NULL || ie == NULL)
669		return -1;
670
671	random_add_randomness(sa, ETH_ALEN);
672	for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++) {
673		if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx,
674					    sa, da, bssid, ie, ie_len,
675					    ssi_signal) > 0) {
676			ret = 1;
677			break;
678		}
679	}
680	return ret;
681}
682
683
684#ifdef HOSTAPD
685
686#ifdef CONFIG_IEEE80211R
687static void hostapd_notify_auth_ft_finish(void *ctx, const u8 *dst,
688					  const u8 *bssid,
689					  u16 auth_transaction, u16 status,
690					  const u8 *ies, size_t ies_len)
691{
692	struct hostapd_data *hapd = ctx;
693	struct sta_info *sta;
694
695	sta = ap_get_sta(hapd, dst);
696	if (sta == NULL)
697		return;
698
699	hostapd_logger(hapd, dst, HOSTAPD_MODULE_IEEE80211,
700		       HOSTAPD_LEVEL_DEBUG, "authentication OK (FT)");
701	sta->flags |= WLAN_STA_AUTH;
702
703	hostapd_sta_auth(hapd, dst, auth_transaction, status, ies, ies_len);
704}
705#endif /* CONFIG_IEEE80211R */
706
707
708static void hostapd_notif_auth(struct hostapd_data *hapd,
709			       struct auth_info *rx_auth)
710{
711	struct sta_info *sta;
712	u16 status = WLAN_STATUS_SUCCESS;
713	u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
714	size_t resp_ies_len = 0;
715
716	sta = ap_get_sta(hapd, rx_auth->peer);
717	if (!sta) {
718		sta = ap_sta_add(hapd, rx_auth->peer);
719		if (sta == NULL) {
720			status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
721			goto fail;
722		}
723	}
724	sta->flags &= ~WLAN_STA_PREAUTH;
725	ieee802_1x_notify_pre_auth(sta->eapol_sm, 0);
726#ifdef CONFIG_IEEE80211R
727	if (rx_auth->auth_type == WLAN_AUTH_FT && hapd->wpa_auth) {
728		sta->auth_alg = WLAN_AUTH_FT;
729		if (sta->wpa_sm == NULL)
730			sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
731							sta->addr, NULL);
732		if (sta->wpa_sm == NULL) {
733			wpa_printf(MSG_DEBUG,
734				   "FT: Failed to initialize WPA state machine");
735			status = WLAN_STATUS_UNSPECIFIED_FAILURE;
736			goto fail;
737		}
738		wpa_ft_process_auth(sta->wpa_sm, rx_auth->bssid,
739				    rx_auth->auth_transaction, rx_auth->ies,
740				    rx_auth->ies_len,
741				    hostapd_notify_auth_ft_finish, hapd);
742		return;
743	}
744#endif /* CONFIG_IEEE80211R */
745fail:
746	hostapd_sta_auth(hapd, rx_auth->peer, rx_auth->auth_transaction + 1,
747			 status, resp_ies, resp_ies_len);
748}
749
750
751static void hostapd_action_rx(struct hostapd_data *hapd,
752			      struct rx_mgmt *drv_mgmt)
753{
754	struct ieee80211_mgmt *mgmt;
755	struct sta_info *sta;
756	size_t plen __maybe_unused;
757	u16 fc;
758
759	if (drv_mgmt->frame_len < 24 + 1)
760		return;
761
762	plen = drv_mgmt->frame_len - 24 - 1;
763
764	mgmt = (struct ieee80211_mgmt *) drv_mgmt->frame;
765	fc = le_to_host16(mgmt->frame_control);
766	if (WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_ACTION)
767		return; /* handled by the driver */
768
769	wpa_printf(MSG_DEBUG, "RX_ACTION cat %d action plen %d",
770		   mgmt->u.action.category, (int) plen);
771
772	sta = ap_get_sta(hapd, mgmt->sa);
773	if (sta == NULL) {
774		wpa_printf(MSG_DEBUG, "%s: station not found", __func__);
775		return;
776	}
777#ifdef CONFIG_IEEE80211R
778	if (mgmt->u.action.category == WLAN_ACTION_FT) {
779		const u8 *payload = drv_mgmt->frame + 24 + 1;
780
781		wpa_ft_action_rx(sta->wpa_sm, payload, plen);
782	}
783#endif /* CONFIG_IEEE80211R */
784#ifdef CONFIG_IEEE80211W
785	if (mgmt->u.action.category == WLAN_ACTION_SA_QUERY && plen >= 4) {
786		ieee802_11_sa_query_action(
787			hapd, mgmt->sa,
788			mgmt->u.action.u.sa_query_resp.action,
789			mgmt->u.action.u.sa_query_resp.trans_id);
790	}
791#endif /* CONFIG_IEEE80211W */
792#ifdef CONFIG_WNM
793	if (mgmt->u.action.category == WLAN_ACTION_WNM) {
794		ieee802_11_rx_wnm_action_ap(hapd, mgmt, drv_mgmt->frame_len);
795	}
796#endif /* CONFIG_WNM */
797#ifdef CONFIG_FST
798	if (mgmt->u.action.category == WLAN_ACTION_FST && hapd->iface->fst) {
799		fst_rx_action(hapd->iface->fst, mgmt, drv_mgmt->frame_len);
800		return;
801	}
802#endif /* CONFIG_FST */
803
804}
805
806
807#ifdef NEED_AP_MLME
808
809#define HAPD_BROADCAST ((struct hostapd_data *) -1)
810
811static struct hostapd_data * get_hapd_bssid(struct hostapd_iface *iface,
812					    const u8 *bssid)
813{
814	size_t i;
815
816	if (bssid == NULL)
817		return NULL;
818	if (bssid[0] == 0xff && bssid[1] == 0xff && bssid[2] == 0xff &&
819	    bssid[3] == 0xff && bssid[4] == 0xff && bssid[5] == 0xff)
820		return HAPD_BROADCAST;
821
822	for (i = 0; i < iface->num_bss; i++) {
823		if (os_memcmp(bssid, iface->bss[i]->own_addr, ETH_ALEN) == 0)
824			return iface->bss[i];
825	}
826
827	return NULL;
828}
829
830
831static void hostapd_rx_from_unknown_sta(struct hostapd_data *hapd,
832					const u8 *bssid, const u8 *addr,
833					int wds)
834{
835	hapd = get_hapd_bssid(hapd->iface, bssid);
836	if (hapd == NULL || hapd == HAPD_BROADCAST)
837		return;
838
839	ieee802_11_rx_from_unknown(hapd, addr, wds);
840}
841
842
843static int hostapd_mgmt_rx(struct hostapd_data *hapd, struct rx_mgmt *rx_mgmt)
844{
845	struct hostapd_iface *iface = hapd->iface;
846	const struct ieee80211_hdr *hdr;
847	const u8 *bssid;
848	struct hostapd_frame_info fi;
849	int ret;
850
851#ifdef CONFIG_TESTING_OPTIONS
852	if (hapd->ext_mgmt_frame_handling) {
853		size_t hex_len = 2 * rx_mgmt->frame_len + 1;
854		char *hex = os_malloc(hex_len);
855
856		if (hex) {
857			wpa_snprintf_hex(hex, hex_len, rx_mgmt->frame,
858					 rx_mgmt->frame_len);
859			wpa_msg(hapd->msg_ctx, MSG_INFO, "MGMT-RX %s", hex);
860			os_free(hex);
861		}
862		return 1;
863	}
864#endif /* CONFIG_TESTING_OPTIONS */
865
866	hdr = (const struct ieee80211_hdr *) rx_mgmt->frame;
867	bssid = get_hdr_bssid(hdr, rx_mgmt->frame_len);
868	if (bssid == NULL)
869		return 0;
870
871	hapd = get_hapd_bssid(iface, bssid);
872	if (hapd == NULL) {
873		u16 fc = le_to_host16(hdr->frame_control);
874
875		/*
876		 * Drop frames to unknown BSSIDs except for Beacon frames which
877		 * could be used to update neighbor information.
878		 */
879		if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
880		    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
881			hapd = iface->bss[0];
882		else
883			return 0;
884	}
885
886	os_memset(&fi, 0, sizeof(fi));
887	fi.datarate = rx_mgmt->datarate;
888	fi.ssi_signal = rx_mgmt->ssi_signal;
889
890	if (hapd == HAPD_BROADCAST) {
891		size_t i;
892
893		ret = 0;
894		for (i = 0; i < iface->num_bss; i++) {
895			/* if bss is set, driver will call this function for
896			 * each bss individually. */
897			if (rx_mgmt->drv_priv &&
898			    (iface->bss[i]->drv_priv != rx_mgmt->drv_priv))
899				continue;
900
901			if (ieee802_11_mgmt(iface->bss[i], rx_mgmt->frame,
902					    rx_mgmt->frame_len, &fi) > 0)
903				ret = 1;
904		}
905	} else
906		ret = ieee802_11_mgmt(hapd, rx_mgmt->frame, rx_mgmt->frame_len,
907				      &fi);
908
909	random_add_randomness(&fi, sizeof(fi));
910
911	return ret;
912}
913
914
915static void hostapd_mgmt_tx_cb(struct hostapd_data *hapd, const u8 *buf,
916			       size_t len, u16 stype, int ok)
917{
918	struct ieee80211_hdr *hdr;
919
920	hdr = (struct ieee80211_hdr *) buf;
921	hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len));
922	if (hapd == NULL || hapd == HAPD_BROADCAST)
923		return;
924	ieee802_11_mgmt_cb(hapd, buf, len, stype, ok);
925}
926
927#endif /* NEED_AP_MLME */
928
929
930static int hostapd_event_new_sta(struct hostapd_data *hapd, const u8 *addr)
931{
932	struct sta_info *sta = ap_get_sta(hapd, addr);
933
934	if (sta)
935		return 0;
936
937	wpa_printf(MSG_DEBUG, "Data frame from unknown STA " MACSTR
938		   " - adding a new STA", MAC2STR(addr));
939	sta = ap_sta_add(hapd, addr);
940	if (sta) {
941		hostapd_new_assoc_sta(hapd, sta, 0);
942	} else {
943		wpa_printf(MSG_DEBUG, "Failed to add STA entry for " MACSTR,
944			   MAC2STR(addr));
945		return -1;
946	}
947
948	return 0;
949}
950
951
952static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src,
953				   const u8 *data, size_t data_len)
954{
955	struct hostapd_iface *iface = hapd->iface;
956	struct sta_info *sta;
957	size_t j;
958
959	for (j = 0; j < iface->num_bss; j++) {
960		sta = ap_get_sta(iface->bss[j], src);
961		if (sta && sta->flags & WLAN_STA_ASSOC) {
962			hapd = iface->bss[j];
963			break;
964		}
965	}
966
967	ieee802_1x_receive(hapd, src, data, data_len);
968}
969
970#endif /* HOSTAPD */
971
972
973static struct hostapd_channel_data * hostapd_get_mode_channel(
974	struct hostapd_iface *iface, unsigned int freq)
975{
976	int i;
977	struct hostapd_channel_data *chan;
978
979	for (i = 0; i < iface->current_mode->num_channels; i++) {
980		chan = &iface->current_mode->channels[i];
981		if ((unsigned int) chan->freq == freq)
982			return chan;
983	}
984
985	return NULL;
986}
987
988
989static void hostapd_update_nf(struct hostapd_iface *iface,
990			      struct hostapd_channel_data *chan,
991			      struct freq_survey *survey)
992{
993	if (!iface->chans_surveyed) {
994		chan->min_nf = survey->nf;
995		iface->lowest_nf = survey->nf;
996	} else {
997		if (dl_list_empty(&chan->survey_list))
998			chan->min_nf = survey->nf;
999		else if (survey->nf < chan->min_nf)
1000			chan->min_nf = survey->nf;
1001		if (survey->nf < iface->lowest_nf)
1002			iface->lowest_nf = survey->nf;
1003	}
1004}
1005
1006
1007static void hostapd_single_channel_get_survey(struct hostapd_iface *iface,
1008					      struct survey_results *survey_res)
1009{
1010	struct hostapd_channel_data *chan;
1011	struct freq_survey *survey;
1012	u64 divisor, dividend;
1013
1014	survey = dl_list_first(&survey_res->survey_list, struct freq_survey,
1015			       list);
1016	if (!survey || !survey->freq)
1017		return;
1018
1019	chan = hostapd_get_mode_channel(iface, survey->freq);
1020	if (!chan || chan->flag & HOSTAPD_CHAN_DISABLED)
1021		return;
1022
1023	wpa_printf(MSG_DEBUG,
1024		   "Single Channel Survey: (freq=%d channel_time=%ld channel_time_busy=%ld)",
1025		   survey->freq,
1026		   (unsigned long int) survey->channel_time,
1027		   (unsigned long int) survey->channel_time_busy);
1028
1029	if (survey->channel_time > iface->last_channel_time &&
1030	    survey->channel_time > survey->channel_time_busy) {
1031		dividend = survey->channel_time_busy -
1032			iface->last_channel_time_busy;
1033		divisor = survey->channel_time - iface->last_channel_time;
1034
1035		iface->channel_utilization = dividend * 255 / divisor;
1036		wpa_printf(MSG_DEBUG, "Channel Utilization: %d",
1037			   iface->channel_utilization);
1038	}
1039	iface->last_channel_time = survey->channel_time;
1040	iface->last_channel_time_busy = survey->channel_time_busy;
1041}
1042
1043
1044void hostapd_event_get_survey(struct hostapd_iface *iface,
1045			      struct survey_results *survey_results)
1046{
1047	struct freq_survey *survey, *tmp;
1048	struct hostapd_channel_data *chan;
1049
1050	if (dl_list_empty(&survey_results->survey_list)) {
1051		wpa_printf(MSG_DEBUG, "No survey data received");
1052		return;
1053	}
1054
1055	if (survey_results->freq_filter) {
1056		hostapd_single_channel_get_survey(iface, survey_results);
1057		return;
1058	}
1059
1060	dl_list_for_each_safe(survey, tmp, &survey_results->survey_list,
1061			      struct freq_survey, list) {
1062		chan = hostapd_get_mode_channel(iface, survey->freq);
1063		if (!chan)
1064			continue;
1065		if (chan->flag & HOSTAPD_CHAN_DISABLED)
1066			continue;
1067
1068		dl_list_del(&survey->list);
1069		dl_list_add_tail(&chan->survey_list, &survey->list);
1070
1071		hostapd_update_nf(iface, chan, survey);
1072
1073		iface->chans_surveyed++;
1074	}
1075}
1076
1077
1078#ifdef HOSTAPD
1079#ifdef NEED_AP_MLME
1080
1081static void hostapd_event_iface_unavailable(struct hostapd_data *hapd)
1082{
1083	wpa_printf(MSG_DEBUG, "Interface %s is unavailable -- stopped",
1084		   hapd->conf->iface);
1085
1086	if (hapd->csa_in_progress) {
1087		wpa_printf(MSG_INFO, "CSA failed (%s was stopped)",
1088			   hapd->conf->iface);
1089		hostapd_switch_channel_fallback(hapd->iface,
1090						&hapd->cs_freq_params);
1091	}
1092}
1093
1094
1095static void hostapd_event_dfs_radar_detected(struct hostapd_data *hapd,
1096					     struct dfs_event *radar)
1097{
1098	wpa_printf(MSG_DEBUG, "DFS radar detected on %d MHz", radar->freq);
1099	hostapd_dfs_radar_detected(hapd->iface, radar->freq, radar->ht_enabled,
1100				   radar->chan_offset, radar->chan_width,
1101				   radar->cf1, radar->cf2);
1102}
1103
1104
1105static void hostapd_event_dfs_cac_finished(struct hostapd_data *hapd,
1106					   struct dfs_event *radar)
1107{
1108	wpa_printf(MSG_DEBUG, "DFS CAC finished on %d MHz", radar->freq);
1109	hostapd_dfs_complete_cac(hapd->iface, 1, radar->freq, radar->ht_enabled,
1110				 radar->chan_offset, radar->chan_width,
1111				 radar->cf1, radar->cf2);
1112}
1113
1114
1115static void hostapd_event_dfs_cac_aborted(struct hostapd_data *hapd,
1116					  struct dfs_event *radar)
1117{
1118	wpa_printf(MSG_DEBUG, "DFS CAC aborted on %d MHz", radar->freq);
1119	hostapd_dfs_complete_cac(hapd->iface, 0, radar->freq, radar->ht_enabled,
1120				 radar->chan_offset, radar->chan_width,
1121				 radar->cf1, radar->cf2);
1122}
1123
1124
1125static void hostapd_event_dfs_nop_finished(struct hostapd_data *hapd,
1126					   struct dfs_event *radar)
1127{
1128	wpa_printf(MSG_DEBUG, "DFS NOP finished on %d MHz", radar->freq);
1129	hostapd_dfs_nop_finished(hapd->iface, radar->freq, radar->ht_enabled,
1130				 radar->chan_offset, radar->chan_width,
1131				 radar->cf1, radar->cf2);
1132}
1133
1134
1135static void hostapd_event_dfs_cac_started(struct hostapd_data *hapd,
1136					  struct dfs_event *radar)
1137{
1138	wpa_printf(MSG_DEBUG, "DFS offload CAC started on %d MHz", radar->freq);
1139	hostapd_dfs_start_cac(hapd->iface, radar->freq, radar->ht_enabled,
1140			      radar->chan_offset, radar->chan_width,
1141			      radar->cf1, radar->cf2);
1142}
1143
1144#endif /* NEED_AP_MLME */
1145
1146
1147void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
1148			  union wpa_event_data *data)
1149{
1150	struct hostapd_data *hapd = ctx;
1151#ifndef CONFIG_NO_STDOUT_DEBUG
1152	int level = MSG_DEBUG;
1153
1154	if (event == EVENT_RX_MGMT && data->rx_mgmt.frame &&
1155	    data->rx_mgmt.frame_len >= 24) {
1156		const struct ieee80211_hdr *hdr;
1157		u16 fc;
1158
1159		hdr = (const struct ieee80211_hdr *) data->rx_mgmt.frame;
1160		fc = le_to_host16(hdr->frame_control);
1161		if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
1162		    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
1163			level = MSG_EXCESSIVE;
1164		if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
1165		    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_REQ)
1166			level = MSG_EXCESSIVE;
1167	}
1168
1169	wpa_dbg(hapd->msg_ctx, level, "Event %s (%d) received",
1170		event_to_string(event), event);
1171#endif /* CONFIG_NO_STDOUT_DEBUG */
1172
1173	switch (event) {
1174	case EVENT_MICHAEL_MIC_FAILURE:
1175		michael_mic_failure(hapd, data->michael_mic_failure.src, 1);
1176		break;
1177	case EVENT_SCAN_RESULTS:
1178		if (hapd->iface->scan_cb)
1179			hapd->iface->scan_cb(hapd->iface);
1180		break;
1181	case EVENT_WPS_BUTTON_PUSHED:
1182		hostapd_wps_button_pushed(hapd, NULL);
1183		break;
1184#ifdef NEED_AP_MLME
1185	case EVENT_TX_STATUS:
1186		switch (data->tx_status.type) {
1187		case WLAN_FC_TYPE_MGMT:
1188			hostapd_mgmt_tx_cb(hapd, data->tx_status.data,
1189					   data->tx_status.data_len,
1190					   data->tx_status.stype,
1191					   data->tx_status.ack);
1192			break;
1193		case WLAN_FC_TYPE_DATA:
1194			hostapd_tx_status(hapd, data->tx_status.dst,
1195					  data->tx_status.data,
1196					  data->tx_status.data_len,
1197					  data->tx_status.ack);
1198			break;
1199		}
1200		break;
1201	case EVENT_EAPOL_TX_STATUS:
1202		hostapd_eapol_tx_status(hapd, data->eapol_tx_status.dst,
1203					data->eapol_tx_status.data,
1204					data->eapol_tx_status.data_len,
1205					data->eapol_tx_status.ack);
1206		break;
1207	case EVENT_DRIVER_CLIENT_POLL_OK:
1208		hostapd_client_poll_ok(hapd, data->client_poll.addr);
1209		break;
1210	case EVENT_RX_FROM_UNKNOWN:
1211		hostapd_rx_from_unknown_sta(hapd, data->rx_from_unknown.bssid,
1212					    data->rx_from_unknown.addr,
1213					    data->rx_from_unknown.wds);
1214		break;
1215#endif /* NEED_AP_MLME */
1216	case EVENT_RX_MGMT:
1217		if (!data->rx_mgmt.frame)
1218			break;
1219#ifdef NEED_AP_MLME
1220		if (hostapd_mgmt_rx(hapd, &data->rx_mgmt) > 0)
1221			break;
1222#endif /* NEED_AP_MLME */
1223		hostapd_action_rx(hapd, &data->rx_mgmt);
1224		break;
1225	case EVENT_RX_PROBE_REQ:
1226		if (data->rx_probe_req.sa == NULL ||
1227		    data->rx_probe_req.ie == NULL)
1228			break;
1229		hostapd_probe_req_rx(hapd, data->rx_probe_req.sa,
1230				     data->rx_probe_req.da,
1231				     data->rx_probe_req.bssid,
1232				     data->rx_probe_req.ie,
1233				     data->rx_probe_req.ie_len,
1234				     data->rx_probe_req.ssi_signal);
1235		break;
1236	case EVENT_NEW_STA:
1237		hostapd_event_new_sta(hapd, data->new_sta.addr);
1238		break;
1239	case EVENT_EAPOL_RX:
1240		hostapd_event_eapol_rx(hapd, data->eapol_rx.src,
1241				       data->eapol_rx.data,
1242				       data->eapol_rx.data_len);
1243		break;
1244	case EVENT_ASSOC:
1245		if (!data)
1246			return;
1247		hostapd_notif_assoc(hapd, data->assoc_info.addr,
1248				    data->assoc_info.req_ies,
1249				    data->assoc_info.req_ies_len,
1250				    data->assoc_info.reassoc);
1251		break;
1252	case EVENT_DISASSOC:
1253		if (data)
1254			hostapd_notif_disassoc(hapd, data->disassoc_info.addr);
1255		break;
1256	case EVENT_DEAUTH:
1257		if (data)
1258			hostapd_notif_disassoc(hapd, data->deauth_info.addr);
1259		break;
1260	case EVENT_STATION_LOW_ACK:
1261		if (!data)
1262			break;
1263		hostapd_event_sta_low_ack(hapd, data->low_ack.addr);
1264		break;
1265	case EVENT_AUTH:
1266		hostapd_notif_auth(hapd, &data->auth);
1267		break;
1268	case EVENT_CH_SWITCH:
1269		if (!data)
1270			break;
1271		hostapd_event_ch_switch(hapd, data->ch_switch.freq,
1272					data->ch_switch.ht_enabled,
1273					data->ch_switch.ch_offset,
1274					data->ch_switch.ch_width,
1275					data->ch_switch.cf1,
1276					data->ch_switch.cf2);
1277		break;
1278	case EVENT_CONNECT_FAILED_REASON:
1279		if (!data)
1280			break;
1281		hostapd_event_connect_failed_reason(
1282			hapd, data->connect_failed_reason.addr,
1283			data->connect_failed_reason.code);
1284		break;
1285	case EVENT_SURVEY:
1286		hostapd_event_get_survey(hapd->iface, &data->survey_results);
1287		break;
1288#ifdef NEED_AP_MLME
1289	case EVENT_INTERFACE_UNAVAILABLE:
1290		hostapd_event_iface_unavailable(hapd);
1291		break;
1292	case EVENT_DFS_RADAR_DETECTED:
1293		if (!data)
1294			break;
1295		hostapd_event_dfs_radar_detected(hapd, &data->dfs_event);
1296		break;
1297	case EVENT_DFS_CAC_FINISHED:
1298		if (!data)
1299			break;
1300		hostapd_event_dfs_cac_finished(hapd, &data->dfs_event);
1301		break;
1302	case EVENT_DFS_CAC_ABORTED:
1303		if (!data)
1304			break;
1305		hostapd_event_dfs_cac_aborted(hapd, &data->dfs_event);
1306		break;
1307	case EVENT_DFS_NOP_FINISHED:
1308		if (!data)
1309			break;
1310		hostapd_event_dfs_nop_finished(hapd, &data->dfs_event);
1311		break;
1312	case EVENT_CHANNEL_LIST_CHANGED:
1313		/* channel list changed (regulatory?), update channel list */
1314		/* TODO: check this. hostapd_get_hw_features() initializes
1315		 * too much stuff. */
1316		/* hostapd_get_hw_features(hapd->iface); */
1317		hostapd_channel_list_updated(
1318			hapd->iface, data->channel_list_changed.initiator);
1319		break;
1320	case EVENT_DFS_CAC_STARTED:
1321		if (!data)
1322			break;
1323		hostapd_event_dfs_cac_started(hapd, &data->dfs_event);
1324		break;
1325#endif /* NEED_AP_MLME */
1326	case EVENT_INTERFACE_ENABLED:
1327		wpa_msg(hapd->msg_ctx, MSG_INFO, INTERFACE_ENABLED);
1328		if (hapd->disabled && hapd->started) {
1329			hapd->disabled = 0;
1330			/*
1331			 * Try to re-enable interface if the driver stopped it
1332			 * when the interface got disabled.
1333			 */
1334			wpa_auth_reconfig_group_keys(hapd->wpa_auth);
1335			hapd->reenable_beacon = 1;
1336			ieee802_11_set_beacon(hapd);
1337		}
1338		break;
1339	case EVENT_INTERFACE_DISABLED:
1340		hostapd_free_stas(hapd);
1341		wpa_msg(hapd->msg_ctx, MSG_INFO, INTERFACE_DISABLED);
1342		hapd->disabled = 1;
1343		break;
1344#ifdef CONFIG_ACS
1345	case EVENT_ACS_CHANNEL_SELECTED:
1346		hostapd_acs_channel_selected(hapd,
1347					     &data->acs_selected_channels);
1348		break;
1349#endif /* CONFIG_ACS */
1350	default:
1351		wpa_printf(MSG_DEBUG, "Unknown event %d", event);
1352		break;
1353	}
1354}
1355
1356
1357void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event,
1358				 union wpa_event_data *data)
1359{
1360	struct hapd_interfaces *interfaces = ctx;
1361	struct hostapd_data *hapd;
1362
1363	if (event != EVENT_INTERFACE_STATUS)
1364		return;
1365
1366	hapd = hostapd_get_iface(interfaces, data->interface_status.ifname);
1367	if (hapd && hapd->driver && hapd->driver->get_ifindex &&
1368	    hapd->drv_priv) {
1369		unsigned int ifindex;
1370
1371		ifindex = hapd->driver->get_ifindex(hapd->drv_priv);
1372		if (ifindex != data->interface_status.ifindex) {
1373			wpa_dbg(hapd->msg_ctx, MSG_DEBUG,
1374				"interface status ifindex %d mismatch (%d)",
1375				ifindex, data->interface_status.ifindex);
1376			return;
1377		}
1378	}
1379	if (hapd)
1380		wpa_supplicant_event(hapd, event, data);
1381}
1382
1383#endif /* HOSTAPD */
1384