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