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