drv_callbacks.c revision 61d9df3e62aaa0e87ad05452fcb95142159a17b6
1/*
2 * hostapd / Callback functions for driver wrappers
3 * Copyright (c) 2002-2009, 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 "radius/radius.h"
13#include "drivers/driver.h"
14#include "common/ieee802_11_defs.h"
15#include "common/ieee802_11_common.h"
16#include "crypto/random.h"
17#include "p2p/p2p.h"
18#include "wps/wps.h"
19#include "wnm_ap.h"
20#include "hostapd.h"
21#include "ieee802_11.h"
22#include "sta_info.h"
23#include "accounting.h"
24#include "tkip_countermeasures.h"
25#include "ieee802_1x.h"
26#include "wpa_auth.h"
27#include "wps_hostapd.h"
28#include "ap_drv_ops.h"
29#include "ap_config.h"
30#include "hw_features.h"
31
32
33int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
34			const u8 *req_ies, size_t req_ies_len, int reassoc)
35{
36	struct sta_info *sta;
37	int new_assoc, res;
38	struct ieee802_11_elems elems;
39	const u8 *ie;
40	size_t ielen;
41#ifdef CONFIG_IEEE80211R
42	u8 buf[sizeof(struct ieee80211_mgmt) + 1024];
43	u8 *p = buf;
44#endif /* CONFIG_IEEE80211R */
45	u16 reason = WLAN_REASON_UNSPECIFIED;
46	u16 status = WLAN_STATUS_SUCCESS;
47
48	if (addr == NULL) {
49		/*
50		 * This could potentially happen with unexpected event from the
51		 * driver wrapper. This was seen at least in one case where the
52		 * driver ended up being set to station mode while hostapd was
53		 * running, so better make sure we stop processing such an
54		 * event here.
55		 */
56		wpa_printf(MSG_DEBUG, "hostapd_notif_assoc: Skip event with "
57			   "no address");
58		return -1;
59	}
60	random_add_randomness(addr, ETH_ALEN);
61
62	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
63		       HOSTAPD_LEVEL_INFO, "associated");
64
65	ieee802_11_parse_elems(req_ies, req_ies_len, &elems, 0);
66	if (elems.wps_ie) {
67		ie = elems.wps_ie - 2;
68		ielen = elems.wps_ie_len + 2;
69		wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)AssocReq");
70	} else if (elems.rsn_ie) {
71		ie = elems.rsn_ie - 2;
72		ielen = elems.rsn_ie_len + 2;
73		wpa_printf(MSG_DEBUG, "STA included RSN IE in (Re)AssocReq");
74	} else if (elems.wpa_ie) {
75		ie = elems.wpa_ie - 2;
76		ielen = elems.wpa_ie_len + 2;
77		wpa_printf(MSG_DEBUG, "STA included WPA IE in (Re)AssocReq");
78	} else {
79		ie = NULL;
80		ielen = 0;
81		wpa_printf(MSG_DEBUG, "STA did not include WPS/RSN/WPA IE in "
82			   "(Re)AssocReq");
83	}
84
85	sta = ap_get_sta(hapd, addr);
86	if (sta) {
87		accounting_sta_stop(hapd, sta);
88
89		/*
90		 * Make sure that the previously registered inactivity timer
91		 * will not remove the STA immediately.
92		 */
93		sta->timeout_next = STA_NULLFUNC;
94	} else {
95		sta = ap_sta_add(hapd, addr);
96		if (sta == NULL) {
97			hostapd_drv_sta_disassoc(hapd, addr,
98						 WLAN_REASON_DISASSOC_AP_BUSY);
99			return -1;
100		}
101	}
102	sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2);
103
104#ifdef CONFIG_P2P
105	if (elems.p2p) {
106		wpabuf_free(sta->p2p_ie);
107		sta->p2p_ie = ieee802_11_vendor_ie_concat(req_ies, req_ies_len,
108							  P2P_IE_VENDOR_TYPE);
109	}
110#endif /* CONFIG_P2P */
111
112	if (hapd->conf->wpa) {
113		if (ie == NULL || ielen == 0) {
114#ifdef CONFIG_WPS
115			if (hapd->conf->wps_state) {
116				wpa_printf(MSG_DEBUG, "STA did not include "
117					   "WPA/RSN IE in (Re)Association "
118					   "Request - possible WPS use");
119				sta->flags |= WLAN_STA_MAYBE_WPS;
120				goto skip_wpa_check;
121			}
122#endif /* CONFIG_WPS */
123
124			wpa_printf(MSG_DEBUG, "No WPA/RSN IE from STA");
125			return -1;
126		}
127#ifdef CONFIG_WPS
128		if (hapd->conf->wps_state && ie[0] == 0xdd && ie[1] >= 4 &&
129		    os_memcmp(ie + 2, "\x00\x50\xf2\x04", 4) == 0) {
130			struct wpabuf *wps;
131			sta->flags |= WLAN_STA_WPS;
132			wps = ieee802_11_vendor_ie_concat(ie, ielen,
133							  WPS_IE_VENDOR_TYPE);
134			if (wps) {
135				if (wps_is_20(wps)) {
136					wpa_printf(MSG_DEBUG, "WPS: STA "
137						   "supports WPS 2.0");
138					sta->flags |= WLAN_STA_WPS2;
139				}
140				wpabuf_free(wps);
141			}
142			goto skip_wpa_check;
143		}
144#endif /* CONFIG_WPS */
145
146		if (sta->wpa_sm == NULL)
147			sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
148							sta->addr);
149		if (sta->wpa_sm == NULL) {
150			wpa_printf(MSG_ERROR, "Failed to initialize WPA state "
151				   "machine");
152			return -1;
153		}
154		res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
155					  ie, ielen,
156					  elems.mdie, elems.mdie_len);
157		if (res != WPA_IE_OK) {
158			wpa_printf(MSG_DEBUG, "WPA/RSN information element "
159				   "rejected? (res %u)", res);
160			wpa_hexdump(MSG_DEBUG, "IE", ie, ielen);
161			if (res == WPA_INVALID_GROUP) {
162				reason = WLAN_REASON_GROUP_CIPHER_NOT_VALID;
163				status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
164			} else if (res == WPA_INVALID_PAIRWISE) {
165				reason = WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID;
166				status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
167			} else if (res == WPA_INVALID_AKMP) {
168				reason = WLAN_REASON_AKMP_NOT_VALID;
169				status = WLAN_STATUS_AKMP_NOT_VALID;
170			}
171#ifdef CONFIG_IEEE80211W
172			else if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION) {
173				reason = WLAN_REASON_INVALID_IE;
174				status = WLAN_STATUS_INVALID_IE;
175			} else if (res == WPA_INVALID_MGMT_GROUP_CIPHER) {
176				reason = WLAN_REASON_GROUP_CIPHER_NOT_VALID;
177				status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
178			}
179#endif /* CONFIG_IEEE80211W */
180			else {
181				reason = WLAN_REASON_INVALID_IE;
182				status = WLAN_STATUS_INVALID_IE;
183			}
184			goto fail;
185		}
186#ifdef CONFIG_IEEE80211W
187		if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out &&
188		    sta->sa_query_count > 0)
189			ap_check_sa_query_timeout(hapd, sta);
190		if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out &&
191		    (sta->auth_alg != WLAN_AUTH_FT)) {
192			/*
193			 * STA has already been associated with MFP and SA
194			 * Query timeout has not been reached. Reject the
195			 * association attempt temporarily and start SA Query,
196			 * if one is not pending.
197			 */
198
199			if (sta->sa_query_count == 0)
200				ap_sta_start_sa_query(hapd, sta);
201
202#ifdef CONFIG_IEEE80211R
203			status = WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY;
204
205			p = hostapd_eid_assoc_comeback_time(hapd, sta, p);
206
207			hostapd_sta_assoc(hapd, addr, reassoc, status, buf,
208					  p - buf);
209#endif /* CONFIG_IEEE80211R */
210			return 0;
211		}
212
213		if (wpa_auth_uses_mfp(sta->wpa_sm))
214			sta->flags |= WLAN_STA_MFP;
215		else
216			sta->flags &= ~WLAN_STA_MFP;
217#endif /* CONFIG_IEEE80211W */
218
219#ifdef CONFIG_IEEE80211R
220		if (sta->auth_alg == WLAN_AUTH_FT) {
221			status = wpa_ft_validate_reassoc(sta->wpa_sm, req_ies,
222							 req_ies_len);
223			if (status != WLAN_STATUS_SUCCESS) {
224				if (status == WLAN_STATUS_INVALID_PMKID)
225					reason = WLAN_REASON_INVALID_IE;
226				if (status == WLAN_STATUS_INVALID_MDIE)
227					reason = WLAN_REASON_INVALID_IE;
228				if (status == WLAN_STATUS_INVALID_FTIE)
229					reason = WLAN_REASON_INVALID_IE;
230				goto fail;
231			}
232		}
233#endif /* CONFIG_IEEE80211R */
234	} else if (hapd->conf->wps_state) {
235#ifdef CONFIG_WPS
236		struct wpabuf *wps;
237		if (req_ies)
238			wps = ieee802_11_vendor_ie_concat(req_ies, req_ies_len,
239							  WPS_IE_VENDOR_TYPE);
240		else
241			wps = NULL;
242#ifdef CONFIG_WPS_STRICT
243		if (wps && wps_validate_assoc_req(wps) < 0) {
244			reason = WLAN_REASON_INVALID_IE;
245			status = WLAN_STATUS_INVALID_IE;
246			wpabuf_free(wps);
247			goto fail;
248		}
249#endif /* CONFIG_WPS_STRICT */
250		if (wps) {
251			sta->flags |= WLAN_STA_WPS;
252			if (wps_is_20(wps)) {
253				wpa_printf(MSG_DEBUG, "WPS: STA supports "
254					   "WPS 2.0");
255				sta->flags |= WLAN_STA_WPS2;
256			}
257		} else
258			sta->flags |= WLAN_STA_MAYBE_WPS;
259		wpabuf_free(wps);
260#endif /* CONFIG_WPS */
261	}
262#ifdef CONFIG_WPS
263skip_wpa_check:
264#endif /* CONFIG_WPS */
265
266#ifdef CONFIG_IEEE80211R
267	p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, buf, sizeof(buf),
268					sta->auth_alg, req_ies, req_ies_len);
269
270	hostapd_sta_assoc(hapd, addr, reassoc, status, buf, p - buf);
271#else /* CONFIG_IEEE80211R */
272	/* Keep compiler silent about unused variables */
273	if (status) {
274	}
275#endif /* CONFIG_IEEE80211R */
276
277	new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;
278	sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
279
280	if (reassoc && (sta->auth_alg == WLAN_AUTH_FT))
281		wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT);
282	else
283		wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
284
285	hostapd_new_assoc_sta(hapd, sta, !new_assoc);
286
287	ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
288
289#ifdef CONFIG_P2P
290	if (req_ies) {
291		p2p_group_notif_assoc(hapd->p2p_group, sta->addr,
292				      req_ies, req_ies_len);
293	}
294#endif /* CONFIG_P2P */
295
296	return 0;
297
298fail:
299#ifdef CONFIG_IEEE80211R
300	hostapd_sta_assoc(hapd, addr, reassoc, status, buf, p - buf);
301#endif /* CONFIG_IEEE80211R */
302	hostapd_drv_sta_disassoc(hapd, sta->addr, reason);
303	ap_free_sta(hapd, sta);
304	return -1;
305}
306
307
308void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr)
309{
310	struct sta_info *sta;
311
312	if (addr == NULL) {
313		/*
314		 * This could potentially happen with unexpected event from the
315		 * driver wrapper. This was seen at least in one case where the
316		 * driver ended up reporting a station mode event while hostapd
317		 * was running, so better make sure we stop processing such an
318		 * event here.
319		 */
320		wpa_printf(MSG_DEBUG, "hostapd_notif_disassoc: Skip event "
321			   "with no address");
322		return;
323	}
324
325	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
326		       HOSTAPD_LEVEL_INFO, "disassociated");
327
328	sta = ap_get_sta(hapd, addr);
329	if (sta == NULL) {
330		wpa_printf(MSG_DEBUG, "Disassociation notification for "
331			   "unknown STA " MACSTR, MAC2STR(addr));
332		return;
333	}
334
335	ap_sta_set_authorized(hapd, sta, 0);
336	sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
337	wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
338	sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
339	ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
340	ap_free_sta(hapd, sta);
341}
342
343
344void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr)
345{
346	struct sta_info *sta = ap_get_sta(hapd, addr);
347
348	if (!sta || !hapd->conf->disassoc_low_ack)
349		return;
350
351	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
352		       HOSTAPD_LEVEL_INFO, "disconnected due to excessive "
353		       "missing ACKs");
354	hostapd_drv_sta_disassoc(hapd, addr, WLAN_REASON_DISASSOC_LOW_ACK);
355	if (sta)
356		ap_sta_disassociate(hapd, sta, WLAN_REASON_DISASSOC_LOW_ACK);
357}
358
359
360void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
361			     int offset)
362{
363#ifdef NEED_AP_MLME
364	int channel;
365
366	hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
367		       HOSTAPD_LEVEL_INFO, "driver had channel switch: "
368		       "freq=%d, ht=%d, offset=%d", freq, ht, offset);
369
370	hapd->iface->freq = freq;
371
372	channel = hostapd_hw_get_channel(hapd, freq);
373	if (!channel) {
374		hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
375			       HOSTAPD_LEVEL_WARNING, "driver switched to "
376			       "bad channel!");
377		return;
378	}
379
380	hapd->iconf->channel = channel;
381	hapd->iconf->ieee80211n = ht;
382	hapd->iconf->secondary_channel = offset;
383#endif /* NEED_AP_MLME */
384}
385
386
387int hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, const u8 *da,
388			 const u8 *bssid, const u8 *ie, size_t ie_len,
389			 int ssi_signal)
390{
391	size_t i;
392	int ret = 0;
393
394	if (sa == NULL || ie == NULL)
395		return -1;
396
397	random_add_randomness(sa, ETH_ALEN);
398	for (i = 0; hapd->probereq_cb && i < hapd->num_probereq_cb; i++) {
399		if (hapd->probereq_cb[i].cb(hapd->probereq_cb[i].ctx,
400					    sa, da, bssid, ie, ie_len,
401					    ssi_signal) > 0) {
402			ret = 1;
403			break;
404		}
405	}
406	return ret;
407}
408
409
410#ifdef HOSTAPD
411
412#ifdef CONFIG_IEEE80211R
413static void hostapd_notify_auth_ft_finish(void *ctx, const u8 *dst,
414					  const u8 *bssid,
415					  u16 auth_transaction, u16 status,
416					  const u8 *ies, size_t ies_len)
417{
418	struct hostapd_data *hapd = ctx;
419	struct sta_info *sta;
420
421	sta = ap_get_sta(hapd, dst);
422	if (sta == NULL)
423		return;
424
425	hostapd_logger(hapd, dst, HOSTAPD_MODULE_IEEE80211,
426		       HOSTAPD_LEVEL_DEBUG, "authentication OK (FT)");
427	sta->flags |= WLAN_STA_AUTH;
428
429	hostapd_sta_auth(hapd, dst, auth_transaction, status, ies, ies_len);
430}
431#endif /* CONFIG_IEEE80211R */
432
433
434static void hostapd_notif_auth(struct hostapd_data *hapd,
435			       struct auth_info *rx_auth)
436{
437	struct sta_info *sta;
438	u16 status = WLAN_STATUS_SUCCESS;
439	u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
440	size_t resp_ies_len = 0;
441
442	sta = ap_get_sta(hapd, rx_auth->peer);
443	if (!sta) {
444		sta = ap_sta_add(hapd, rx_auth->peer);
445		if (sta == NULL) {
446			status = WLAN_STATUS_UNSPECIFIED_FAILURE;
447			goto fail;
448		}
449	}
450	sta->flags &= ~WLAN_STA_PREAUTH;
451	ieee802_1x_notify_pre_auth(sta->eapol_sm, 0);
452#ifdef CONFIG_IEEE80211R
453	if (rx_auth->auth_type == WLAN_AUTH_FT && hapd->wpa_auth) {
454		sta->auth_alg = WLAN_AUTH_FT;
455		if (sta->wpa_sm == NULL)
456			sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
457							sta->addr);
458		if (sta->wpa_sm == NULL) {
459			wpa_printf(MSG_DEBUG, "FT: Failed to initialize WPA "
460				   "state machine");
461			status = WLAN_STATUS_UNSPECIFIED_FAILURE;
462			goto fail;
463		}
464		wpa_ft_process_auth(sta->wpa_sm, rx_auth->bssid,
465				    rx_auth->auth_transaction, rx_auth->ies,
466				    rx_auth->ies_len,
467				    hostapd_notify_auth_ft_finish, hapd);
468		return;
469	}
470#endif /* CONFIG_IEEE80211R */
471fail:
472	hostapd_sta_auth(hapd, rx_auth->peer, rx_auth->auth_transaction + 1,
473			 status, resp_ies, resp_ies_len);
474}
475
476
477static void hostapd_action_rx(struct hostapd_data *hapd,
478			      struct rx_action *action)
479{
480	struct sta_info *sta;
481
482        wpa_printf(MSG_DEBUG, "RX_ACTION cat %d action plen %d",
483		   action->category, (int) action->len);
484
485	sta = ap_get_sta(hapd, action->sa);
486	if (sta == NULL) {
487		wpa_printf(MSG_DEBUG, "%s: station not found", __func__);
488		return;
489	}
490#ifdef CONFIG_IEEE80211R
491	if (action->category == WLAN_ACTION_FT) {
492		wpa_printf(MSG_DEBUG, "%s: FT_ACTION length %d",
493			   __func__, (int) action->len);
494		wpa_ft_action_rx(sta->wpa_sm, action->data, action->len);
495	}
496#endif /* CONFIG_IEEE80211R */
497#ifdef CONFIG_IEEE80211W
498	if (action->category == WLAN_ACTION_SA_QUERY && action->len >= 4) {
499		wpa_printf(MSG_DEBUG, "%s: SA_QUERY_ACTION length %d",
500			   __func__, (int) action->len);
501		ieee802_11_sa_query_action(hapd, action->sa,
502					   *(action->data + 1),
503					   action->data + 2);
504	}
505#endif /* CONFIG_IEEE80211W */
506#ifdef CONFIG_IEEE80211V
507	if (action->category == WLAN_ACTION_WNM) {
508		wpa_printf(MSG_DEBUG, "%s: WNM_ACTION length %d",
509			   __func__, (int) action->len);
510		ieee802_11_rx_wnm_action_ap(hapd, action);
511	}
512#endif /* CONFIG_IEEE80211V */
513}
514
515
516#ifdef NEED_AP_MLME
517
518#define HAPD_BROADCAST ((struct hostapd_data *) -1)
519
520static struct hostapd_data * get_hapd_bssid(struct hostapd_iface *iface,
521					    const u8 *bssid)
522{
523	size_t i;
524
525	if (bssid == NULL)
526		return NULL;
527	if (bssid[0] == 0xff && bssid[1] == 0xff && bssid[2] == 0xff &&
528	    bssid[3] == 0xff && bssid[4] == 0xff && bssid[5] == 0xff)
529		return HAPD_BROADCAST;
530
531	for (i = 0; i < iface->num_bss; i++) {
532		if (os_memcmp(bssid, iface->bss[i]->own_addr, ETH_ALEN) == 0)
533			return iface->bss[i];
534	}
535
536	return NULL;
537}
538
539
540static void hostapd_rx_from_unknown_sta(struct hostapd_data *hapd,
541					const u8 *bssid, const u8 *addr,
542					int wds)
543{
544	hapd = get_hapd_bssid(hapd->iface, bssid);
545	if (hapd == NULL || hapd == HAPD_BROADCAST)
546		return;
547
548	ieee802_11_rx_from_unknown(hapd, addr, wds);
549}
550
551
552static void hostapd_mgmt_rx(struct hostapd_data *hapd, struct rx_mgmt *rx_mgmt)
553{
554	struct hostapd_iface *iface = hapd->iface;
555	const struct ieee80211_hdr *hdr;
556	const u8 *bssid;
557	struct hostapd_frame_info fi;
558
559	hdr = (const struct ieee80211_hdr *) rx_mgmt->frame;
560	bssid = get_hdr_bssid(hdr, rx_mgmt->frame_len);
561	if (bssid == NULL)
562		return;
563
564	hapd = get_hapd_bssid(iface, bssid);
565	if (hapd == NULL) {
566		u16 fc;
567		fc = le_to_host16(hdr->frame_control);
568
569		/*
570		 * Drop frames to unknown BSSIDs except for Beacon frames which
571		 * could be used to update neighbor information.
572		 */
573		if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
574		    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
575			hapd = iface->bss[0];
576		else
577			return;
578	}
579
580	os_memset(&fi, 0, sizeof(fi));
581	fi.datarate = rx_mgmt->datarate;
582	fi.ssi_signal = rx_mgmt->ssi_signal;
583
584	if (hapd == HAPD_BROADCAST) {
585		size_t i;
586		for (i = 0; i < iface->num_bss; i++)
587			ieee802_11_mgmt(iface->bss[i], rx_mgmt->frame,
588					rx_mgmt->frame_len, &fi);
589	} else
590		ieee802_11_mgmt(hapd, rx_mgmt->frame, rx_mgmt->frame_len, &fi);
591
592	random_add_randomness(&fi, sizeof(fi));
593}
594
595
596static void hostapd_rx_action(struct hostapd_data *hapd,
597			      struct rx_action *rx_action)
598{
599	struct rx_mgmt rx_mgmt;
600	u8 *buf;
601	struct ieee80211_hdr *hdr;
602
603	wpa_printf(MSG_DEBUG, "EVENT_RX_ACTION DA=" MACSTR " SA=" MACSTR
604		   " BSSID=" MACSTR " category=%u",
605		   MAC2STR(rx_action->da), MAC2STR(rx_action->sa),
606		   MAC2STR(rx_action->bssid), rx_action->category);
607	wpa_hexdump(MSG_MSGDUMP, "Received action frame contents",
608		    rx_action->data, rx_action->len);
609
610	buf = os_zalloc(24 + 1 + rx_action->len);
611	if (buf == NULL)
612		return;
613	hdr = (struct ieee80211_hdr *) buf;
614	hdr->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
615					  WLAN_FC_STYPE_ACTION);
616	if (rx_action->category == WLAN_ACTION_SA_QUERY) {
617		/*
618		 * Assume frame was protected; it would have been dropped if
619		 * not.
620		 */
621		hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP);
622	}
623	os_memcpy(hdr->addr1, rx_action->da, ETH_ALEN);
624	os_memcpy(hdr->addr2, rx_action->sa, ETH_ALEN);
625	os_memcpy(hdr->addr3, rx_action->bssid, ETH_ALEN);
626	buf[24] = rx_action->category;
627	os_memcpy(buf + 24 + 1, rx_action->data, rx_action->len);
628	os_memset(&rx_mgmt, 0, sizeof(rx_mgmt));
629	rx_mgmt.frame = buf;
630	rx_mgmt.frame_len = 24 + 1 + rx_action->len;
631	hostapd_mgmt_rx(hapd, &rx_mgmt);
632	os_free(buf);
633}
634
635
636static void hostapd_mgmt_tx_cb(struct hostapd_data *hapd, const u8 *buf,
637			       size_t len, u16 stype, int ok)
638{
639	struct ieee80211_hdr *hdr;
640	hdr = (struct ieee80211_hdr *) buf;
641	hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len));
642	if (hapd == NULL || hapd == HAPD_BROADCAST)
643		return;
644	ieee802_11_mgmt_cb(hapd, buf, len, stype, ok);
645}
646
647#endif /* NEED_AP_MLME */
648
649
650static int hostapd_event_new_sta(struct hostapd_data *hapd, const u8 *addr)
651{
652	struct sta_info *sta = ap_get_sta(hapd, addr);
653	if (sta)
654		return 0;
655
656	wpa_printf(MSG_DEBUG, "Data frame from unknown STA " MACSTR
657		   " - adding a new STA", MAC2STR(addr));
658	sta = ap_sta_add(hapd, addr);
659	if (sta) {
660		hostapd_new_assoc_sta(hapd, sta, 0);
661	} else {
662		wpa_printf(MSG_DEBUG, "Failed to add STA entry for " MACSTR,
663			   MAC2STR(addr));
664		return -1;
665	}
666
667	return 0;
668}
669
670
671static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src,
672				   const u8 *data, size_t data_len)
673{
674	struct hostapd_iface *iface = hapd->iface;
675	size_t j;
676
677	for (j = 0; j < iface->num_bss; j++) {
678		if (ap_get_sta(iface->bss[j], src)) {
679			hapd = iface->bss[j];
680			break;
681		}
682	}
683
684	ieee802_1x_receive(hapd, src, data, data_len);
685}
686
687
688void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
689			  union wpa_event_data *data)
690{
691	struct hostapd_data *hapd = ctx;
692#ifndef CONFIG_NO_STDOUT_DEBUG
693	int level = MSG_DEBUG;
694
695	if (event == EVENT_RX_MGMT && data->rx_mgmt.frame &&
696	    data->rx_mgmt.frame_len >= 24) {
697		const struct ieee80211_hdr *hdr;
698		u16 fc;
699		hdr = (const struct ieee80211_hdr *) data->rx_mgmt.frame;
700		fc = le_to_host16(hdr->frame_control);
701		if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
702		    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
703			level = MSG_EXCESSIVE;
704	}
705
706	wpa_dbg(hapd->msg_ctx, level, "Event %s (%d) received",
707		event_to_string(event), event);
708#endif /* CONFIG_NO_STDOUT_DEBUG */
709
710	switch (event) {
711	case EVENT_MICHAEL_MIC_FAILURE:
712		michael_mic_failure(hapd, data->michael_mic_failure.src, 1);
713		break;
714	case EVENT_SCAN_RESULTS:
715		if (hapd->iface->scan_cb)
716			hapd->iface->scan_cb(hapd->iface);
717		break;
718#ifdef CONFIG_IEEE80211R
719	case EVENT_FT_RRB_RX:
720		wpa_ft_rrb_rx(hapd->wpa_auth, data->ft_rrb_rx.src,
721			      data->ft_rrb_rx.data, data->ft_rrb_rx.data_len);
722		break;
723#endif /* CONFIG_IEEE80211R */
724	case EVENT_WPS_BUTTON_PUSHED:
725		hostapd_wps_button_pushed(hapd, NULL);
726		break;
727#ifdef NEED_AP_MLME
728	case EVENT_TX_STATUS:
729		switch (data->tx_status.type) {
730		case WLAN_FC_TYPE_MGMT:
731			hostapd_mgmt_tx_cb(hapd, data->tx_status.data,
732					   data->tx_status.data_len,
733					   data->tx_status.stype,
734					   data->tx_status.ack);
735			break;
736		case WLAN_FC_TYPE_DATA:
737			hostapd_tx_status(hapd, data->tx_status.dst,
738					  data->tx_status.data,
739					  data->tx_status.data_len,
740					  data->tx_status.ack);
741			break;
742		}
743		break;
744	case EVENT_EAPOL_TX_STATUS:
745		hostapd_eapol_tx_status(hapd, data->eapol_tx_status.dst,
746					data->eapol_tx_status.data,
747					data->eapol_tx_status.data_len,
748					data->eapol_tx_status.ack);
749		break;
750	case EVENT_DRIVER_CLIENT_POLL_OK:
751		hostapd_client_poll_ok(hapd, data->client_poll.addr);
752		break;
753	case EVENT_RX_FROM_UNKNOWN:
754		hostapd_rx_from_unknown_sta(hapd, data->rx_from_unknown.bssid,
755					    data->rx_from_unknown.addr,
756					    data->rx_from_unknown.wds);
757		break;
758	case EVENT_RX_MGMT:
759		hostapd_mgmt_rx(hapd, &data->rx_mgmt);
760		break;
761#endif /* NEED_AP_MLME */
762	case EVENT_RX_PROBE_REQ:
763		if (data->rx_probe_req.sa == NULL ||
764		    data->rx_probe_req.ie == NULL)
765			break;
766		hostapd_probe_req_rx(hapd, data->rx_probe_req.sa,
767				     data->rx_probe_req.da,
768				     data->rx_probe_req.bssid,
769				     data->rx_probe_req.ie,
770				     data->rx_probe_req.ie_len,
771				     data->rx_probe_req.ssi_signal);
772		break;
773	case EVENT_NEW_STA:
774		hostapd_event_new_sta(hapd, data->new_sta.addr);
775		break;
776	case EVENT_EAPOL_RX:
777		hostapd_event_eapol_rx(hapd, data->eapol_rx.src,
778				       data->eapol_rx.data,
779				       data->eapol_rx.data_len);
780		break;
781	case EVENT_ASSOC:
782		hostapd_notif_assoc(hapd, data->assoc_info.addr,
783				    data->assoc_info.req_ies,
784				    data->assoc_info.req_ies_len,
785				    data->assoc_info.reassoc);
786		break;
787	case EVENT_DISASSOC:
788		if (data)
789			hostapd_notif_disassoc(hapd, data->disassoc_info.addr);
790		break;
791	case EVENT_DEAUTH:
792		if (data)
793			hostapd_notif_disassoc(hapd, data->deauth_info.addr);
794		break;
795	case EVENT_STATION_LOW_ACK:
796		if (!data)
797			break;
798		hostapd_event_sta_low_ack(hapd, data->low_ack.addr);
799		break;
800	case EVENT_RX_ACTION:
801		if (data->rx_action.da == NULL || data->rx_action.sa == NULL ||
802		    data->rx_action.bssid == NULL)
803			break;
804#ifdef NEED_AP_MLME
805		hostapd_rx_action(hapd, &data->rx_action);
806#endif /* NEED_AP_MLME */
807		hostapd_action_rx(hapd, &data->rx_action);
808		break;
809	case EVENT_AUTH:
810		hostapd_notif_auth(hapd, &data->auth);
811		break;
812	case EVENT_CH_SWITCH:
813		if (!data)
814			break;
815		hostapd_event_ch_switch(hapd, data->ch_switch.freq,
816					data->ch_switch.ht_enabled,
817					data->ch_switch.ch_offset);
818		break;
819	default:
820		wpa_printf(MSG_DEBUG, "Unknown event %d", event);
821		break;
822	}
823}
824
825#endif /* HOSTAPD */
826