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