8cd6c3f1f7c19ffb1c9a03fa148a7dd4d5586d72
[mech_eap.git] / src / ap / sta_info.c
1 /*
2  * hostapd / Station table
3  * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14
15 #include "utils/includes.h"
16
17 #include "utils/common.h"
18 #include "utils/eloop.h"
19 #include "common/ieee802_11_defs.h"
20 #include "radius/radius.h"
21 #include "radius/radius_client.h"
22 #include "drivers/driver.h"
23 #include "p2p/p2p.h"
24 #include "hostapd.h"
25 #include "accounting.h"
26 #include "ieee802_1x.h"
27 #include "ieee802_11.h"
28 #include "wpa_auth.h"
29 #include "preauth_auth.h"
30 #include "ap_config.h"
31 #include "beacon.h"
32 #include "ap_mlme.h"
33 #include "vlan_init.h"
34 #include "sta_info.h"
35
36 static void ap_sta_remove_in_other_bss(struct hostapd_data *hapd,
37                                        struct sta_info *sta);
38 static void ap_handle_session_timer(void *eloop_ctx, void *timeout_ctx);
39 #ifdef CONFIG_IEEE80211W
40 static void ap_sa_query_timer(void *eloop_ctx, void *timeout_ctx);
41 #endif /* CONFIG_IEEE80211W */
42
43 int ap_for_each_sta(struct hostapd_data *hapd,
44                     int (*cb)(struct hostapd_data *hapd, struct sta_info *sta,
45                               void *ctx),
46                     void *ctx)
47 {
48         struct sta_info *sta;
49
50         for (sta = hapd->sta_list; sta; sta = sta->next) {
51                 if (cb(hapd, sta, ctx))
52                         return 1;
53         }
54
55         return 0;
56 }
57
58
59 struct sta_info * ap_get_sta(struct hostapd_data *hapd, const u8 *sta)
60 {
61         struct sta_info *s;
62
63         s = hapd->sta_hash[STA_HASH(sta)];
64         while (s != NULL && os_memcmp(s->addr, sta, 6) != 0)
65                 s = s->hnext;
66         return s;
67 }
68
69
70 static void ap_sta_list_del(struct hostapd_data *hapd, struct sta_info *sta)
71 {
72         struct sta_info *tmp;
73
74         if (hapd->sta_list == sta) {
75                 hapd->sta_list = sta->next;
76                 return;
77         }
78
79         tmp = hapd->sta_list;
80         while (tmp != NULL && tmp->next != sta)
81                 tmp = tmp->next;
82         if (tmp == NULL) {
83                 wpa_printf(MSG_DEBUG, "Could not remove STA " MACSTR " from "
84                            "list.", MAC2STR(sta->addr));
85         } else
86                 tmp->next = sta->next;
87 }
88
89
90 void ap_sta_hash_add(struct hostapd_data *hapd, struct sta_info *sta)
91 {
92         sta->hnext = hapd->sta_hash[STA_HASH(sta->addr)];
93         hapd->sta_hash[STA_HASH(sta->addr)] = sta;
94 }
95
96
97 static void ap_sta_hash_del(struct hostapd_data *hapd, struct sta_info *sta)
98 {
99         struct sta_info *s;
100
101         s = hapd->sta_hash[STA_HASH(sta->addr)];
102         if (s == NULL) return;
103         if (os_memcmp(s->addr, sta->addr, 6) == 0) {
104                 hapd->sta_hash[STA_HASH(sta->addr)] = s->hnext;
105                 return;
106         }
107
108         while (s->hnext != NULL &&
109                os_memcmp(s->hnext->addr, sta->addr, ETH_ALEN) != 0)
110                 s = s->hnext;
111         if (s->hnext != NULL)
112                 s->hnext = s->hnext->hnext;
113         else
114                 wpa_printf(MSG_DEBUG, "AP: could not remove STA " MACSTR
115                            " from hash table", MAC2STR(sta->addr));
116 }
117
118
119 void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
120 {
121         int set_beacon = 0;
122
123         accounting_sta_stop(hapd, sta);
124
125         if (sta->flags & WLAN_STA_WDS)
126                 hapd->drv.set_wds_sta(hapd, sta->addr, sta->aid, 0);
127
128         if (!(sta->flags & WLAN_STA_PREAUTH))
129                 hapd->drv.sta_remove(hapd, sta->addr);
130
131         ap_sta_hash_del(hapd, sta);
132         ap_sta_list_del(hapd, sta);
133
134         if (sta->aid > 0)
135                 hapd->sta_aid[(sta->aid - 1) / 32] &=
136                         ~BIT((sta->aid - 1) % 32);
137
138         hapd->num_sta--;
139         if (sta->nonerp_set) {
140                 sta->nonerp_set = 0;
141                 hapd->iface->num_sta_non_erp--;
142                 if (hapd->iface->num_sta_non_erp == 0)
143                         set_beacon++;
144         }
145
146         if (sta->no_short_slot_time_set) {
147                 sta->no_short_slot_time_set = 0;
148                 hapd->iface->num_sta_no_short_slot_time--;
149                 if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
150                     && hapd->iface->num_sta_no_short_slot_time == 0)
151                         set_beacon++;
152         }
153
154         if (sta->no_short_preamble_set) {
155                 sta->no_short_preamble_set = 0;
156                 hapd->iface->num_sta_no_short_preamble--;
157                 if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
158                     && hapd->iface->num_sta_no_short_preamble == 0)
159                         set_beacon++;
160         }
161
162         if (sta->no_ht_gf_set) {
163                 sta->no_ht_gf_set = 0;
164                 hapd->iface->num_sta_ht_no_gf--;
165         }
166
167         if (sta->no_ht_set) {
168                 sta->no_ht_set = 0;
169                 hapd->iface->num_sta_no_ht--;
170         }
171
172         if (sta->ht_20mhz_set) {
173                 sta->ht_20mhz_set = 0;
174                 hapd->iface->num_sta_ht_20mhz--;
175         }
176
177 #if defined(NEED_AP_MLME) && defined(CONFIG_IEEE80211N)
178         if (hostapd_ht_operation_update(hapd->iface) > 0)
179                 set_beacon++;
180 #endif /* NEED_AP_MLME && CONFIG_IEEE80211N */
181
182         if (set_beacon)
183                 ieee802_11_set_beacons(hapd->iface);
184
185         eloop_cancel_timeout(ap_handle_timer, hapd, sta);
186         eloop_cancel_timeout(ap_handle_session_timer, hapd, sta);
187
188         ieee802_1x_free_station(sta);
189         wpa_auth_sta_deinit(sta->wpa_sm);
190         rsn_preauth_free_station(hapd, sta);
191 #ifndef CONFIG_NO_RADIUS
192         radius_client_flush_auth(hapd->radius, sta->addr);
193 #endif /* CONFIG_NO_RADIUS */
194
195         os_free(sta->last_assoc_req);
196         os_free(sta->challenge);
197
198 #ifdef CONFIG_IEEE80211W
199         os_free(sta->sa_query_trans_id);
200         eloop_cancel_timeout(ap_sa_query_timer, hapd, sta);
201 #endif /* CONFIG_IEEE80211W */
202
203 #ifdef CONFIG_P2P
204         p2p_group_notif_disassoc(hapd->p2p_group, sta->addr);
205 #endif /* CONFIG_P2P */
206
207         wpabuf_free(sta->wps_ie);
208         wpabuf_free(sta->p2p_ie);
209
210         os_free(sta->ht_capabilities);
211
212         os_free(sta);
213 }
214
215
216 void hostapd_free_stas(struct hostapd_data *hapd)
217 {
218         struct sta_info *sta, *prev;
219
220         sta = hapd->sta_list;
221
222         while (sta) {
223                 prev = sta;
224                 if (sta->flags & WLAN_STA_AUTH) {
225                         mlme_deauthenticate_indication(
226                                 hapd, sta, WLAN_REASON_UNSPECIFIED);
227                 }
228                 sta = sta->next;
229                 wpa_printf(MSG_DEBUG, "Removing station " MACSTR,
230                            MAC2STR(prev->addr));
231                 ap_free_sta(hapd, prev);
232         }
233 }
234
235
236 /**
237  * ap_handle_timer - Per STA timer handler
238  * @eloop_ctx: struct hostapd_data *
239  * @timeout_ctx: struct sta_info *
240  *
241  * This function is called to check station activity and to remove inactive
242  * stations.
243  */
244 void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
245 {
246         struct hostapd_data *hapd = eloop_ctx;
247         struct sta_info *sta = timeout_ctx;
248         unsigned long next_time = 0;
249
250         if (sta->timeout_next == STA_REMOVE) {
251                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
252                                HOSTAPD_LEVEL_INFO, "deauthenticated due to "
253                                "local deauth request");
254                 ap_free_sta(hapd, sta);
255                 return;
256         }
257
258         if ((sta->flags & WLAN_STA_ASSOC) &&
259             (sta->timeout_next == STA_NULLFUNC ||
260              sta->timeout_next == STA_DISASSOC)) {
261                 int inactive_sec;
262                 wpa_printf(MSG_DEBUG, "Checking STA " MACSTR " inactivity:",
263                            MAC2STR(sta->addr));
264                 inactive_sec = hapd->drv.get_inact_sec(hapd, sta->addr);
265                 if (inactive_sec == -1) {
266                         wpa_printf(MSG_DEBUG, "Could not get station info "
267                                    "from kernel driver for " MACSTR ".",
268                                    MAC2STR(sta->addr));
269                 } else if (inactive_sec < hapd->conf->ap_max_inactivity &&
270                            sta->flags & WLAN_STA_ASSOC) {
271                         /* station activity detected; reset timeout state */
272                         wpa_printf(MSG_DEBUG, "  Station has been active");
273                         sta->timeout_next = STA_NULLFUNC;
274                         next_time = hapd->conf->ap_max_inactivity -
275                                 inactive_sec;
276                 }
277         }
278
279         if ((sta->flags & WLAN_STA_ASSOC) &&
280             sta->timeout_next == STA_DISASSOC &&
281             !(sta->flags & WLAN_STA_PENDING_POLL)) {
282                 wpa_printf(MSG_DEBUG, "  Station has ACKed data poll");
283                 /* data nullfunc frame poll did not produce TX errors; assume
284                  * station ACKed it */
285                 sta->timeout_next = STA_NULLFUNC;
286                 next_time = hapd->conf->ap_max_inactivity;
287         }
288
289         if (next_time) {
290                 eloop_register_timeout(next_time, 0, ap_handle_timer, hapd,
291                                        sta);
292                 return;
293         }
294
295         if (sta->timeout_next == STA_NULLFUNC &&
296             (sta->flags & WLAN_STA_ASSOC)) {
297 #ifndef CONFIG_NATIVE_WINDOWS
298                 /* send data frame to poll STA and check whether this frame
299                  * is ACKed */
300                 struct ieee80211_hdr hdr;
301
302                 wpa_printf(MSG_DEBUG, "  Polling STA with data frame");
303                 sta->flags |= WLAN_STA_PENDING_POLL;
304
305                 os_memset(&hdr, 0, sizeof(hdr));
306                 if (hapd->driver &&
307                     os_strcmp(hapd->driver->name, "hostap") == 0) {
308                         /*
309                          * WLAN_FC_STYPE_NULLFUNC would be more appropriate,
310                          * but it is apparently not retried so TX Exc events
311                          * are not received for it.
312                          */
313                         hdr.frame_control =
314                                 IEEE80211_FC(WLAN_FC_TYPE_DATA,
315                                              WLAN_FC_STYPE_DATA);
316                 } else {
317                         hdr.frame_control =
318                                 IEEE80211_FC(WLAN_FC_TYPE_DATA,
319                                              WLAN_FC_STYPE_NULLFUNC);
320                 }
321
322                 hdr.frame_control |= host_to_le16(WLAN_FC_FROMDS);
323                 os_memcpy(hdr.IEEE80211_DA_FROMDS, sta->addr, ETH_ALEN);
324                 os_memcpy(hdr.IEEE80211_BSSID_FROMDS, hapd->own_addr,
325                           ETH_ALEN);
326                 os_memcpy(hdr.IEEE80211_SA_FROMDS, hapd->own_addr, ETH_ALEN);
327
328                 if (hapd->drv.send_mgmt_frame(hapd, &hdr, sizeof(hdr)) < 0)
329                         perror("ap_handle_timer: send");
330 #endif /* CONFIG_NATIVE_WINDOWS */
331         } else if (sta->timeout_next != STA_REMOVE) {
332                 int deauth = sta->timeout_next == STA_DEAUTH;
333
334                 wpa_printf(MSG_DEBUG, "Sending %s info to STA " MACSTR,
335                            deauth ? "deauthentication" : "disassociation",
336                            MAC2STR(sta->addr));
337
338                 if (deauth) {
339                         hapd->drv.sta_deauth(hapd, sta->addr,
340                                              WLAN_REASON_PREV_AUTH_NOT_VALID);
341                 } else {
342                         hapd->drv.sta_disassoc(
343                                 hapd, sta->addr,
344                                 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
345                 }
346         }
347
348         switch (sta->timeout_next) {
349         case STA_NULLFUNC:
350                 sta->timeout_next = STA_DISASSOC;
351                 eloop_register_timeout(AP_DISASSOC_DELAY, 0, ap_handle_timer,
352                                        hapd, sta);
353                 break;
354         case STA_DISASSOC:
355                 sta->flags &= ~WLAN_STA_ASSOC;
356                 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
357                 if (!sta->acct_terminate_cause)
358                         sta->acct_terminate_cause =
359                                 RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT;
360                 accounting_sta_stop(hapd, sta);
361                 ieee802_1x_free_station(sta);
362                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
363                                HOSTAPD_LEVEL_INFO, "disassociated due to "
364                                "inactivity");
365                 sta->timeout_next = STA_DEAUTH;
366                 eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer,
367                                        hapd, sta);
368                 mlme_disassociate_indication(
369                         hapd, sta, WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
370                 break;
371         case STA_DEAUTH:
372         case STA_REMOVE:
373                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
374                                HOSTAPD_LEVEL_INFO, "deauthenticated due to "
375                                "inactivity");
376                 if (!sta->acct_terminate_cause)
377                         sta->acct_terminate_cause =
378                                 RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT;
379                 mlme_deauthenticate_indication(
380                         hapd, sta,
381                         WLAN_REASON_PREV_AUTH_NOT_VALID);
382                 ap_free_sta(hapd, sta);
383                 break;
384         }
385 }
386
387
388 static void ap_handle_session_timer(void *eloop_ctx, void *timeout_ctx)
389 {
390         struct hostapd_data *hapd = eloop_ctx;
391         struct sta_info *sta = timeout_ctx;
392         u8 addr[ETH_ALEN];
393
394         if (!(sta->flags & WLAN_STA_AUTH))
395                 return;
396
397         mlme_deauthenticate_indication(hapd, sta,
398                                        WLAN_REASON_PREV_AUTH_NOT_VALID);
399         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
400                        HOSTAPD_LEVEL_INFO, "deauthenticated due to "
401                        "session timeout");
402         sta->acct_terminate_cause =
403                 RADIUS_ACCT_TERMINATE_CAUSE_SESSION_TIMEOUT;
404         os_memcpy(addr, sta->addr, ETH_ALEN);
405         ap_free_sta(hapd, sta);
406         hapd->drv.sta_deauth(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
407 }
408
409
410 void ap_sta_session_timeout(struct hostapd_data *hapd, struct sta_info *sta,
411                             u32 session_timeout)
412 {
413         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
414                        HOSTAPD_LEVEL_DEBUG, "setting session timeout to %d "
415                        "seconds", session_timeout);
416         eloop_cancel_timeout(ap_handle_session_timer, hapd, sta);
417         eloop_register_timeout(session_timeout, 0, ap_handle_session_timer,
418                                hapd, sta);
419 }
420
421
422 void ap_sta_no_session_timeout(struct hostapd_data *hapd, struct sta_info *sta)
423 {
424         eloop_cancel_timeout(ap_handle_session_timer, hapd, sta);
425 }
426
427
428 struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr)
429 {
430         struct sta_info *sta;
431
432         sta = ap_get_sta(hapd, addr);
433         if (sta)
434                 return sta;
435
436         wpa_printf(MSG_DEBUG, "  New STA");
437         if (hapd->num_sta >= hapd->conf->max_num_sta) {
438                 /* FIX: might try to remove some old STAs first? */
439                 wpa_printf(MSG_DEBUG, "no more room for new STAs (%d/%d)",
440                            hapd->num_sta, hapd->conf->max_num_sta);
441                 return NULL;
442         }
443
444         sta = os_zalloc(sizeof(struct sta_info));
445         if (sta == NULL) {
446                 wpa_printf(MSG_ERROR, "malloc failed");
447                 return NULL;
448         }
449         sta->acct_interim_interval = hapd->conf->acct_interim_interval;
450
451         /* initialize STA info data */
452         eloop_register_timeout(hapd->conf->ap_max_inactivity, 0,
453                                ap_handle_timer, hapd, sta);
454         os_memcpy(sta->addr, addr, ETH_ALEN);
455         sta->next = hapd->sta_list;
456         hapd->sta_list = sta;
457         hapd->num_sta++;
458         ap_sta_hash_add(hapd, sta);
459         sta->ssid = &hapd->conf->ssid;
460         ap_sta_remove_in_other_bss(hapd, sta);
461
462         return sta;
463 }
464
465
466 static int ap_sta_remove(struct hostapd_data *hapd, struct sta_info *sta)
467 {
468         ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
469
470         wpa_printf(MSG_DEBUG, "Removing STA " MACSTR " from kernel driver",
471                    MAC2STR(sta->addr));
472         if (hapd->drv.sta_remove(hapd, sta->addr) &&
473             sta->flags & WLAN_STA_ASSOC) {
474                 wpa_printf(MSG_DEBUG, "Could not remove station " MACSTR
475                            " from kernel driver.", MAC2STR(sta->addr));
476                 return -1;
477         }
478         return 0;
479 }
480
481
482 static void ap_sta_remove_in_other_bss(struct hostapd_data *hapd,
483                                        struct sta_info *sta)
484 {
485         struct hostapd_iface *iface = hapd->iface;
486         size_t i;
487
488         for (i = 0; i < iface->num_bss; i++) {
489                 struct hostapd_data *bss = iface->bss[i];
490                 struct sta_info *sta2;
491                 /* bss should always be set during operation, but it may be
492                  * NULL during reconfiguration. Assume the STA is not
493                  * associated to another BSS in that case to avoid NULL pointer
494                  * dereferences. */
495                 if (bss == hapd || bss == NULL)
496                         continue;
497                 sta2 = ap_get_sta(bss, sta->addr);
498                 if (!sta2)
499                         continue;
500
501                 ap_sta_disconnect(bss, sta2, sta2->addr,
502                                   WLAN_REASON_PREV_AUTH_NOT_VALID);
503         }
504 }
505
506
507 void ap_sta_disassociate(struct hostapd_data *hapd, struct sta_info *sta,
508                          u16 reason)
509 {
510         wpa_printf(MSG_DEBUG, "%s: disassociate STA " MACSTR,
511                    hapd->conf->iface, MAC2STR(sta->addr));
512         sta->flags &= ~WLAN_STA_ASSOC;
513         ap_sta_remove(hapd, sta);
514         sta->timeout_next = STA_DEAUTH;
515         eloop_cancel_timeout(ap_handle_timer, hapd, sta);
516         eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DISASSOC, 0,
517                                ap_handle_timer, hapd, sta);
518         accounting_sta_stop(hapd, sta);
519         ieee802_1x_free_station(sta);
520
521         mlme_disassociate_indication(hapd, sta, reason);
522 }
523
524
525 void ap_sta_deauthenticate(struct hostapd_data *hapd, struct sta_info *sta,
526                            u16 reason)
527 {
528         wpa_printf(MSG_DEBUG, "%s: deauthenticate STA " MACSTR,
529                    hapd->conf->iface, MAC2STR(sta->addr));
530         sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
531         ap_sta_remove(hapd, sta);
532         sta->timeout_next = STA_REMOVE;
533         eloop_cancel_timeout(ap_handle_timer, hapd, sta);
534         eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DEAUTH, 0,
535                                ap_handle_timer, hapd, sta);
536         accounting_sta_stop(hapd, sta);
537         ieee802_1x_free_station(sta);
538
539         mlme_deauthenticate_indication(hapd, sta, reason);
540 }
541
542
543 int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta,
544                      int old_vlanid)
545 {
546 #ifndef CONFIG_NO_VLAN
547         const char *iface;
548         struct hostapd_vlan *vlan = NULL;
549         int ret;
550
551         /*
552          * Do not proceed furthur if the vlan id remains same. We do not want
553          * duplicate dynamic vlan entries.
554          */
555         if (sta->vlan_id == old_vlanid)
556                 return 0;
557
558         /*
559          * During 1x reauth, if the vlan id changes, then remove the old id and
560          * proceed furthur to add the new one.
561          */
562         if (old_vlanid > 0)
563                 vlan_remove_dynamic(hapd, old_vlanid);
564
565         iface = hapd->conf->iface;
566         if (sta->ssid->vlan[0])
567                 iface = sta->ssid->vlan;
568
569         if (sta->ssid->dynamic_vlan == DYNAMIC_VLAN_DISABLED)
570                 sta->vlan_id = 0;
571         else if (sta->vlan_id > 0) {
572                 vlan = hapd->conf->vlan;
573                 while (vlan) {
574                         if (vlan->vlan_id == sta->vlan_id ||
575                             vlan->vlan_id == VLAN_ID_WILDCARD) {
576                                 iface = vlan->ifname;
577                                 break;
578                         }
579                         vlan = vlan->next;
580                 }
581         }
582
583         if (sta->vlan_id > 0 && vlan == NULL) {
584                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
585                                HOSTAPD_LEVEL_DEBUG, "could not find VLAN for "
586                                "binding station to (vlan_id=%d)",
587                                sta->vlan_id);
588                 return -1;
589         } else if (sta->vlan_id > 0 && vlan->vlan_id == VLAN_ID_WILDCARD) {
590                 vlan = vlan_add_dynamic(hapd, vlan, sta->vlan_id);
591                 if (vlan == NULL) {
592                         hostapd_logger(hapd, sta->addr,
593                                        HOSTAPD_MODULE_IEEE80211,
594                                        HOSTAPD_LEVEL_DEBUG, "could not add "
595                                        "dynamic VLAN interface for vlan_id=%d",
596                                        sta->vlan_id);
597                         return -1;
598                 }
599
600                 iface = vlan->ifname;
601                 if (vlan_setup_encryption_dyn(hapd, sta->ssid, iface) != 0) {
602                         hostapd_logger(hapd, sta->addr,
603                                        HOSTAPD_MODULE_IEEE80211,
604                                        HOSTAPD_LEVEL_DEBUG, "could not "
605                                        "configure encryption for dynamic VLAN "
606                                        "interface for vlan_id=%d",
607                                        sta->vlan_id);
608                 }
609
610                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
611                                HOSTAPD_LEVEL_DEBUG, "added new dynamic VLAN "
612                                "interface '%s'", iface);
613         } else if (vlan && vlan->vlan_id == sta->vlan_id) {
614                 if (sta->vlan_id > 0) {
615                         vlan->dynamic_vlan++;
616                         hostapd_logger(hapd, sta->addr,
617                                        HOSTAPD_MODULE_IEEE80211,
618                                        HOSTAPD_LEVEL_DEBUG, "updated existing "
619                                        "dynamic VLAN interface '%s'", iface);
620                 }
621
622                 /*
623                  * Update encryption configuration for statically generated
624                  * VLAN interface. This is only used for static WEP
625                  * configuration for the case where hostapd did not yet know
626                  * which keys are to be used when the interface was added.
627                  */
628                 if (vlan_setup_encryption_dyn(hapd, sta->ssid, iface) != 0) {
629                         hostapd_logger(hapd, sta->addr,
630                                        HOSTAPD_MODULE_IEEE80211,
631                                        HOSTAPD_LEVEL_DEBUG, "could not "
632                                        "configure encryption for VLAN "
633                                        "interface for vlan_id=%d",
634                                        sta->vlan_id);
635                 }
636         }
637
638         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
639                        HOSTAPD_LEVEL_DEBUG, "binding station to interface "
640                        "'%s'", iface);
641
642         if (wpa_auth_sta_set_vlan(sta->wpa_sm, sta->vlan_id) < 0)
643                 wpa_printf(MSG_INFO, "Failed to update VLAN-ID for WPA");
644
645         ret = hapd->drv.set_sta_vlan(iface, hapd, sta->addr, sta->vlan_id);
646         if (ret < 0) {
647                 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
648                                HOSTAPD_LEVEL_DEBUG, "could not bind the STA "
649                                "entry to vlan_id=%d", sta->vlan_id);
650         }
651         return ret;
652 #else /* CONFIG_NO_VLAN */
653         return 0;
654 #endif /* CONFIG_NO_VLAN */
655 }
656
657
658 #ifdef CONFIG_IEEE80211W
659
660 int ap_check_sa_query_timeout(struct hostapd_data *hapd, struct sta_info *sta)
661 {
662         u32 tu;
663         struct os_time now, passed;
664         os_get_time(&now);
665         os_time_sub(&now, &sta->sa_query_start, &passed);
666         tu = (passed.sec * 1000000 + passed.usec) / 1024;
667         if (hapd->conf->assoc_sa_query_max_timeout < tu) {
668                 hostapd_logger(hapd, sta->addr,
669                                HOSTAPD_MODULE_IEEE80211,
670                                HOSTAPD_LEVEL_DEBUG,
671                                "association SA Query timed out");
672                 sta->sa_query_timed_out = 1;
673                 os_free(sta->sa_query_trans_id);
674                 sta->sa_query_trans_id = NULL;
675                 sta->sa_query_count = 0;
676                 eloop_cancel_timeout(ap_sa_query_timer, hapd, sta);
677                 return 1;
678         }
679
680         return 0;
681 }
682
683
684 static void ap_sa_query_timer(void *eloop_ctx, void *timeout_ctx)
685 {
686         struct hostapd_data *hapd = eloop_ctx;
687         struct sta_info *sta = timeout_ctx;
688         unsigned int timeout, sec, usec;
689         u8 *trans_id, *nbuf;
690
691         if (sta->sa_query_count > 0 &&
692             ap_check_sa_query_timeout(hapd, sta))
693                 return;
694
695         nbuf = os_realloc(sta->sa_query_trans_id,
696                           (sta->sa_query_count + 1) * WLAN_SA_QUERY_TR_ID_LEN);
697         if (nbuf == NULL)
698                 return;
699         if (sta->sa_query_count == 0) {
700                 /* Starting a new SA Query procedure */
701                 os_get_time(&sta->sa_query_start);
702         }
703         trans_id = nbuf + sta->sa_query_count * WLAN_SA_QUERY_TR_ID_LEN;
704         sta->sa_query_trans_id = nbuf;
705         sta->sa_query_count++;
706
707         os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN);
708
709         timeout = hapd->conf->assoc_sa_query_retry_timeout;
710         sec = ((timeout / 1000) * 1024) / 1000;
711         usec = (timeout % 1000) * 1024;
712         eloop_register_timeout(sec, usec, ap_sa_query_timer, hapd, sta);
713
714         hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
715                        HOSTAPD_LEVEL_DEBUG,
716                        "association SA Query attempt %d", sta->sa_query_count);
717
718 #ifdef NEED_AP_MLME
719         ieee802_11_send_sa_query_req(hapd, sta->addr, trans_id);
720 #endif /* NEED_AP_MLME */
721 }
722
723
724 void ap_sta_start_sa_query(struct hostapd_data *hapd, struct sta_info *sta)
725 {
726         ap_sa_query_timer(hapd, sta);
727 }
728
729
730 void ap_sta_stop_sa_query(struct hostapd_data *hapd, struct sta_info *sta)
731 {
732         eloop_cancel_timeout(ap_sa_query_timer, hapd, sta);
733         os_free(sta->sa_query_trans_id);
734         sta->sa_query_trans_id = NULL;
735         sta->sa_query_count = 0;
736 }
737
738 #endif /* CONFIG_IEEE80211W */
739
740
741 void ap_sta_disconnect(struct hostapd_data *hapd, struct sta_info *sta,
742                        const u8 *addr, u16 reason)
743 {
744
745         if (sta == NULL && addr)
746                 sta = ap_get_sta(hapd, addr);
747
748         if (addr)
749                 hapd->drv.sta_deauth(hapd, addr, reason);
750
751         if (sta == NULL)
752                 return;
753         sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_AUTHORIZED);
754         eloop_cancel_timeout(ap_handle_timer, hapd, sta);
755         eloop_register_timeout(0, 0, ap_handle_timer, hapd, sta);
756         sta->timeout_next = STA_REMOVE;
757 }