2 * hostapd / Station table
3 * Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
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.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
20 #include "accounting.h"
21 #include "ieee802_1x.h"
22 #include "ieee802_11.h"
23 #include "radius/radius.h"
26 #include "radius/radius_client.h"
29 #include "hw_features.h"
31 #include "vlan_init.h"
33 static int ap_sta_in_other_bss(struct hostapd_data
*hapd
,
34 struct sta_info
*sta
, u32 flags
);
35 static void ap_handle_session_timer(void *eloop_ctx
, void *timeout_ctx
);
37 int ap_for_each_sta(struct hostapd_data
*hapd
,
38 int (*cb
)(struct hostapd_data
*hapd
, struct sta_info
*sta
,
44 for (sta
= hapd
->sta_list
; sta
; sta
= sta
->next
) {
45 if (cb(hapd
, sta
, ctx
))
53 struct sta_info
* ap_get_sta(struct hostapd_data
*hapd
, const u8
*sta
)
57 s
= hapd
->sta_hash
[STA_HASH(sta
)];
58 while (s
!= NULL
&& os_memcmp(s
->addr
, sta
, 6) != 0)
64 static void ap_sta_list_del(struct hostapd_data
*hapd
, struct sta_info
*sta
)
68 if (hapd
->sta_list
== sta
) {
69 hapd
->sta_list
= sta
->next
;
74 while (tmp
!= NULL
&& tmp
->next
!= sta
)
77 wpa_printf(MSG_DEBUG
, "Could not remove STA " MACSTR
" from "
78 "list.", MAC2STR(sta
->addr
));
80 tmp
->next
= sta
->next
;
84 void ap_sta_hash_add(struct hostapd_data
*hapd
, struct sta_info
*sta
)
86 sta
->hnext
= hapd
->sta_hash
[STA_HASH(sta
->addr
)];
87 hapd
->sta_hash
[STA_HASH(sta
->addr
)] = sta
;
91 static void ap_sta_hash_del(struct hostapd_data
*hapd
, struct sta_info
*sta
)
95 s
= hapd
->sta_hash
[STA_HASH(sta
->addr
)];
96 if (s
== NULL
) return;
97 if (os_memcmp(s
->addr
, sta
->addr
, 6) == 0) {
98 hapd
->sta_hash
[STA_HASH(sta
->addr
)] = s
->hnext
;
102 while (s
->hnext
!= NULL
&&
103 os_memcmp(s
->hnext
->addr
, sta
->addr
, ETH_ALEN
) != 0)
105 if (s
->hnext
!= NULL
)
106 s
->hnext
= s
->hnext
->hnext
;
108 wpa_printf(MSG_DEBUG
, "AP: could not remove STA " MACSTR
109 " from hash table", MAC2STR(sta
->addr
));
113 void ap_free_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
)
117 accounting_sta_stop(hapd
, sta
);
119 if (!ap_sta_in_other_bss(hapd
, sta
, WLAN_STA_ASSOC
) &&
120 !(sta
->flags
& WLAN_STA_PREAUTH
))
121 hostapd_sta_remove(hapd
, sta
->addr
);
123 ap_sta_hash_del(hapd
, sta
);
124 ap_sta_list_del(hapd
, sta
);
127 hapd
->sta_aid
[sta
->aid
- 1] = NULL
;
130 if (sta
->nonerp_set
) {
132 hapd
->iface
->num_sta_non_erp
--;
133 if (hapd
->iface
->num_sta_non_erp
== 0)
137 if (sta
->no_short_slot_time_set
) {
138 sta
->no_short_slot_time_set
= 0;
139 hapd
->iface
->num_sta_no_short_slot_time
--;
140 if (hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
141 && hapd
->iface
->num_sta_no_short_slot_time
== 0)
145 if (sta
->no_short_preamble_set
) {
146 sta
->no_short_preamble_set
= 0;
147 hapd
->iface
->num_sta_no_short_preamble
--;
148 if (hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
149 && hapd
->iface
->num_sta_no_short_preamble
== 0)
154 ieee802_11_set_beacons(hapd
->iface
);
156 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
157 eloop_cancel_timeout(ap_handle_session_timer
, hapd
, sta
);
159 ieee802_1x_free_station(sta
);
160 wpa_auth_sta_deinit(sta
->wpa_sm
);
161 rsn_preauth_free_station(hapd
, sta
);
162 radius_client_flush_auth(hapd
->radius
, sta
->addr
);
164 os_free(sta
->last_assoc_req
);
165 os_free(sta
->challenge
);
170 void hostapd_free_stas(struct hostapd_data
*hapd
)
172 struct sta_info
*sta
, *prev
;
174 sta
= hapd
->sta_list
;
178 if (sta
->flags
& WLAN_STA_AUTH
) {
179 mlme_deauthenticate_indication(
180 hapd
, sta
, WLAN_REASON_UNSPECIFIED
);
183 wpa_printf(MSG_DEBUG
, "Removing station " MACSTR
,
184 MAC2STR(prev
->addr
));
185 ap_free_sta(hapd
, prev
);
190 void ap_handle_timer(void *eloop_ctx
, void *timeout_ctx
)
192 struct hostapd_data
*hapd
= eloop_ctx
;
193 struct sta_info
*sta
= timeout_ctx
;
194 unsigned long next_time
= 0;
196 if (sta
->timeout_next
== STA_REMOVE
) {
197 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
198 HOSTAPD_LEVEL_INFO
, "deauthenticated due to "
199 "local deauth request");
200 ap_free_sta(hapd
, sta
);
204 if ((sta
->flags
& WLAN_STA_ASSOC
) &&
205 (sta
->timeout_next
== STA_NULLFUNC
||
206 sta
->timeout_next
== STA_DISASSOC
)) {
208 wpa_printf(MSG_DEBUG
, "Checking STA " MACSTR
" inactivity:",
210 inactive_sec
= hostapd_get_inact_sec(hapd
, sta
->addr
);
211 if (inactive_sec
== -1) {
212 wpa_printf(MSG_DEBUG
, "Could not get station info "
213 "from kernel driver for " MACSTR
".",
215 } else if (inactive_sec
< hapd
->conf
->ap_max_inactivity
&&
216 sta
->flags
& WLAN_STA_ASSOC
) {
217 /* station activity detected; reset timeout state */
218 wpa_printf(MSG_DEBUG
, " Station has been active");
219 sta
->timeout_next
= STA_NULLFUNC
;
220 next_time
= hapd
->conf
->ap_max_inactivity
-
225 if ((sta
->flags
& WLAN_STA_ASSOC
) &&
226 sta
->timeout_next
== STA_DISASSOC
&&
227 !(sta
->flags
& WLAN_STA_PENDING_POLL
)) {
228 wpa_printf(MSG_DEBUG
, " Station has ACKed data poll");
229 /* data nullfunc frame poll did not produce TX errors; assume
230 * station ACKed it */
231 sta
->timeout_next
= STA_NULLFUNC
;
232 next_time
= hapd
->conf
->ap_max_inactivity
;
236 eloop_register_timeout(next_time
, 0, ap_handle_timer
, hapd
,
241 if (sta
->timeout_next
== STA_NULLFUNC
&&
242 (sta
->flags
& WLAN_STA_ASSOC
)) {
243 /* send data frame to poll STA and check whether this frame
245 struct ieee80211_hdr hdr
;
247 wpa_printf(MSG_DEBUG
, " Polling STA with data frame");
248 sta
->flags
|= WLAN_STA_PENDING_POLL
;
250 #ifndef CONFIG_NATIVE_WINDOWS
251 /* FIX: WLAN_FC_STYPE_NULLFUNC would be more appropriate, but
252 * it is apparently not retried so TX Exc events are not
254 os_memset(&hdr
, 0, sizeof(hdr
));
256 IEEE80211_FC(WLAN_FC_TYPE_DATA
, WLAN_FC_STYPE_DATA
);
257 hdr
.frame_control
|= host_to_le16(BIT(1));
258 hdr
.frame_control
|= host_to_le16(WLAN_FC_FROMDS
);
259 os_memcpy(hdr
.IEEE80211_DA_FROMDS
, sta
->addr
, ETH_ALEN
);
260 os_memcpy(hdr
.IEEE80211_BSSID_FROMDS
, hapd
->own_addr
,
262 os_memcpy(hdr
.IEEE80211_SA_FROMDS
, hapd
->own_addr
, ETH_ALEN
);
264 if (hostapd_send_mgmt_frame(hapd
, &hdr
, sizeof(hdr
), 0) < 0)
265 perror("ap_handle_timer: send");
266 #endif /* CONFIG_NATIVE_WINDOWS */
267 } else if (sta
->timeout_next
!= STA_REMOVE
) {
268 int deauth
= sta
->timeout_next
== STA_DEAUTH
;
270 wpa_printf(MSG_DEBUG
, "Sending %s info to STA " MACSTR
,
271 deauth
? "deauthentication" : "disassociation",
275 hostapd_sta_deauth(hapd
, sta
->addr
,
276 WLAN_REASON_PREV_AUTH_NOT_VALID
);
278 hostapd_sta_disassoc(
280 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY
);
284 switch (sta
->timeout_next
) {
286 sta
->timeout_next
= STA_DISASSOC
;
287 eloop_register_timeout(AP_DISASSOC_DELAY
, 0, ap_handle_timer
,
291 sta
->flags
&= ~WLAN_STA_ASSOC
;
292 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
293 if (!sta
->acct_terminate_cause
)
294 sta
->acct_terminate_cause
=
295 RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT
;
296 accounting_sta_stop(hapd
, sta
);
297 ieee802_1x_free_station(sta
);
298 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
299 HOSTAPD_LEVEL_INFO
, "disassociated due to "
301 sta
->timeout_next
= STA_DEAUTH
;
302 eloop_register_timeout(AP_DEAUTH_DELAY
, 0, ap_handle_timer
,
304 mlme_disassociate_indication(
305 hapd
, sta
, WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY
);
309 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
310 HOSTAPD_LEVEL_INFO
, "deauthenticated due to "
312 if (!sta
->acct_terminate_cause
)
313 sta
->acct_terminate_cause
=
314 RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT
;
315 mlme_deauthenticate_indication(
317 WLAN_REASON_PREV_AUTH_NOT_VALID
);
318 ap_free_sta(hapd
, sta
);
324 static void ap_handle_session_timer(void *eloop_ctx
, void *timeout_ctx
)
326 struct hostapd_data
*hapd
= eloop_ctx
;
327 struct sta_info
*sta
= timeout_ctx
;
330 if (!(sta
->flags
& WLAN_STA_AUTH
))
333 mlme_deauthenticate_indication(hapd
, sta
,
334 WLAN_REASON_PREV_AUTH_NOT_VALID
);
335 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
336 HOSTAPD_LEVEL_INFO
, "deauthenticated due to "
338 sta
->acct_terminate_cause
=
339 RADIUS_ACCT_TERMINATE_CAUSE_SESSION_TIMEOUT
;
340 os_memcpy(addr
, sta
->addr
, ETH_ALEN
);
341 ap_free_sta(hapd
, sta
);
342 hostapd_sta_deauth(hapd
, addr
, WLAN_REASON_PREV_AUTH_NOT_VALID
);
346 void ap_sta_session_timeout(struct hostapd_data
*hapd
, struct sta_info
*sta
,
349 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
350 HOSTAPD_LEVEL_DEBUG
, "setting session timeout to %d "
351 "seconds", session_timeout
);
352 eloop_cancel_timeout(ap_handle_session_timer
, hapd
, sta
);
353 eloop_register_timeout(session_timeout
, 0, ap_handle_session_timer
,
358 void ap_sta_no_session_timeout(struct hostapd_data
*hapd
, struct sta_info
*sta
)
360 eloop_cancel_timeout(ap_handle_session_timer
, hapd
, sta
);
364 struct sta_info
* ap_sta_add(struct hostapd_data
*hapd
, const u8
*addr
)
366 struct sta_info
*sta
;
368 sta
= ap_get_sta(hapd
, addr
);
372 wpa_printf(MSG_DEBUG
, " New STA");
373 if (hapd
->num_sta
>= hapd
->conf
->max_num_sta
) {
374 /* FIX: might try to remove some old STAs first? */
375 wpa_printf(MSG_DEBUG
, "no more room for new STAs (%d/%d)",
376 hapd
->num_sta
, hapd
->conf
->max_num_sta
);
380 sta
= os_zalloc(sizeof(struct sta_info
));
382 wpa_printf(MSG_ERROR
, "malloc failed");
385 sta
->acct_interim_interval
= hapd
->conf
->radius
->acct_interim_interval
;
387 /* initialize STA info data */
388 eloop_register_timeout(hapd
->conf
->ap_max_inactivity
, 0,
389 ap_handle_timer
, hapd
, sta
);
390 os_memcpy(sta
->addr
, addr
, ETH_ALEN
);
391 sta
->next
= hapd
->sta_list
;
392 hapd
->sta_list
= sta
;
394 ap_sta_hash_add(hapd
, sta
);
395 sta
->ssid
= &hapd
->conf
->ssid
;
401 static int ap_sta_remove(struct hostapd_data
*hapd
, struct sta_info
*sta
)
403 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
405 wpa_printf(MSG_DEBUG
, "Removing STA " MACSTR
" from kernel driver",
407 if (hostapd_sta_remove(hapd
, sta
->addr
) &&
408 sta
->flags
& WLAN_STA_ASSOC
) {
409 wpa_printf(MSG_DEBUG
, "Could not remove station " MACSTR
410 " from kernel driver.", MAC2STR(sta
->addr
));
417 static int ap_sta_in_other_bss(struct hostapd_data
*hapd
,
418 struct sta_info
*sta
, u32 flags
)
420 struct hostapd_iface
*iface
= hapd
->iface
;
423 for (i
= 0; i
< iface
->num_bss
; i
++) {
424 struct hostapd_data
*bss
= iface
->bss
[i
];
425 struct sta_info
*sta2
;
426 /* bss should always be set during operation, but it may be
427 * NULL during reconfiguration. Assume the STA is not
428 * associated to another BSS in that case to avoid NULL pointer
430 if (bss
== hapd
|| bss
== NULL
)
432 sta2
= ap_get_sta(bss
, sta
->addr
);
433 if (sta2
&& ((sta2
->flags
& flags
) == flags
))
441 void ap_sta_disassociate(struct hostapd_data
*hapd
, struct sta_info
*sta
,
444 wpa_printf(MSG_DEBUG
, "%s: disassociate STA " MACSTR
,
445 hapd
->conf
->iface
, MAC2STR(sta
->addr
));
446 sta
->flags
&= ~WLAN_STA_ASSOC
;
447 if (!ap_sta_in_other_bss(hapd
, sta
, WLAN_STA_ASSOC
))
448 ap_sta_remove(hapd
, sta
);
449 sta
->timeout_next
= STA_DEAUTH
;
450 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
451 eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DISASSOC
, 0,
452 ap_handle_timer
, hapd
, sta
);
453 accounting_sta_stop(hapd
, sta
);
454 ieee802_1x_free_station(sta
);
456 mlme_disassociate_indication(hapd
, sta
, reason
);
460 void ap_sta_deauthenticate(struct hostapd_data
*hapd
, struct sta_info
*sta
,
463 wpa_printf(MSG_DEBUG
, "%s: deauthenticate STA " MACSTR
,
464 hapd
->conf
->iface
, MAC2STR(sta
->addr
));
465 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
);
466 if (!ap_sta_in_other_bss(hapd
, sta
, WLAN_STA_ASSOC
))
467 ap_sta_remove(hapd
, sta
);
468 sta
->timeout_next
= STA_REMOVE
;
469 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
470 eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DEAUTH
, 0,
471 ap_handle_timer
, hapd
, sta
);
472 accounting_sta_stop(hapd
, sta
);
473 ieee802_1x_free_station(sta
);
475 mlme_deauthenticate_indication(hapd
, sta
, reason
);
479 int ap_sta_bind_vlan(struct hostapd_data
*hapd
, struct sta_info
*sta
,
483 struct hostapd_vlan
*vlan
= NULL
;
486 * Do not proceed furthur if the vlan id remains same. We do not want
487 * duplicate dynamic vlan entries.
489 if (sta
->vlan_id
== old_vlanid
)
493 * During 1x reauth, if the vlan id changes, then remove the old id and
494 * proceed furthur to add the new one.
497 vlan_remove_dynamic(hapd
, old_vlanid
);
499 iface
= hapd
->conf
->iface
;
500 if (sta
->ssid
->vlan
[0])
501 iface
= sta
->ssid
->vlan
;
503 if (sta
->ssid
->dynamic_vlan
== DYNAMIC_VLAN_DISABLED
)
505 else if (sta
->vlan_id
> 0) {
506 vlan
= hapd
->conf
->vlan
;
508 if (vlan
->vlan_id
== sta
->vlan_id
||
509 vlan
->vlan_id
== VLAN_ID_WILDCARD
) {
510 iface
= vlan
->ifname
;
517 if (sta
->vlan_id
> 0 && vlan
== NULL
) {
518 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
519 HOSTAPD_LEVEL_DEBUG
, "could not find VLAN for "
520 "binding station to (vlan_id=%d)",
523 } else if (sta
->vlan_id
> 0 && vlan
->vlan_id
== VLAN_ID_WILDCARD
) {
524 vlan
= vlan_add_dynamic(hapd
, vlan
, sta
->vlan_id
);
526 hostapd_logger(hapd
, sta
->addr
,
527 HOSTAPD_MODULE_IEEE80211
,
528 HOSTAPD_LEVEL_DEBUG
, "could not add "
529 "dynamic VLAN interface for vlan_id=%d",
534 iface
= vlan
->ifname
;
535 if (vlan_setup_encryption_dyn(hapd
, sta
->ssid
, iface
) != 0) {
536 hostapd_logger(hapd
, sta
->addr
,
537 HOSTAPD_MODULE_IEEE80211
,
538 HOSTAPD_LEVEL_DEBUG
, "could not "
539 "configure encryption for dynamic VLAN "
540 "interface for vlan_id=%d",
544 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
545 HOSTAPD_LEVEL_DEBUG
, "added new dynamic VLAN "
546 "interface '%s'", iface
);
547 } else if (vlan
&& vlan
->vlan_id
== sta
->vlan_id
) {
548 if (sta
->vlan_id
> 0) {
549 vlan
->dynamic_vlan
++;
550 hostapd_logger(hapd
, sta
->addr
,
551 HOSTAPD_MODULE_IEEE80211
,
552 HOSTAPD_LEVEL_DEBUG
, "updated existing "
553 "dynamic VLAN interface '%s'", iface
);
557 * Update encryption configuration for statically generated
558 * VLAN interface. This is only used for static WEP
559 * configuration for the case where hostapd did not yet know
560 * which keys are to be used when the interface was added.
562 if (vlan_setup_encryption_dyn(hapd
, sta
->ssid
, iface
) != 0) {
563 hostapd_logger(hapd
, sta
->addr
,
564 HOSTAPD_MODULE_IEEE80211
,
565 HOSTAPD_LEVEL_DEBUG
, "could not "
566 "configure encryption for VLAN "
567 "interface for vlan_id=%d",
572 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
573 HOSTAPD_LEVEL_DEBUG
, "binding station to interface "
576 if (wpa_auth_sta_set_vlan(sta
->wpa_sm
, sta
->vlan_id
) < 0)
577 wpa_printf(MSG_INFO
, "Failed to update VLAN-ID for WPA");
579 return hostapd_set_sta_vlan(iface
, hapd
, sta
->addr
, sta
->vlan_id
);