Line data Source code
1 : /*
2 : * hostapd / Station table
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 "utils/eloop.h"
13 : #include "common/ieee802_11_defs.h"
14 : #include "common/wpa_ctrl.h"
15 : #include "common/sae.h"
16 : #include "radius/radius.h"
17 : #include "radius/radius_client.h"
18 : #include "p2p/p2p.h"
19 : #include "fst/fst.h"
20 : #include "hostapd.h"
21 : #include "accounting.h"
22 : #include "ieee802_1x.h"
23 : #include "ieee802_11.h"
24 : #include "ieee802_11_auth.h"
25 : #include "wpa_auth.h"
26 : #include "preauth_auth.h"
27 : #include "ap_config.h"
28 : #include "beacon.h"
29 : #include "ap_mlme.h"
30 : #include "vlan_init.h"
31 : #include "p2p_hostapd.h"
32 : #include "ap_drv_ops.h"
33 : #include "gas_serv.h"
34 : #include "wnm_ap.h"
35 : #include "ndisc_snoop.h"
36 : #include "sta_info.h"
37 :
38 : static void ap_sta_remove_in_other_bss(struct hostapd_data *hapd,
39 : struct sta_info *sta);
40 : static void ap_handle_session_timer(void *eloop_ctx, void *timeout_ctx);
41 : static void ap_handle_session_warning_timer(void *eloop_ctx, void *timeout_ctx);
42 : static void ap_sta_deauth_cb_timeout(void *eloop_ctx, void *timeout_ctx);
43 : static void ap_sta_disassoc_cb_timeout(void *eloop_ctx, void *timeout_ctx);
44 : #ifdef CONFIG_IEEE80211W
45 : static void ap_sa_query_timer(void *eloop_ctx, void *timeout_ctx);
46 : #endif /* CONFIG_IEEE80211W */
47 : static int ap_sta_remove(struct hostapd_data *hapd, struct sta_info *sta);
48 :
49 3894 : int ap_for_each_sta(struct hostapd_data *hapd,
50 : int (*cb)(struct hostapd_data *hapd, struct sta_info *sta,
51 : void *ctx),
52 : void *ctx)
53 : {
54 : struct sta_info *sta;
55 :
56 3972 : for (sta = hapd->sta_list; sta; sta = sta->next) {
57 3831 : if (cb(hapd, sta, ctx))
58 3753 : return 1;
59 : }
60 :
61 141 : return 0;
62 : }
63 :
64 :
65 426818 : struct sta_info * ap_get_sta(struct hostapd_data *hapd, const u8 *sta)
66 : {
67 : struct sta_info *s;
68 :
69 426818 : s = hapd->sta_hash[STA_HASH(sta)];
70 860508 : while (s != NULL && os_memcmp(s->addr, sta, 6) != 0)
71 6872 : s = s->hnext;
72 426818 : return s;
73 : }
74 :
75 :
76 : #ifdef CONFIG_P2P
77 5 : struct sta_info * ap_get_sta_p2p(struct hostapd_data *hapd, const u8 *addr)
78 : {
79 : struct sta_info *sta;
80 :
81 7 : for (sta = hapd->sta_list; sta; sta = sta->next) {
82 : const u8 *p2p_dev_addr;
83 :
84 7 : if (sta->p2p_ie == NULL)
85 0 : continue;
86 :
87 7 : p2p_dev_addr = p2p_get_go_dev_addr(sta->p2p_ie);
88 7 : if (p2p_dev_addr == NULL)
89 0 : continue;
90 :
91 7 : if (os_memcmp(p2p_dev_addr, addr, ETH_ALEN) == 0)
92 5 : return sta;
93 : }
94 :
95 0 : return NULL;
96 : }
97 : #endif /* CONFIG_P2P */
98 :
99 :
100 3010 : static void ap_sta_list_del(struct hostapd_data *hapd, struct sta_info *sta)
101 : {
102 : struct sta_info *tmp;
103 :
104 3010 : if (hapd->sta_list == sta) {
105 2849 : hapd->sta_list = sta->next;
106 5859 : return;
107 : }
108 :
109 161 : tmp = hapd->sta_list;
110 388 : while (tmp != NULL && tmp->next != sta)
111 66 : tmp = tmp->next;
112 161 : if (tmp == NULL) {
113 0 : wpa_printf(MSG_DEBUG, "Could not remove STA " MACSTR " from "
114 0 : "list.", MAC2STR(sta->addr));
115 : } else
116 161 : tmp->next = sta->next;
117 : }
118 :
119 :
120 3010 : void ap_sta_hash_add(struct hostapd_data *hapd, struct sta_info *sta)
121 : {
122 3010 : sta->hnext = hapd->sta_hash[STA_HASH(sta->addr)];
123 3010 : hapd->sta_hash[STA_HASH(sta->addr)] = sta;
124 3010 : }
125 :
126 :
127 3010 : static void ap_sta_hash_del(struct hostapd_data *hapd, struct sta_info *sta)
128 : {
129 : struct sta_info *s;
130 :
131 3010 : s = hapd->sta_hash[STA_HASH(sta->addr)];
132 3010 : if (s == NULL) return;
133 3010 : if (os_memcmp(s->addr, sta->addr, 6) == 0) {
134 2849 : hapd->sta_hash[STA_HASH(sta->addr)] = s->hnext;
135 2849 : return;
136 : }
137 :
138 615 : while (s->hnext != NULL &&
139 227 : os_memcmp(s->hnext->addr, sta->addr, ETH_ALEN) != 0)
140 66 : s = s->hnext;
141 161 : if (s->hnext != NULL)
142 161 : s->hnext = s->hnext->hnext;
143 : else
144 0 : wpa_printf(MSG_DEBUG, "AP: could not remove STA " MACSTR
145 0 : " from hash table", MAC2STR(sta->addr));
146 : }
147 :
148 :
149 3259 : void ap_sta_ip6addr_del(struct hostapd_data *hapd, struct sta_info *sta)
150 : {
151 3259 : sta_ip6addr_del(hapd, sta);
152 3259 : }
153 :
154 :
155 3010 : void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
156 : {
157 3010 : int set_beacon = 0;
158 :
159 3010 : accounting_sta_stop(hapd, sta);
160 :
161 : /* just in case */
162 3010 : ap_sta_set_authorized(hapd, sta, 0);
163 :
164 3010 : if (sta->flags & WLAN_STA_WDS)
165 1 : hostapd_set_wds_sta(hapd, NULL, sta->addr, sta->aid, 0);
166 :
167 3010 : if (sta->ipaddr)
168 4 : hostapd_drv_br_delete_ip_neigh(hapd, 4, (u8 *) &sta->ipaddr);
169 3010 : ap_sta_ip6addr_del(hapd, sta);
170 :
171 5675 : if (!hapd->iface->driver_ap_teardown &&
172 2665 : !(sta->flags & WLAN_STA_PREAUTH))
173 2661 : hostapd_drv_sta_remove(hapd, sta->addr);
174 :
175 : #ifndef CONFIG_NO_VLAN
176 2543 : if (sta->vlan_id_bound) {
177 : /*
178 : * Need to remove the STA entry before potentially removing the
179 : * VLAN.
180 : */
181 18 : if (hapd->iface->driver_ap_teardown &&
182 1 : !(sta->flags & WLAN_STA_PREAUTH))
183 1 : hostapd_drv_sta_remove(hapd, sta->addr);
184 17 : vlan_remove_dynamic(hapd, sta->vlan_id_bound);
185 : }
186 : #endif /* CONFIG_NO_VLAN */
187 :
188 3010 : ap_sta_hash_del(hapd, sta);
189 3010 : ap_sta_list_del(hapd, sta);
190 :
191 3010 : if (sta->aid > 0)
192 5882 : hapd->sta_aid[(sta->aid - 1) / 32] &=
193 2941 : ~BIT((sta->aid - 1) % 32);
194 :
195 3010 : hapd->num_sta--;
196 3010 : if (sta->nonerp_set) {
197 0 : sta->nonerp_set = 0;
198 0 : hapd->iface->num_sta_non_erp--;
199 0 : if (hapd->iface->num_sta_non_erp == 0)
200 0 : set_beacon++;
201 : }
202 :
203 3010 : if (sta->no_short_slot_time_set) {
204 179 : sta->no_short_slot_time_set = 0;
205 179 : hapd->iface->num_sta_no_short_slot_time--;
206 179 : if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
207 0 : && hapd->iface->num_sta_no_short_slot_time == 0)
208 0 : set_beacon++;
209 : }
210 :
211 3010 : if (sta->no_short_preamble_set) {
212 179 : sta->no_short_preamble_set = 0;
213 179 : hapd->iface->num_sta_no_short_preamble--;
214 179 : if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
215 0 : && hapd->iface->num_sta_no_short_preamble == 0)
216 0 : set_beacon++;
217 : }
218 :
219 3010 : if (sta->no_ht_gf_set) {
220 0 : sta->no_ht_gf_set = 0;
221 0 : hapd->iface->num_sta_ht_no_gf--;
222 : }
223 :
224 3010 : if (sta->no_ht_set) {
225 90 : sta->no_ht_set = 0;
226 90 : hapd->iface->num_sta_no_ht--;
227 : }
228 :
229 3010 : if (sta->ht_20mhz_set) {
230 2850 : sta->ht_20mhz_set = 0;
231 2850 : hapd->iface->num_sta_ht_20mhz--;
232 : }
233 :
234 : #ifdef CONFIG_IEEE80211N
235 3010 : ht40_intolerant_remove(hapd->iface, sta);
236 : #endif /* CONFIG_IEEE80211N */
237 :
238 : #ifdef CONFIG_P2P
239 467 : if (sta->no_p2p_set) {
240 40 : sta->no_p2p_set = 0;
241 40 : hapd->num_sta_no_p2p--;
242 40 : if (hapd->num_sta_no_p2p == 0)
243 36 : hostapd_p2p_non_p2p_sta_disconnected(hapd);
244 : }
245 : #endif /* CONFIG_P2P */
246 :
247 : #if defined(NEED_AP_MLME) && defined(CONFIG_IEEE80211N)
248 3010 : if (hostapd_ht_operation_update(hapd->iface) > 0)
249 67 : set_beacon++;
250 : #endif /* NEED_AP_MLME && CONFIG_IEEE80211N */
251 :
252 : #ifdef CONFIG_MESH
253 467 : if (hapd->mesh_sta_free_cb)
254 42 : hapd->mesh_sta_free_cb(sta);
255 : #endif /* CONFIG_MESH */
256 :
257 3010 : if (set_beacon)
258 67 : ieee802_11_set_beacons(hapd->iface);
259 :
260 18060 : wpa_printf(MSG_DEBUG, "%s: cancel ap_handle_timer for " MACSTR,
261 18060 : __func__, MAC2STR(sta->addr));
262 3010 : eloop_cancel_timeout(ap_handle_timer, hapd, sta);
263 3010 : eloop_cancel_timeout(ap_handle_session_timer, hapd, sta);
264 3010 : eloop_cancel_timeout(ap_handle_session_warning_timer, hapd, sta);
265 3010 : eloop_cancel_timeout(ap_sta_deauth_cb_timeout, hapd, sta);
266 3010 : eloop_cancel_timeout(ap_sta_disassoc_cb_timeout, hapd, sta);
267 3010 : sae_clear_retransmit_timer(hapd, sta);
268 :
269 3010 : ieee802_1x_free_station(sta);
270 3010 : wpa_auth_sta_deinit(sta->wpa_sm);
271 3010 : rsn_preauth_free_station(hapd, sta);
272 : #ifndef CONFIG_NO_RADIUS
273 2543 : if (hapd->radius)
274 2543 : radius_client_flush_auth(hapd->radius, sta->addr);
275 : #endif /* CONFIG_NO_RADIUS */
276 :
277 3010 : os_free(sta->challenge);
278 :
279 : #ifdef CONFIG_IEEE80211W
280 3010 : os_free(sta->sa_query_trans_id);
281 3010 : eloop_cancel_timeout(ap_sa_query_timer, hapd, sta);
282 : #endif /* CONFIG_IEEE80211W */
283 :
284 : #ifdef CONFIG_P2P
285 467 : p2p_group_notif_disassoc(hapd->p2p_group, sta->addr);
286 : #endif /* CONFIG_P2P */
287 :
288 : #ifdef CONFIG_INTERWORKING
289 3010 : if (sta->gas_dialog) {
290 : int i;
291 18 : for (i = 0; i < GAS_DIALOG_MAX; i++)
292 16 : gas_serv_dialog_clear(&sta->gas_dialog[i]);
293 2 : os_free(sta->gas_dialog);
294 : }
295 : #endif /* CONFIG_INTERWORKING */
296 :
297 3010 : wpabuf_free(sta->wps_ie);
298 3010 : wpabuf_free(sta->p2p_ie);
299 3010 : wpabuf_free(sta->hs20_ie);
300 : #ifdef CONFIG_FST
301 3010 : wpabuf_free(sta->mb_ies);
302 : #endif /* CONFIG_FST */
303 :
304 3010 : os_free(sta->ht_capabilities);
305 3010 : os_free(sta->vht_capabilities);
306 3010 : hostapd_free_psk_list(sta->psk);
307 3010 : os_free(sta->identity);
308 3010 : os_free(sta->radius_cui);
309 3010 : os_free(sta->remediation_url);
310 3010 : wpabuf_free(sta->hs20_deauth_req);
311 3010 : os_free(sta->hs20_session_info_url);
312 :
313 : #ifdef CONFIG_SAE
314 3010 : sae_clear_data(sta->sae);
315 3010 : os_free(sta->sae);
316 : #endif /* CONFIG_SAE */
317 :
318 3010 : os_free(sta);
319 3010 : }
320 :
321 :
322 6081 : void hostapd_free_stas(struct hostapd_data *hapd)
323 : {
324 : struct sta_info *sta, *prev;
325 :
326 6081 : sta = hapd->sta_list;
327 :
328 12558 : while (sta) {
329 396 : prev = sta;
330 396 : if (sta->flags & WLAN_STA_AUTH) {
331 233 : mlme_deauthenticate_indication(
332 : hapd, sta, WLAN_REASON_UNSPECIFIED);
333 : }
334 396 : sta = sta->next;
335 2376 : wpa_printf(MSG_DEBUG, "Removing station " MACSTR,
336 2376 : MAC2STR(prev->addr));
337 396 : ap_free_sta(hapd, prev);
338 : }
339 6081 : }
340 :
341 :
342 : /**
343 : * ap_handle_timer - Per STA timer handler
344 : * @eloop_ctx: struct hostapd_data *
345 : * @timeout_ctx: struct sta_info *
346 : *
347 : * This function is called to check station activity and to remove inactive
348 : * stations.
349 : */
350 10 : void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
351 : {
352 10 : struct hostapd_data *hapd = eloop_ctx;
353 10 : struct sta_info *sta = timeout_ctx;
354 10 : unsigned long next_time = 0;
355 : int reason;
356 :
357 70 : wpa_printf(MSG_DEBUG, "%s: " MACSTR " flags=0x%x timeout_next=%d",
358 60 : __func__, MAC2STR(sta->addr), sta->flags,
359 10 : sta->timeout_next);
360 10 : if (sta->timeout_next == STA_REMOVE) {
361 2 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
362 : HOSTAPD_LEVEL_INFO, "deauthenticated due to "
363 : "local deauth request");
364 2 : ap_free_sta(hapd, sta);
365 2 : return;
366 : }
367 :
368 16 : if ((sta->flags & WLAN_STA_ASSOC) &&
369 9 : (sta->timeout_next == STA_NULLFUNC ||
370 1 : sta->timeout_next == STA_DISASSOC)) {
371 : int inactive_sec;
372 : /*
373 : * Add random value to timeout so that we don't end up bouncing
374 : * all stations at the same time if we have lots of associated
375 : * stations that are idle (but keep re-associating).
376 : */
377 8 : int fuzz = os_random() % 20;
378 8 : inactive_sec = hostapd_drv_get_inact_sec(hapd, sta->addr);
379 8 : if (inactive_sec == -1) {
380 0 : wpa_msg(hapd->msg_ctx, MSG_DEBUG,
381 : "Check inactivity: Could not "
382 : "get station info from kernel driver for "
383 0 : MACSTR, MAC2STR(sta->addr));
384 : /*
385 : * The driver may not support this functionality.
386 : * Anyway, try again after the next inactivity timeout,
387 : * but do not disconnect the station now.
388 : */
389 0 : next_time = hapd->conf->ap_max_inactivity + fuzz;
390 8 : } else if (inactive_sec == -ENOENT) {
391 0 : wpa_msg(hapd->msg_ctx, MSG_DEBUG,
392 : "Station " MACSTR " has lost its driver entry",
393 0 : MAC2STR(sta->addr));
394 :
395 : /* Avoid sending client probe on removed client */
396 0 : sta->timeout_next = STA_DISASSOC;
397 0 : goto skip_poll;
398 8 : } else if (inactive_sec < hapd->conf->ap_max_inactivity) {
399 : /* station activity detected; reset timeout state */
400 24 : wpa_msg(hapd->msg_ctx, MSG_DEBUG,
401 : "Station " MACSTR " has been active %is ago",
402 24 : MAC2STR(sta->addr), inactive_sec);
403 4 : sta->timeout_next = STA_NULLFUNC;
404 4 : next_time = hapd->conf->ap_max_inactivity + fuzz -
405 : inactive_sec;
406 : } else {
407 28 : wpa_msg(hapd->msg_ctx, MSG_DEBUG,
408 : "Station " MACSTR " has been "
409 : "inactive too long: %d sec, max allowed: %d",
410 24 : MAC2STR(sta->addr), inactive_sec,
411 4 : hapd->conf->ap_max_inactivity);
412 :
413 4 : if (hapd->conf->skip_inactivity_poll)
414 1 : sta->timeout_next = STA_DISASSOC;
415 : }
416 : }
417 :
418 16 : if ((sta->flags & WLAN_STA_ASSOC) &&
419 10 : sta->timeout_next == STA_DISASSOC &&
420 3 : !(sta->flags & WLAN_STA_PENDING_POLL) &&
421 1 : !hapd->conf->skip_inactivity_poll) {
422 0 : wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR
423 0 : " has ACKed data poll", MAC2STR(sta->addr));
424 : /* data nullfunc frame poll did not produce TX errors; assume
425 : * station ACKed it */
426 0 : sta->timeout_next = STA_NULLFUNC;
427 0 : next_time = hapd->conf->ap_max_inactivity;
428 : }
429 :
430 : skip_poll:
431 8 : if (next_time) {
432 24 : wpa_printf(MSG_DEBUG, "%s: register ap_handle_timer timeout "
433 : "for " MACSTR " (%lu seconds)",
434 24 : __func__, MAC2STR(sta->addr), next_time);
435 4 : eloop_register_timeout(next_time, 0, ap_handle_timer, hapd,
436 : sta);
437 4 : return;
438 : }
439 :
440 6 : if (sta->timeout_next == STA_NULLFUNC &&
441 2 : (sta->flags & WLAN_STA_ASSOC)) {
442 2 : wpa_printf(MSG_DEBUG, " Polling STA");
443 2 : sta->flags |= WLAN_STA_PENDING_POLL;
444 2 : hostapd_drv_poll_client(hapd, hapd->own_addr, sta->addr,
445 2 : sta->flags & WLAN_STA_WMM);
446 2 : } else if (sta->timeout_next != STA_REMOVE) {
447 2 : int deauth = sta->timeout_next == STA_DEAUTH;
448 :
449 2 : wpa_dbg(hapd->msg_ctx, MSG_DEBUG,
450 : "Timeout, sending %s info to STA " MACSTR,
451 : deauth ? "deauthentication" : "disassociation",
452 : MAC2STR(sta->addr));
453 :
454 2 : if (deauth) {
455 0 : hostapd_drv_sta_deauth(
456 0 : hapd, sta->addr,
457 : WLAN_REASON_PREV_AUTH_NOT_VALID);
458 : } else {
459 4 : reason = (sta->timeout_next == STA_DISASSOC) ?
460 2 : WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY :
461 : WLAN_REASON_PREV_AUTH_NOT_VALID;
462 :
463 2 : hostapd_drv_sta_disassoc(hapd, sta->addr, reason);
464 : }
465 : }
466 :
467 4 : switch (sta->timeout_next) {
468 : case STA_NULLFUNC:
469 2 : sta->timeout_next = STA_DISASSOC;
470 12 : wpa_printf(MSG_DEBUG, "%s: register ap_handle_timer timeout "
471 : "for " MACSTR " (%d seconds - AP_DISASSOC_DELAY)",
472 12 : __func__, MAC2STR(sta->addr), AP_DISASSOC_DELAY);
473 2 : eloop_register_timeout(AP_DISASSOC_DELAY, 0, ap_handle_timer,
474 : hapd, sta);
475 2 : break;
476 : case STA_DISASSOC:
477 : case STA_DISASSOC_FROM_CLI:
478 2 : ap_sta_set_authorized(hapd, sta, 0);
479 2 : sta->flags &= ~WLAN_STA_ASSOC;
480 2 : ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
481 2 : if (!sta->acct_terminate_cause)
482 2 : sta->acct_terminate_cause =
483 : RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT;
484 2 : accounting_sta_stop(hapd, sta);
485 2 : ieee802_1x_free_station(sta);
486 2 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
487 : HOSTAPD_LEVEL_INFO, "disassociated due to "
488 : "inactivity");
489 4 : reason = (sta->timeout_next == STA_DISASSOC) ?
490 2 : WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY :
491 : WLAN_REASON_PREV_AUTH_NOT_VALID;
492 2 : sta->timeout_next = STA_DEAUTH;
493 12 : wpa_printf(MSG_DEBUG, "%s: register ap_handle_timer timeout "
494 : "for " MACSTR " (%d seconds - AP_DEAUTH_DELAY)",
495 12 : __func__, MAC2STR(sta->addr), AP_DEAUTH_DELAY);
496 2 : eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer,
497 : hapd, sta);
498 2 : mlme_disassociate_indication(hapd, sta, reason);
499 2 : break;
500 : case STA_DEAUTH:
501 : case STA_REMOVE:
502 0 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
503 : HOSTAPD_LEVEL_INFO, "deauthenticated due to "
504 : "inactivity (timer DEAUTH/REMOVE)");
505 0 : if (!sta->acct_terminate_cause)
506 0 : sta->acct_terminate_cause =
507 : RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT;
508 0 : mlme_deauthenticate_indication(
509 : hapd, sta,
510 : WLAN_REASON_PREV_AUTH_NOT_VALID);
511 0 : ap_free_sta(hapd, sta);
512 0 : break;
513 : }
514 : }
515 :
516 :
517 4 : static void ap_handle_session_timer(void *eloop_ctx, void *timeout_ctx)
518 : {
519 4 : struct hostapd_data *hapd = eloop_ctx;
520 4 : struct sta_info *sta = timeout_ctx;
521 :
522 4 : if (!(sta->flags & WLAN_STA_AUTH)) {
523 0 : if (sta->flags & WLAN_STA_GAS) {
524 0 : wpa_printf(MSG_DEBUG, "GAS: Remove temporary STA "
525 0 : "entry " MACSTR, MAC2STR(sta->addr));
526 0 : ap_free_sta(hapd, sta);
527 : }
528 4 : return;
529 : }
530 :
531 4 : hostapd_drv_sta_deauth(hapd, sta->addr,
532 : WLAN_REASON_PREV_AUTH_NOT_VALID);
533 4 : mlme_deauthenticate_indication(hapd, sta,
534 : WLAN_REASON_PREV_AUTH_NOT_VALID);
535 4 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
536 : HOSTAPD_LEVEL_INFO, "deauthenticated due to "
537 : "session timeout");
538 4 : sta->acct_terminate_cause =
539 : RADIUS_ACCT_TERMINATE_CAUSE_SESSION_TIMEOUT;
540 4 : ap_free_sta(hapd, sta);
541 : }
542 :
543 :
544 9 : void ap_sta_replenish_timeout(struct hostapd_data *hapd, struct sta_info *sta,
545 : u32 session_timeout)
546 : {
547 9 : if (eloop_replenish_timeout(session_timeout, 0,
548 : ap_handle_session_timer, hapd, sta) == 1) {
549 8 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
550 : HOSTAPD_LEVEL_DEBUG, "setting session timeout "
551 : "to %d seconds", session_timeout);
552 : }
553 9 : }
554 :
555 :
556 18 : void ap_sta_session_timeout(struct hostapd_data *hapd, struct sta_info *sta,
557 : u32 session_timeout)
558 : {
559 18 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
560 : HOSTAPD_LEVEL_DEBUG, "setting session timeout to %d "
561 : "seconds", session_timeout);
562 18 : eloop_cancel_timeout(ap_handle_session_timer, hapd, sta);
563 18 : eloop_register_timeout(session_timeout, 0, ap_handle_session_timer,
564 : hapd, sta);
565 18 : }
566 :
567 :
568 3599 : void ap_sta_no_session_timeout(struct hostapd_data *hapd, struct sta_info *sta)
569 : {
570 3599 : eloop_cancel_timeout(ap_handle_session_timer, hapd, sta);
571 3599 : }
572 :
573 :
574 1 : static void ap_handle_session_warning_timer(void *eloop_ctx, void *timeout_ctx)
575 : {
576 : #ifdef CONFIG_WNM
577 1 : struct hostapd_data *hapd = eloop_ctx;
578 1 : struct sta_info *sta = timeout_ctx;
579 :
580 6 : wpa_printf(MSG_DEBUG, "WNM: Session warning time reached for " MACSTR,
581 6 : MAC2STR(sta->addr));
582 1 : if (sta->hs20_session_info_url == NULL)
583 1 : return;
584 :
585 1 : wnm_send_ess_disassoc_imminent(hapd, sta, sta->hs20_session_info_url,
586 : sta->hs20_disassoc_timer);
587 : #endif /* CONFIG_WNM */
588 : }
589 :
590 :
591 1 : void ap_sta_session_warning_timeout(struct hostapd_data *hapd,
592 : struct sta_info *sta, int warning_time)
593 : {
594 1 : eloop_cancel_timeout(ap_handle_session_warning_timer, hapd, sta);
595 1 : eloop_register_timeout(warning_time, 0, ap_handle_session_warning_timer,
596 : hapd, sta);
597 1 : }
598 :
599 :
600 3117 : struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr)
601 : {
602 : struct sta_info *sta;
603 :
604 3117 : sta = ap_get_sta(hapd, addr);
605 3117 : if (sta)
606 103 : return sta;
607 :
608 3014 : wpa_printf(MSG_DEBUG, " New STA");
609 3014 : if (hapd->num_sta >= hapd->conf->max_num_sta) {
610 : /* FIX: might try to remove some old STAs first? */
611 3 : wpa_printf(MSG_DEBUG, "no more room for new STAs (%d/%d)",
612 3 : hapd->num_sta, hapd->conf->max_num_sta);
613 3 : return NULL;
614 : }
615 :
616 3011 : sta = os_zalloc(sizeof(struct sta_info));
617 3011 : if (sta == NULL) {
618 1 : wpa_printf(MSG_ERROR, "malloc failed");
619 1 : return NULL;
620 : }
621 3010 : sta->acct_interim_interval = hapd->conf->acct_interim_interval;
622 3010 : accounting_sta_get_id(hapd, sta);
623 :
624 3010 : if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_INACTIVITY_TIMER)) {
625 21070 : wpa_printf(MSG_DEBUG, "%s: register ap_handle_timer timeout "
626 : "for " MACSTR " (%d seconds - ap_max_inactivity)",
627 18060 : __func__, MAC2STR(addr),
628 3010 : hapd->conf->ap_max_inactivity);
629 3010 : eloop_register_timeout(hapd->conf->ap_max_inactivity, 0,
630 : ap_handle_timer, hapd, sta);
631 : }
632 :
633 : /* initialize STA info data */
634 3010 : os_memcpy(sta->addr, addr, ETH_ALEN);
635 3010 : sta->next = hapd->sta_list;
636 3010 : hapd->sta_list = sta;
637 3010 : hapd->num_sta++;
638 3010 : ap_sta_hash_add(hapd, sta);
639 3010 : ap_sta_remove_in_other_bss(hapd, sta);
640 3010 : sta->last_seq_ctrl = WLAN_INVALID_MGMT_SEQ;
641 3010 : dl_list_init(&sta->ip6addr);
642 :
643 3010 : return sta;
644 : }
645 :
646 :
647 248 : static int ap_sta_remove(struct hostapd_data *hapd, struct sta_info *sta)
648 : {
649 248 : ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
650 :
651 248 : if (sta->ipaddr)
652 0 : hostapd_drv_br_delete_ip_neigh(hapd, 4, (u8 *) &sta->ipaddr);
653 248 : ap_sta_ip6addr_del(hapd, sta);
654 :
655 1488 : wpa_printf(MSG_DEBUG, "Removing STA " MACSTR " from kernel driver",
656 1488 : MAC2STR(sta->addr));
657 248 : if (hostapd_drv_sta_remove(hapd, sta->addr) &&
658 0 : sta->flags & WLAN_STA_ASSOC) {
659 0 : wpa_printf(MSG_DEBUG, "Could not remove station " MACSTR
660 0 : " from kernel driver.", MAC2STR(sta->addr));
661 0 : return -1;
662 : }
663 248 : return 0;
664 : }
665 :
666 :
667 3010 : static void ap_sta_remove_in_other_bss(struct hostapd_data *hapd,
668 : struct sta_info *sta)
669 : {
670 3010 : struct hostapd_iface *iface = hapd->iface;
671 : size_t i;
672 :
673 6250 : for (i = 0; i < iface->num_bss; i++) {
674 3240 : struct hostapd_data *bss = iface->bss[i];
675 : struct sta_info *sta2;
676 : /* bss should always be set during operation, but it may be
677 : * NULL during reconfiguration. Assume the STA is not
678 : * associated to another BSS in that case to avoid NULL pointer
679 : * dereferences. */
680 3240 : if (bss == hapd || bss == NULL)
681 3010 : continue;
682 230 : sta2 = ap_get_sta(bss, sta->addr);
683 230 : if (!sta2)
684 230 : continue;
685 :
686 0 : ap_sta_disconnect(bss, sta2, sta2->addr,
687 : WLAN_REASON_PREV_AUTH_NOT_VALID);
688 : }
689 3010 : }
690 :
691 :
692 11 : static void ap_sta_disassoc_cb_timeout(void *eloop_ctx, void *timeout_ctx)
693 : {
694 11 : struct hostapd_data *hapd = eloop_ctx;
695 11 : struct sta_info *sta = timeout_ctx;
696 :
697 11 : ap_sta_remove(hapd, sta);
698 11 : mlme_disassociate_indication(hapd, sta, sta->disassoc_reason);
699 11 : }
700 :
701 :
702 266 : void ap_sta_disassociate(struct hostapd_data *hapd, struct sta_info *sta,
703 : u16 reason)
704 : {
705 1862 : wpa_printf(MSG_DEBUG, "%s: disassociate STA " MACSTR,
706 1862 : hapd->conf->iface, MAC2STR(sta->addr));
707 266 : sta->last_seq_ctrl = WLAN_INVALID_MGMT_SEQ;
708 266 : sta->flags &= ~(WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK);
709 266 : ap_sta_set_authorized(hapd, sta, 0);
710 266 : sta->timeout_next = STA_DEAUTH;
711 1596 : wpa_printf(MSG_DEBUG, "%s: reschedule ap_handle_timer timeout "
712 : "for " MACSTR " (%d seconds - "
713 : "AP_MAX_INACTIVITY_AFTER_DISASSOC)",
714 1596 : __func__, MAC2STR(sta->addr),
715 : AP_MAX_INACTIVITY_AFTER_DISASSOC);
716 266 : eloop_cancel_timeout(ap_handle_timer, hapd, sta);
717 266 : eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DISASSOC, 0,
718 : ap_handle_timer, hapd, sta);
719 266 : accounting_sta_stop(hapd, sta);
720 266 : ieee802_1x_free_station(sta);
721 :
722 266 : sta->disassoc_reason = reason;
723 266 : sta->flags |= WLAN_STA_PENDING_DISASSOC_CB;
724 266 : eloop_cancel_timeout(ap_sta_disassoc_cb_timeout, hapd, sta);
725 266 : eloop_register_timeout(hapd->iface->drv_flags &
726 : WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS ? 2 : 0, 0,
727 : ap_sta_disassoc_cb_timeout, hapd, sta);
728 266 : }
729 :
730 :
731 237 : static void ap_sta_deauth_cb_timeout(void *eloop_ctx, void *timeout_ctx)
732 : {
733 237 : struct hostapd_data *hapd = eloop_ctx;
734 237 : struct sta_info *sta = timeout_ctx;
735 :
736 237 : ap_sta_remove(hapd, sta);
737 237 : mlme_deauthenticate_indication(hapd, sta, sta->deauth_reason);
738 237 : }
739 :
740 :
741 21 : void ap_sta_deauthenticate(struct hostapd_data *hapd, struct sta_info *sta,
742 : u16 reason)
743 : {
744 147 : wpa_printf(MSG_DEBUG, "%s: deauthenticate STA " MACSTR,
745 147 : hapd->conf->iface, MAC2STR(sta->addr));
746 21 : sta->last_seq_ctrl = WLAN_INVALID_MGMT_SEQ;
747 21 : sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK);
748 21 : ap_sta_set_authorized(hapd, sta, 0);
749 21 : sta->timeout_next = STA_REMOVE;
750 126 : wpa_printf(MSG_DEBUG, "%s: reschedule ap_handle_timer timeout "
751 : "for " MACSTR " (%d seconds - "
752 : "AP_MAX_INACTIVITY_AFTER_DEAUTH)",
753 126 : __func__, MAC2STR(sta->addr),
754 : AP_MAX_INACTIVITY_AFTER_DEAUTH);
755 21 : eloop_cancel_timeout(ap_handle_timer, hapd, sta);
756 21 : eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DEAUTH, 0,
757 : ap_handle_timer, hapd, sta);
758 21 : accounting_sta_stop(hapd, sta);
759 21 : ieee802_1x_free_station(sta);
760 :
761 21 : sta->deauth_reason = reason;
762 21 : sta->flags |= WLAN_STA_PENDING_DEAUTH_CB;
763 21 : eloop_cancel_timeout(ap_sta_deauth_cb_timeout, hapd, sta);
764 21 : eloop_register_timeout(hapd->iface->drv_flags &
765 : WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS ? 2 : 0, 0,
766 : ap_sta_deauth_cb_timeout, hapd, sta);
767 21 : }
768 :
769 :
770 : #ifdef CONFIG_WPS
771 2 : int ap_sta_wps_cancel(struct hostapd_data *hapd,
772 : struct sta_info *sta, void *ctx)
773 : {
774 2 : if (sta && (sta->flags & WLAN_STA_WPS)) {
775 0 : ap_sta_deauthenticate(hapd, sta,
776 : WLAN_REASON_PREV_AUTH_NOT_VALID);
777 0 : wpa_printf(MSG_DEBUG, "WPS: %s: Deauth sta=" MACSTR,
778 0 : __func__, MAC2STR(sta->addr));
779 0 : return 1;
780 : }
781 :
782 2 : return 0;
783 : }
784 : #endif /* CONFIG_WPS */
785 :
786 :
787 3896 : int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta)
788 : {
789 : #ifndef CONFIG_NO_VLAN
790 : const char *iface;
791 3463 : struct hostapd_vlan *vlan = NULL;
792 : int ret;
793 3463 : int old_vlanid = sta->vlan_id_bound;
794 :
795 3463 : iface = hapd->conf->iface;
796 3463 : if (hapd->conf->ssid.vlan[0])
797 8 : iface = hapd->conf->ssid.vlan;
798 :
799 3463 : if (hapd->conf->ssid.dynamic_vlan == DYNAMIC_VLAN_DISABLED)
800 3423 : sta->vlan_id = 0;
801 40 : else if (sta->vlan_id > 0) {
802 21 : struct hostapd_vlan *wildcard_vlan = NULL;
803 21 : vlan = hapd->conf->vlan;
804 70 : while (vlan) {
805 31 : if (vlan->vlan_id == sta->vlan_id)
806 3 : break;
807 28 : if (vlan->vlan_id == VLAN_ID_WILDCARD)
808 19 : wildcard_vlan = vlan;
809 28 : vlan = vlan->next;
810 : }
811 21 : if (!vlan)
812 18 : vlan = wildcard_vlan;
813 21 : if (vlan)
814 21 : iface = vlan->ifname;
815 : }
816 :
817 : /*
818 : * Do not increment ref counters if the VLAN ID remains same, but do
819 : * not skip hostapd_drv_set_sta_vlan() as hostapd_drv_sta_remove() might
820 : * have been called before.
821 : */
822 3463 : if (sta->vlan_id == old_vlanid)
823 3442 : goto skip_counting;
824 :
825 21 : if (sta->vlan_id > 0 && vlan == NULL) {
826 0 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
827 : HOSTAPD_LEVEL_DEBUG, "could not find VLAN for "
828 : "binding station to (vlan_id=%d)",
829 : sta->vlan_id);
830 0 : ret = -1;
831 0 : goto done;
832 21 : } else if (sta->vlan_id > 0 && vlan->vlan_id == VLAN_ID_WILDCARD) {
833 18 : vlan = vlan_add_dynamic(hapd, vlan, sta->vlan_id);
834 18 : if (vlan == NULL) {
835 0 : hostapd_logger(hapd, sta->addr,
836 : HOSTAPD_MODULE_IEEE80211,
837 : HOSTAPD_LEVEL_DEBUG, "could not add "
838 : "dynamic VLAN interface for vlan_id=%d",
839 : sta->vlan_id);
840 0 : ret = -1;
841 0 : goto done;
842 : }
843 :
844 18 : iface = vlan->ifname;
845 18 : if (vlan_setup_encryption_dyn(hapd, iface) != 0) {
846 0 : hostapd_logger(hapd, sta->addr,
847 : HOSTAPD_MODULE_IEEE80211,
848 : HOSTAPD_LEVEL_DEBUG, "could not "
849 : "configure encryption for dynamic VLAN "
850 : "interface for vlan_id=%d",
851 : sta->vlan_id);
852 : }
853 :
854 18 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
855 : HOSTAPD_LEVEL_DEBUG, "added new dynamic VLAN "
856 : "interface '%s'", iface);
857 3 : } else if (vlan && vlan->vlan_id == sta->vlan_id) {
858 3 : if (vlan->dynamic_vlan > 0) {
859 0 : vlan->dynamic_vlan++;
860 0 : hostapd_logger(hapd, sta->addr,
861 : HOSTAPD_MODULE_IEEE80211,
862 : HOSTAPD_LEVEL_DEBUG, "updated existing "
863 : "dynamic VLAN interface '%s'", iface);
864 : }
865 :
866 : /*
867 : * Update encryption configuration for statically generated
868 : * VLAN interface. This is only used for static WEP
869 : * configuration for the case where hostapd did not yet know
870 : * which keys are to be used when the interface was added.
871 : */
872 3 : if (vlan_setup_encryption_dyn(hapd, iface) != 0) {
873 0 : hostapd_logger(hapd, sta->addr,
874 : HOSTAPD_MODULE_IEEE80211,
875 : HOSTAPD_LEVEL_DEBUG, "could not "
876 : "configure encryption for VLAN "
877 : "interface for vlan_id=%d",
878 : sta->vlan_id);
879 : }
880 : }
881 :
882 : /* ref counters have been increased, so mark the station */
883 21 : sta->vlan_id_bound = sta->vlan_id;
884 :
885 : skip_counting:
886 3463 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
887 : HOSTAPD_LEVEL_DEBUG, "binding station to interface "
888 : "'%s'", iface);
889 :
890 3463 : if (wpa_auth_sta_set_vlan(sta->wpa_sm, sta->vlan_id) < 0)
891 0 : wpa_printf(MSG_INFO, "Failed to update VLAN-ID for WPA");
892 :
893 3463 : ret = hostapd_drv_set_sta_vlan(iface, hapd, sta->addr, sta->vlan_id);
894 3463 : if (ret < 0) {
895 0 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
896 : HOSTAPD_LEVEL_DEBUG, "could not bind the STA "
897 : "entry to vlan_id=%d", sta->vlan_id);
898 : }
899 :
900 : /* During 1x reauth, if the vlan id changes, then remove the old id. */
901 3463 : if (old_vlanid > 0 && old_vlanid != sta->vlan_id)
902 4 : vlan_remove_dynamic(hapd, old_vlanid);
903 : done:
904 :
905 3463 : return ret;
906 : #else /* CONFIG_NO_VLAN */
907 433 : return 0;
908 : #endif /* CONFIG_NO_VLAN */
909 : }
910 :
911 :
912 : #ifdef CONFIG_IEEE80211W
913 :
914 16 : int ap_check_sa_query_timeout(struct hostapd_data *hapd, struct sta_info *sta)
915 : {
916 : u32 tu;
917 : struct os_reltime now, passed;
918 16 : os_get_reltime(&now);
919 16 : os_reltime_sub(&now, &sta->sa_query_start, &passed);
920 16 : tu = (passed.sec * 1000000 + passed.usec) / 1024;
921 16 : if (hapd->conf->assoc_sa_query_max_timeout < tu) {
922 4 : hostapd_logger(hapd, sta->addr,
923 : HOSTAPD_MODULE_IEEE80211,
924 : HOSTAPD_LEVEL_DEBUG,
925 : "association SA Query timed out");
926 4 : sta->sa_query_timed_out = 1;
927 4 : os_free(sta->sa_query_trans_id);
928 4 : sta->sa_query_trans_id = NULL;
929 4 : sta->sa_query_count = 0;
930 4 : eloop_cancel_timeout(ap_sa_query_timer, hapd, sta);
931 4 : return 1;
932 : }
933 :
934 12 : return 0;
935 : }
936 :
937 :
938 20 : static void ap_sa_query_timer(void *eloop_ctx, void *timeout_ctx)
939 : {
940 20 : struct hostapd_data *hapd = eloop_ctx;
941 20 : struct sta_info *sta = timeout_ctx;
942 : unsigned int timeout, sec, usec;
943 : u8 *trans_id, *nbuf;
944 :
945 36 : if (sta->sa_query_count > 0 &&
946 16 : ap_check_sa_query_timeout(hapd, sta))
947 4 : return;
948 :
949 16 : nbuf = os_realloc_array(sta->sa_query_trans_id,
950 16 : sta->sa_query_count + 1,
951 : WLAN_SA_QUERY_TR_ID_LEN);
952 16 : if (nbuf == NULL)
953 0 : return;
954 16 : if (sta->sa_query_count == 0) {
955 : /* Starting a new SA Query procedure */
956 4 : os_get_reltime(&sta->sa_query_start);
957 : }
958 16 : trans_id = nbuf + sta->sa_query_count * WLAN_SA_QUERY_TR_ID_LEN;
959 16 : sta->sa_query_trans_id = nbuf;
960 16 : sta->sa_query_count++;
961 :
962 16 : if (os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN) < 0) {
963 : /*
964 : * We don't really care which ID is used here, so simply
965 : * hardcode this if the mostly theoretical os_get_random()
966 : * failure happens.
967 : */
968 0 : trans_id[0] = 0x12;
969 0 : trans_id[1] = 0x34;
970 : }
971 :
972 16 : timeout = hapd->conf->assoc_sa_query_retry_timeout;
973 16 : sec = ((timeout / 1000) * 1024) / 1000;
974 16 : usec = (timeout % 1000) * 1024;
975 16 : eloop_register_timeout(sec, usec, ap_sa_query_timer, hapd, sta);
976 :
977 16 : hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
978 : HOSTAPD_LEVEL_DEBUG,
979 : "association SA Query attempt %d", sta->sa_query_count);
980 :
981 16 : ieee802_11_send_sa_query_req(hapd, sta->addr, trans_id);
982 : }
983 :
984 :
985 4 : void ap_sta_start_sa_query(struct hostapd_data *hapd, struct sta_info *sta)
986 : {
987 4 : ap_sa_query_timer(hapd, sta);
988 4 : }
989 :
990 :
991 0 : void ap_sta_stop_sa_query(struct hostapd_data *hapd, struct sta_info *sta)
992 : {
993 0 : eloop_cancel_timeout(ap_sa_query_timer, hapd, sta);
994 0 : os_free(sta->sa_query_trans_id);
995 0 : sta->sa_query_trans_id = NULL;
996 0 : sta->sa_query_count = 0;
997 0 : }
998 :
999 : #endif /* CONFIG_IEEE80211W */
1000 :
1001 :
1002 13140 : void ap_sta_set_authorized(struct hostapd_data *hapd, struct sta_info *sta,
1003 : int authorized)
1004 : {
1005 13140 : const u8 *dev_addr = NULL;
1006 : char buf[100];
1007 : #ifdef CONFIG_P2P
1008 : u8 addr[ETH_ALEN];
1009 : u8 ip_addr_buf[4];
1010 : #endif /* CONFIG_P2P */
1011 :
1012 13140 : if (!!authorized == !!(sta->flags & WLAN_STA_AUTHORIZED))
1013 21614 : return;
1014 :
1015 4666 : if (authorized)
1016 2333 : sta->flags |= WLAN_STA_AUTHORIZED;
1017 : else
1018 2333 : sta->flags &= ~WLAN_STA_AUTHORIZED;
1019 :
1020 : #ifdef CONFIG_P2P
1021 462 : if (hapd->p2p_group == NULL) {
1022 291 : if (sta->p2p_ie != NULL &&
1023 144 : p2p_parse_dev_addr_in_p2p_ie(sta->p2p_ie, addr) == 0)
1024 144 : dev_addr = addr;
1025 : } else
1026 315 : dev_addr = p2p_group_get_dev_addr(hapd->p2p_group, sta->addr);
1027 :
1028 462 : if (dev_addr)
1029 4896 : os_snprintf(buf, sizeof(buf), MACSTR " p2p_dev_addr=" MACSTR,
1030 4896 : MAC2STR(sta->addr), MAC2STR(dev_addr));
1031 : else
1032 : #endif /* CONFIG_P2P */
1033 4258 : os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(sta->addr));
1034 :
1035 4666 : if (hapd->sta_authorized_cb)
1036 924 : hapd->sta_authorized_cb(hapd->sta_authorized_cb_ctx,
1037 462 : sta->addr, authorized, dev_addr);
1038 :
1039 4666 : if (authorized) {
1040 : char ip_addr[100];
1041 2333 : ip_addr[0] = '\0';
1042 : #ifdef CONFIG_P2P
1043 231 : if (wpa_auth_get_ip_addr(sta->wpa_sm, ip_addr_buf) == 0) {
1044 380 : os_snprintf(ip_addr, sizeof(ip_addr),
1045 : " ip_addr=%u.%u.%u.%u",
1046 190 : ip_addr_buf[0], ip_addr_buf[1],
1047 190 : ip_addr_buf[2], ip_addr_buf[3]);
1048 : }
1049 : #endif /* CONFIG_P2P */
1050 :
1051 2333 : wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s",
1052 : buf, ip_addr);
1053 :
1054 2564 : if (hapd->msg_ctx_parent &&
1055 231 : hapd->msg_ctx_parent != hapd->msg_ctx)
1056 23 : wpa_msg_no_global(hapd->msg_ctx_parent, MSG_INFO,
1057 : AP_STA_CONNECTED "%s%s",
1058 : buf, ip_addr);
1059 : } else {
1060 2333 : wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED "%s", buf);
1061 :
1062 2564 : if (hapd->msg_ctx_parent &&
1063 231 : hapd->msg_ctx_parent != hapd->msg_ctx)
1064 23 : wpa_msg_no_global(hapd->msg_ctx_parent, MSG_INFO,
1065 : AP_STA_DISCONNECTED "%s", buf);
1066 : }
1067 :
1068 : #ifdef CONFIG_FST
1069 4666 : if (hapd->iface->fst) {
1070 493 : if (authorized)
1071 247 : fst_notify_peer_connected(hapd->iface->fst, sta->addr);
1072 : else
1073 246 : fst_notify_peer_disconnected(hapd->iface->fst,
1074 246 : sta->addr);
1075 : }
1076 : #endif /* CONFIG_FST */
1077 : }
1078 :
1079 :
1080 576 : void ap_sta_disconnect(struct hostapd_data *hapd, struct sta_info *sta,
1081 : const u8 *addr, u16 reason)
1082 : {
1083 :
1084 576 : if (sta == NULL && addr)
1085 21 : sta = ap_get_sta(hapd, addr);
1086 :
1087 576 : if (addr)
1088 576 : hostapd_drv_sta_deauth(hapd, addr, reason);
1089 :
1090 576 : if (sta == NULL)
1091 576 : return;
1092 576 : ap_sta_set_authorized(hapd, sta, 0);
1093 576 : wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH);
1094 576 : ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
1095 576 : sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
1096 3456 : wpa_printf(MSG_DEBUG, "%s: reschedule ap_handle_timer timeout "
1097 : "for " MACSTR " (%d seconds - "
1098 : "AP_MAX_INACTIVITY_AFTER_DEAUTH)",
1099 3456 : __func__, MAC2STR(sta->addr),
1100 : AP_MAX_INACTIVITY_AFTER_DEAUTH);
1101 576 : eloop_cancel_timeout(ap_handle_timer, hapd, sta);
1102 576 : eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DEAUTH, 0,
1103 : ap_handle_timer, hapd, sta);
1104 576 : sta->timeout_next = STA_REMOVE;
1105 :
1106 576 : sta->deauth_reason = reason;
1107 576 : sta->flags |= WLAN_STA_PENDING_DEAUTH_CB;
1108 576 : eloop_cancel_timeout(ap_sta_deauth_cb_timeout, hapd, sta);
1109 576 : eloop_register_timeout(hapd->iface->drv_flags &
1110 : WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS ? 2 : 0, 0,
1111 : ap_sta_deauth_cb_timeout, hapd, sta);
1112 : }
1113 :
1114 :
1115 259 : void ap_sta_deauth_cb(struct hostapd_data *hapd, struct sta_info *sta)
1116 : {
1117 259 : if (!(sta->flags & WLAN_STA_PENDING_DEAUTH_CB)) {
1118 22 : wpa_printf(MSG_DEBUG, "Ignore deauth cb for test frame");
1119 281 : return;
1120 : }
1121 237 : sta->flags &= ~WLAN_STA_PENDING_DEAUTH_CB;
1122 237 : eloop_cancel_timeout(ap_sta_deauth_cb_timeout, hapd, sta);
1123 237 : ap_sta_deauth_cb_timeout(hapd, sta);
1124 : }
1125 :
1126 :
1127 24 : void ap_sta_disassoc_cb(struct hostapd_data *hapd, struct sta_info *sta)
1128 : {
1129 24 : if (!(sta->flags & WLAN_STA_PENDING_DISASSOC_CB)) {
1130 22 : wpa_printf(MSG_DEBUG, "Ignore disassoc cb for test frame");
1131 46 : return;
1132 : }
1133 2 : sta->flags &= ~WLAN_STA_PENDING_DISASSOC_CB;
1134 2 : eloop_cancel_timeout(ap_sta_disassoc_cb_timeout, hapd, sta);
1135 2 : ap_sta_disassoc_cb_timeout(hapd, sta);
1136 : }
1137 :
1138 :
1139 202 : int ap_sta_flags_txt(u32 flags, char *buf, size_t buflen)
1140 : {
1141 : int res;
1142 :
1143 202 : buf[0] = '\0';
1144 3434 : res = os_snprintf(buf, buflen, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
1145 202 : (flags & WLAN_STA_AUTH ? "[AUTH]" : ""),
1146 202 : (flags & WLAN_STA_ASSOC ? "[ASSOC]" : ""),
1147 202 : (flags & WLAN_STA_AUTHORIZED ? "[AUTHORIZED]" : ""),
1148 202 : (flags & WLAN_STA_PENDING_POLL ? "[PENDING_POLL" :
1149 : ""),
1150 202 : (flags & WLAN_STA_SHORT_PREAMBLE ?
1151 : "[SHORT_PREAMBLE]" : ""),
1152 202 : (flags & WLAN_STA_PREAUTH ? "[PREAUTH]" : ""),
1153 202 : (flags & WLAN_STA_WMM ? "[WMM]" : ""),
1154 202 : (flags & WLAN_STA_MFP ? "[MFP]" : ""),
1155 202 : (flags & WLAN_STA_WPS ? "[WPS]" : ""),
1156 202 : (flags & WLAN_STA_MAYBE_WPS ? "[MAYBE_WPS]" : ""),
1157 202 : (flags & WLAN_STA_WDS ? "[WDS]" : ""),
1158 202 : (flags & WLAN_STA_NONERP ? "[NonERP]" : ""),
1159 202 : (flags & WLAN_STA_WPS2 ? "[WPS2]" : ""),
1160 202 : (flags & WLAN_STA_GAS ? "[GAS]" : ""),
1161 202 : (flags & WLAN_STA_VHT ? "[VHT]" : ""),
1162 202 : (flags & WLAN_STA_VENDOR_VHT ? "[VENDOR_VHT]" : ""),
1163 202 : (flags & WLAN_STA_WNM_SLEEP_MODE ?
1164 : "[WNM_SLEEP_MODE]" : ""));
1165 202 : if (os_snprintf_error(buflen, res))
1166 0 : res = -1;
1167 :
1168 202 : return res;
1169 : }
|