5517294f07045f76204bf722465924f3d54a22fb
[mech_eap.git] / src / ap / drv_callbacks.c
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
33 int 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
263 skip_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
298 fail:
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
308 void 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
344 void 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
360 void 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
387 int 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
413 static 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
434 static 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 */
471 fail:
472         hostapd_sta_auth(hapd, rx_auth->peer, rx_auth->auth_transaction + 1,
473                          status, resp_ies, resp_ies_len);
474 }
475
476
477 static 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
520 static 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
540 static 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
552 static 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
596 static 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
636 static 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
650 static 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
671 static 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         struct sta_info *sta;
676         size_t j;
677
678         for (j = 0; j < iface->num_bss; j++) {
679                 if ((sta = ap_get_sta(iface->bss[j], src))) {
680                         if (sta->flags & WLAN_STA_ASSOC) {
681                                 hapd = iface->bss[j];
682                                 break;
683                         }
684                 }
685         }
686
687         ieee802_1x_receive(hapd, src, data, data_len);
688 }
689
690
691 void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
692                           union wpa_event_data *data)
693 {
694         struct hostapd_data *hapd = ctx;
695 #ifndef CONFIG_NO_STDOUT_DEBUG
696         int level = MSG_DEBUG;
697
698         if (event == EVENT_RX_MGMT && data->rx_mgmt.frame &&
699             data->rx_mgmt.frame_len >= 24) {
700                 const struct ieee80211_hdr *hdr;
701                 u16 fc;
702                 hdr = (const struct ieee80211_hdr *) data->rx_mgmt.frame;
703                 fc = le_to_host16(hdr->frame_control);
704                 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
705                     WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
706                         level = MSG_EXCESSIVE;
707         }
708
709         wpa_dbg(hapd->msg_ctx, level, "Event %s (%d) received",
710                 event_to_string(event), event);
711 #endif /* CONFIG_NO_STDOUT_DEBUG */
712
713         switch (event) {
714         case EVENT_MICHAEL_MIC_FAILURE:
715                 michael_mic_failure(hapd, data->michael_mic_failure.src, 1);
716                 break;
717         case EVENT_SCAN_RESULTS:
718                 if (hapd->iface->scan_cb)
719                         hapd->iface->scan_cb(hapd->iface);
720                 break;
721 #ifdef CONFIG_IEEE80211R
722         case EVENT_FT_RRB_RX:
723                 wpa_ft_rrb_rx(hapd->wpa_auth, data->ft_rrb_rx.src,
724                               data->ft_rrb_rx.data, data->ft_rrb_rx.data_len);
725                 break;
726 #endif /* CONFIG_IEEE80211R */
727         case EVENT_WPS_BUTTON_PUSHED:
728                 hostapd_wps_button_pushed(hapd, NULL);
729                 break;
730 #ifdef NEED_AP_MLME
731         case EVENT_TX_STATUS:
732                 switch (data->tx_status.type) {
733                 case WLAN_FC_TYPE_MGMT:
734                         hostapd_mgmt_tx_cb(hapd, data->tx_status.data,
735                                            data->tx_status.data_len,
736                                            data->tx_status.stype,
737                                            data->tx_status.ack);
738                         break;
739                 case WLAN_FC_TYPE_DATA:
740                         hostapd_tx_status(hapd, data->tx_status.dst,
741                                           data->tx_status.data,
742                                           data->tx_status.data_len,
743                                           data->tx_status.ack);
744                         break;
745                 }
746                 break;
747         case EVENT_EAPOL_TX_STATUS:
748                 hostapd_eapol_tx_status(hapd, data->eapol_tx_status.dst,
749                                         data->eapol_tx_status.data,
750                                         data->eapol_tx_status.data_len,
751                                         data->eapol_tx_status.ack);
752                 break;
753         case EVENT_DRIVER_CLIENT_POLL_OK:
754                 hostapd_client_poll_ok(hapd, data->client_poll.addr);
755                 break;
756         case EVENT_RX_FROM_UNKNOWN:
757                 hostapd_rx_from_unknown_sta(hapd, data->rx_from_unknown.bssid,
758                                             data->rx_from_unknown.addr,
759                                             data->rx_from_unknown.wds);
760                 break;
761         case EVENT_RX_MGMT:
762                 hostapd_mgmt_rx(hapd, &data->rx_mgmt);
763                 break;
764 #endif /* NEED_AP_MLME */
765         case EVENT_RX_PROBE_REQ:
766                 if (data->rx_probe_req.sa == NULL ||
767                     data->rx_probe_req.ie == NULL)
768                         break;
769                 hostapd_probe_req_rx(hapd, data->rx_probe_req.sa,
770                                      data->rx_probe_req.da,
771                                      data->rx_probe_req.bssid,
772                                      data->rx_probe_req.ie,
773                                      data->rx_probe_req.ie_len,
774                                      data->rx_probe_req.ssi_signal);
775                 break;
776         case EVENT_NEW_STA:
777                 hostapd_event_new_sta(hapd, data->new_sta.addr);
778                 break;
779         case EVENT_EAPOL_RX:
780                 hostapd_event_eapol_rx(hapd, data->eapol_rx.src,
781                                        data->eapol_rx.data,
782                                        data->eapol_rx.data_len);
783                 break;
784         case EVENT_ASSOC:
785                 hostapd_notif_assoc(hapd, data->assoc_info.addr,
786                                     data->assoc_info.req_ies,
787                                     data->assoc_info.req_ies_len,
788                                     data->assoc_info.reassoc);
789                 break;
790         case EVENT_DISASSOC:
791                 if (data)
792                         hostapd_notif_disassoc(hapd, data->disassoc_info.addr);
793                 break;
794         case EVENT_DEAUTH:
795                 if (data)
796                         hostapd_notif_disassoc(hapd, data->deauth_info.addr);
797                 break;
798         case EVENT_STATION_LOW_ACK:
799                 if (!data)
800                         break;
801                 hostapd_event_sta_low_ack(hapd, data->low_ack.addr);
802                 break;
803         case EVENT_RX_ACTION:
804                 if (data->rx_action.da == NULL || data->rx_action.sa == NULL ||
805                     data->rx_action.bssid == NULL)
806                         break;
807 #ifdef NEED_AP_MLME
808                 hostapd_rx_action(hapd, &data->rx_action);
809 #endif /* NEED_AP_MLME */
810                 hostapd_action_rx(hapd, &data->rx_action);
811                 break;
812         case EVENT_AUTH:
813                 hostapd_notif_auth(hapd, &data->auth);
814                 break;
815         case EVENT_CH_SWITCH:
816                 if (!data)
817                         break;
818                 hostapd_event_ch_switch(hapd, data->ch_switch.freq,
819                                         data->ch_switch.ht_enabled,
820                                         data->ch_switch.ch_offset);
821                 break;
822         default:
823                 wpa_printf(MSG_DEBUG, "Unknown event %d", event);
824                 break;
825         }
826 }
827
828 #endif /* HOSTAPD */