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