sta_info.c revision c5ec7f57ead87efa365800228aa0b09a12d9e6c4
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * hostapd / Station table 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (c) 2002-2011, Jouni Malinen <j@w1.fi> 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This software may be distributed under the terms of the BSD license. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See README for more details. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "utils/includes.h" 10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 11d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "utils/common.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "utils/eloop.h" 13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "common/ieee802_11_defs.h" 14c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "common/wpa_ctrl.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "radius/radius.h" 164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "radius/radius_client.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "drivers/driver.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "p2p/p2p.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "hostapd.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "accounting.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ieee802_1x.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ieee802_11.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "wpa_auth.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "preauth_auth.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ap_config.h" 26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "beacon.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ap_mlme.h" 288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "vlan_init.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "p2p_hostapd.h" 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ap_drv_ops.h" 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "sta_info.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)static void ap_sta_remove_in_other_bss(struct hostapd_data *hapd, 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct sta_info *sta); 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static void ap_handle_session_timer(void *eloop_ctx, void *timeout_ctx); 360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)static void ap_sta_deauth_cb_timeout(void *eloop_ctx, void *timeout_ctx); 371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)static void ap_sta_disassoc_cb_timeout(void *eloop_ctx, void *timeout_ctx); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef CONFIG_IEEE80211W 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static void ap_sa_query_timer(void *eloop_ctx, void *timeout_ctx); 4068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif /* CONFIG_IEEE80211W */ 41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)static int ap_sta_remove(struct hostapd_data *hapd, struct sta_info *sta); 42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)int ap_for_each_sta(struct hostapd_data *hapd, 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int (*cb)(struct hostapd_data *hapd, struct sta_info *sta, 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void *ctx), 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void *ctx) 47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles){ 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct sta_info *sta; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (sta = hapd->sta_list; sta; sta = sta->next) { 51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (cb(hapd, sta, ctx)) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct sta_info * ap_get_sta(struct hostapd_data *hapd, const u8 *sta) 60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles){ 61c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch struct sta_info *s; 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 63a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) s = hapd->sta_hash[STA_HASH(sta)]; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (s != NULL && os_memcmp(s->addr, sta, 6) != 0) 653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) s = s->hnext; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return s; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void ap_sta_list_del(struct hostapd_data *hapd, struct sta_info *sta) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct sta_info *tmp; 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hapd->sta_list == sta) { 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hapd->sta_list = sta->next; 764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = hapd->sta_list; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (tmp != NULL && tmp->next != sta) 8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) tmp = tmp->next; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == NULL) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wpa_printf(MSG_DEBUG, "Could not remove STA " MACSTR " from " 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "list.", MAC2STR(sta->addr)); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) tmp->next = sta->next; 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void ap_sta_hash_add(struct hostapd_data *hapd, struct sta_info *sta) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sta->hnext = hapd->sta_hash[STA_HASH(sta->addr)]; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hapd->sta_hash[STA_HASH(sta->addr)] = sta; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)static void ap_sta_hash_del(struct hostapd_data *hapd, struct sta_info *sta) 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles){ 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct sta_info *s; 1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) s = hapd->sta_hash[STA_HASH(sta->addr)]; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (s == NULL) return; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (os_memcmp(s->addr, sta->addr, 6) == 0) { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hapd->sta_hash[STA_HASH(sta->addr)] = s->hnext; 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) while (s->hnext != NULL && 109c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch os_memcmp(s->hnext->addr, sta->addr, ETH_ALEN) != 0) 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) s = s->hnext; 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (s->hnext != NULL) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s->hnext = s->hnext->hnext; 113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch else 114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch wpa_printf(MSG_DEBUG, "AP: could not remove STA " MACSTR 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " from hash table", MAC2STR(sta->addr)); 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 117a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta) 1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles){ 1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int set_beacon = 0; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) accounting_sta_stop(hapd, sta); 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /* just in case */ 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ap_sta_set_authorized(hapd, sta, 0); 1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (sta->flags & WLAN_STA_WDS) 129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch hostapd_set_wds_sta(hapd, sta->addr, sta->aid, 0); 1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 131effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!(sta->flags & WLAN_STA_PREAUTH)) 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) hostapd_drv_sta_remove(hapd, sta->addr); 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 134effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ap_sta_hash_del(hapd, sta); 135c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ap_sta_list_del(hapd, sta); 136c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sta->aid > 0) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hapd->sta_aid[(sta->aid - 1) / 32] &= 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~BIT((sta->aid - 1) % 32); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hapd->num_sta--; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sta->nonerp_set) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sta->nonerp_set = 0; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hapd->iface->num_sta_non_erp--; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hapd->iface->num_sta_non_erp == 0) 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) set_beacon++; 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (sta->no_short_slot_time_set) { 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sta->no_short_slot_time_set = 0; 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hapd->iface->num_sta_no_short_slot_time--; 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) && hapd->iface->num_sta_no_short_slot_time == 0) 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) set_beacon++; 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (sta->no_short_preamble_set) { 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sta->no_short_preamble_set = 0; 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hapd->iface->num_sta_no_short_preamble--; 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) && hapd->iface->num_sta_no_short_preamble == 0) 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) set_beacon++; 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sta->no_ht_gf_set) { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sta->no_ht_gf_set = 0; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hapd->iface->num_sta_ht_no_gf--; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sta->no_ht_set) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sta->no_ht_set = 0; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hapd->iface->num_sta_no_ht--; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sta->ht_20mhz_set) { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sta->ht_20mhz_set = 0; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hapd->iface->num_sta_ht_20mhz--; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef CONFIG_P2P 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sta->no_p2p_set) { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sta->no_p2p_set = 0; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hapd->num_sta_no_p2p--; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hapd->num_sta_no_p2p == 0) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hostapd_p2p_non_p2p_sta_disconnected(hapd); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* CONFIG_P2P */ 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(NEED_AP_MLME) && defined(CONFIG_IEEE80211N) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hostapd_ht_operation_update(hapd->iface) > 0) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_beacon++; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* NEED_AP_MLME && CONFIG_IEEE80211N */ 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (set_beacon) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ieee802_11_set_beacons(hapd->iface); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) eloop_cancel_timeout(ap_handle_timer, hapd, sta); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) eloop_cancel_timeout(ap_handle_session_timer, hapd, sta); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) eloop_cancel_timeout(ap_sta_deauth_cb_timeout, hapd, sta); 200c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch eloop_cancel_timeout(ap_sta_disassoc_cb_timeout, hapd, sta); 201c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ieee802_1x_free_station(sta); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wpa_auth_sta_deinit(sta->wpa_sm); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rsn_preauth_free_station(hapd, sta); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CONFIG_NO_RADIUS 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) radius_client_flush_auth(hapd->radius, sta->addr); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* CONFIG_NO_RADIUS */ 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os_free(sta->last_assoc_req); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os_free(sta->challenge); 2111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef CONFIG_IEEE80211W 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os_free(sta->sa_query_trans_id); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) eloop_cancel_timeout(ap_sa_query_timer, hapd, sta); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* CONFIG_IEEE80211W */ 2161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 217a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#ifdef CONFIG_P2P 218a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) p2p_group_notif_disassoc(hapd->p2p_group, sta->addr); 219a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif /* CONFIG_P2P */ 220a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wpabuf_free(sta->wps_ie); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wpabuf_free(sta->p2p_ie); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os_free(sta->ht_capabilities); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os_free(sta->psk); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os_free(sta); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void hostapd_free_stas(struct hostapd_data *hapd) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct sta_info *sta, *prev; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) sta = hapd->sta_list; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (sta) { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prev = sta; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sta->flags & WLAN_STA_AUTH) { 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mlme_deauthenticate_indication( 2411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) hapd, sta, WLAN_REASON_UNSPECIFIED); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sta = sta->next; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wpa_printf(MSG_DEBUG, "Removing station " MACSTR, 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MAC2STR(prev->addr)); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ap_free_sta(hapd, prev); 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/** 252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * ap_handle_timer - Per STA timer handler 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @eloop_ctx: struct hostapd_data * 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @timeout_ctx: struct sta_info * 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * This function is called to check station activity and to remove inactive 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * stations. 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ap_handle_timer(void *eloop_ctx, void *timeout_ctx) 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct hostapd_data *hapd = eloop_ctx; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct sta_info *sta = timeout_ctx; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long next_time = 0; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (sta->timeout_next == STA_REMOVE) { 2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) HOSTAPD_LEVEL_INFO, "deauthenticated due to " 2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "local deauth request"); 2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ap_free_sta(hapd, sta); 2704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 2714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if ((sta->flags & WLAN_STA_ASSOC) && 2741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) (sta->timeout_next == STA_NULLFUNC || 2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sta->timeout_next == STA_DISASSOC)) { 276c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int inactive_sec; 277c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch inactive_sec = hostapd_drv_get_inact_sec(hapd, sta->addr); 2784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (inactive_sec == -1) { 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) wpa_msg(hapd->msg_ctx, MSG_DEBUG, 2804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "Check inactivity: Could not " 2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "get station info from kernel driver for " 2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) MACSTR, MAC2STR(sta->addr)); 2834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /* 2844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * The driver may not support this functionality. 285c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * Anyway, try again after the next inactivity timeout, 2864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * but do not disconnect the station now. 2874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_time = hapd->conf->ap_max_inactivity; 2894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else if (inactive_sec < hapd->conf->ap_max_inactivity && 2904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sta->flags & WLAN_STA_ASSOC) { 2914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /* station activity detected; reset timeout state */ 2924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) wpa_msg(hapd->msg_ctx, MSG_DEBUG, 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Station " MACSTR " has been active %is ago", 2944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) MAC2STR(sta->addr), inactive_sec); 2954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sta->timeout_next = STA_NULLFUNC; 2964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) next_time = hapd->conf->ap_max_inactivity - 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inactive_sec; 2988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } else { 2998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) wpa_msg(hapd->msg_ctx, MSG_DEBUG, 3008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) "Station " MACSTR " has been " 3018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) "inactive too long: %d sec, max allowed: %d", 3024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) MAC2STR(sta->addr), inactive_sec, 3034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) hapd->conf->ap_max_inactivity); 3044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (hapd->conf->skip_inactivity_poll) 306c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch sta->timeout_next = STA_DISASSOC; 3074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if ((sta->flags & WLAN_STA_ASSOC) && 3114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sta->timeout_next == STA_DISASSOC && 3124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) !(sta->flags & WLAN_STA_PENDING_POLL) && 3134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) !hapd->conf->skip_inactivity_poll) { 3144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR 3154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) " has ACKed data poll", MAC2STR(sta->addr)); 3164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /* data nullfunc frame poll did not produce TX errors; assume 3174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * station ACKed it */ 3184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sta->timeout_next = STA_NULLFUNC; 31990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) next_time = hapd->conf->ap_max_inactivity; 3204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (next_time) { 3238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) eloop_register_timeout(next_time, 0, ap_handle_timer, hapd, 3244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sta); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 327c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 328c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (sta->timeout_next == STA_NULLFUNC && 3294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) (sta->flags & WLAN_STA_ASSOC)) { 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wpa_printf(MSG_DEBUG, " Polling STA"); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sta->flags |= WLAN_STA_PENDING_POLL; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hostapd_drv_poll_client(hapd, hapd->own_addr, sta->addr, 3337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sta->flags & WLAN_STA_WMM); 3347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } else if (sta->timeout_next != STA_REMOVE) { 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int deauth = sta->timeout_next == STA_DEAUTH; 3367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wpa_dbg(hapd->msg_ctx, MSG_DEBUG, 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Timeout, sending %s info to STA " MACSTR, 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deauth ? "deauthentication" : "disassociation", 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MAC2STR(sta->addr)); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (deauth) { 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hostapd_drv_sta_deauth( 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hapd, sta->addr, 345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) WLAN_REASON_PREV_AUTH_NOT_VALID); 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hostapd_drv_sta_disassoc( 348f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hapd, sta->addr, 349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (sta->timeout_next) { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STA_NULLFUNC: 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sta->timeout_next = STA_DISASSOC; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) eloop_register_timeout(AP_DISASSOC_DELAY, 0, ap_handle_timer, 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hapd, sta); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STA_DISASSOC: 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ap_sta_set_authorized(hapd, sta, 0); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sta->flags &= ~WLAN_STA_ASSOC; 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); 363ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (!sta->acct_terminate_cause) 364ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch sta->acct_terminate_cause = 365ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT; 366ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch accounting_sta_stop(hapd, sta); 367c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ieee802_1x_free_station(sta); 368ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 369ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch HOSTAPD_LEVEL_INFO, "disassociated due to " 370ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch "inactivity"); 371ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch sta->timeout_next = STA_DEAUTH; 372ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer, 373ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch hapd, sta); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mlme_disassociate_indication( 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hapd, sta, WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case STA_DEAUTH: 3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case STA_REMOVE: 3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) HOSTAPD_LEVEL_INFO, "deauthenticated due to " 3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "inactivity (timer DEAUTH/REMOVE)"); 3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!sta->acct_terminate_cause) 383a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) sta->acct_terminate_cause = 384a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT; 385a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) mlme_deauthenticate_indication( 386a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) hapd, sta, 387a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) WLAN_REASON_PREV_AUTH_NOT_VALID); 388a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ap_free_sta(hapd, sta); 389a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 390a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 392a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 393a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 394a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static void ap_handle_session_timer(void *eloop_ctx, void *timeout_ctx) 395a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles){ 396a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) struct hostapd_data *hapd = eloop_ctx; 397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) struct sta_info *sta = timeout_ctx; 398a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) u8 addr[ETH_ALEN]; 399a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 400a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!(sta->flags & WLAN_STA_AUTH)) 401a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return; 402a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) mlme_deauthenticate_indication(hapd, sta, 404b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) WLAN_REASON_PREV_AUTH_NOT_VALID); 405b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 406b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) HOSTAPD_LEVEL_INFO, "deauthenticated due to " 4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "session timeout"); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sta->acct_terminate_cause = 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RADIUS_ACCT_TERMINATE_CAUSE_SESSION_TIMEOUT; 410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) os_memcpy(addr, sta->addr, ETH_ALEN); 411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ap_free_sta(hapd, sta); 412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hostapd_drv_sta_deauth(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID); 413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 416c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid ap_sta_session_timeout(struct hostapd_data *hapd, struct sta_info *sta, 417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) u32 session_timeout) 418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){ 419c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) HOSTAPD_LEVEL_DEBUG, "setting session timeout to %d " 421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "seconds", session_timeout); 422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) eloop_cancel_timeout(ap_handle_session_timer, hapd, sta); 4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) eloop_register_timeout(session_timeout, 0, ap_handle_session_timer, 424c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch hapd, sta); 4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 428c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid ap_sta_no_session_timeout(struct hostapd_data *hapd, struct sta_info *sta) 4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){ 4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) eloop_cancel_timeout(ap_handle_session_timer, hapd, sta); 431c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct sta_info * ap_sta_add(struct hostapd_data *hapd, const u8 *addr) 435b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles){ 436b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) struct sta_info *sta; 437b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sta = ap_get_sta(hapd, addr); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sta) 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sta; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wpa_printf(MSG_DEBUG, " New STA"); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hapd->num_sta >= hapd->conf->max_num_sta) { 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* FIX: might try to remove some old STAs first? */ 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wpa_printf(MSG_DEBUG, "no more room for new STAs (%d/%d)", 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hapd->num_sta, hapd->conf->max_num_sta); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 449a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 450a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) sta = os_zalloc(sizeof(struct sta_info)); 451c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (sta == NULL) { 452a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) wpa_printf(MSG_ERROR, "malloc failed"); 453a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return NULL; 454a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 455a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) sta->acct_interim_interval = hapd->conf->acct_interim_interval; 456a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 457a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /* initialize STA info data */ 458a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) eloop_register_timeout(hapd->conf->ap_max_inactivity, 0, 459a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ap_handle_timer, hapd, sta); 460a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) os_memcpy(sta->addr, addr, ETH_ALEN); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sta->next = hapd->sta_list; 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hapd->sta_list = sta; 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hapd->num_sta++; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ap_sta_hash_add(hapd, sta); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sta->ssid = &hapd->conf->ssid; 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ap_sta_remove_in_other_bss(hapd, sta); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sta; 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 471c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int ap_sta_remove(struct hostapd_data *hapd, struct sta_info *sta) 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); 4751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 476c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch wpa_printf(MSG_DEBUG, "Removing STA " MACSTR " from kernel driver", 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MAC2STR(sta->addr)); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (hostapd_drv_sta_remove(hapd, sta->addr) && 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sta->flags & WLAN_STA_ASSOC) { 4801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) wpa_printf(MSG_DEBUG, "Could not remove station " MACSTR 481c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch " from kernel driver.", MAC2STR(sta->addr)); 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return -1; 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 488c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochstatic void ap_sta_remove_in_other_bss(struct hostapd_data *hapd, 489c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch struct sta_info *sta) 490c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch{ 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct hostapd_iface *iface = hapd->iface; 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t i; 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < iface->num_bss; i++) { 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct hostapd_data *bss = iface->bss[i]; 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct sta_info *sta2; 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* bss should always be set during operation, but it may be 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * NULL during reconfiguration. Assume the STA is not 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * associated to another BSS in that case to avoid NULL pointer 5004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * dereferences. */ 5011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (bss == hapd || bss == NULL) 5024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) continue; 5034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sta2 = ap_get_sta(bss, sta->addr); 5044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!sta2) 5054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) continue; 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ap_sta_disconnect(bss, sta2, sta2->addr, 508c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch WLAN_REASON_PREV_AUTH_NOT_VALID); 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void ap_sta_disassoc_cb_timeout(void *eloop_ctx, void *timeout_ctx) 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct hostapd_data *hapd = eloop_ctx; 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct sta_info *sta = timeout_ctx; 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ap_sta_remove(hapd, sta); 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mlme_disassociate_indication(hapd, sta, sta->disassoc_reason); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ap_sta_disassociate(struct hostapd_data *hapd, struct sta_info *sta, 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u16 reason) 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) wpa_printf(MSG_DEBUG, "%s: disassociate STA " MACSTR, 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hapd->conf->iface, MAC2STR(sta->addr)); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sta->flags &= ~WLAN_STA_ASSOC; 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ap_sta_set_authorized(hapd, sta, 0); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sta->timeout_next = STA_DEAUTH; 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) eloop_cancel_timeout(ap_handle_timer, hapd, sta); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DISASSOC, 0, 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ap_handle_timer, hapd, sta); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) accounting_sta_stop(hapd, sta); 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ieee802_1x_free_station(sta); 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sta->disassoc_reason = reason; 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sta->flags |= WLAN_STA_PENDING_DISASSOC_CB; 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) eloop_cancel_timeout(ap_sta_disassoc_cb_timeout, hapd, sta); 5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) eloop_register_timeout(hapd->iface->drv_flags & 5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS ? 2 : 0, 0, 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ap_sta_disassoc_cb_timeout, hapd, sta); 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static void ap_sta_deauth_cb_timeout(void *eloop_ctx, void *timeout_ctx) 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 548a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) struct hostapd_data *hapd = eloop_ctx; 549a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) struct sta_info *sta = timeout_ctx; 550f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 551a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ap_sta_remove(hapd, sta); 552a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) mlme_deauthenticate_indication(hapd, sta, sta->deauth_reason); 553a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 5544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 555a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 556c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid ap_sta_deauthenticate(struct hostapd_data *hapd, struct sta_info *sta, 5574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) u16 reason) 558f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles){ 559a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) wpa_printf(MSG_DEBUG, "%s: deauthenticate STA " MACSTR, 560f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) hapd->conf->iface, MAC2STR(sta->addr)); 5611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC); 5625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ap_sta_set_authorized(hapd, sta, 0); 5634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sta->timeout_next = STA_REMOVE; 564a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) eloop_cancel_timeout(ap_handle_timer, hapd, sta); 565a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DEAUTH, 0, 566c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ap_handle_timer, hapd, sta); 567c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch accounting_sta_stop(hapd, sta); 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ieee802_1x_free_station(sta); 569a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sta->deauth_reason = reason; 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sta->flags |= WLAN_STA_PENDING_DEAUTH_CB; 572eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch eloop_cancel_timeout(ap_sta_deauth_cb_timeout, hapd, sta); 573eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch eloop_register_timeout(hapd->iface->drv_flags & 574eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS ? 2 : 0, 0, 575eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ap_sta_deauth_cb_timeout, hapd, sta); 576eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 5777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 5787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 579eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta, 580eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int old_vlanid) 5818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles){ 5828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#ifndef CONFIG_NO_VLAN 5838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const char *iface; 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct hostapd_vlan *vlan = NULL; 5855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int ret; 5865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /* 5885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Do not proceed furthur if the vlan id remains same. We do not want 5895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * duplicate dynamic vlan entries. 5905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 5918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (sta->vlan_id == old_vlanid) 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * During 1x reauth, if the vlan id changes, then remove the old id and 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * proceed furthur to add the new one. 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (old_vlanid > 0) 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vlan_remove_dynamic(hapd, old_vlanid); 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) iface = hapd->conf->iface; 6025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (sta->ssid->vlan[0]) 6034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) iface = sta->ssid->vlan; 6044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (sta->ssid->dynamic_vlan == DYNAMIC_VLAN_DISABLED) 6064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sta->vlan_id = 0; 607c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch else if (sta->vlan_id > 0) { 608effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch vlan = hapd->conf->vlan; 609c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch while (vlan) { 610effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (vlan->vlan_id == sta->vlan_id || 6114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) vlan->vlan_id == VLAN_ID_WILDCARD) { 612effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch iface = vlan->ifname; 613effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch break; 6144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) vlan = vlan->next; 6164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 618c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 6194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (sta->vlan_id > 0 && vlan == NULL) { 6204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 6215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) HOSTAPD_LEVEL_DEBUG, "could not find VLAN for " 6224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "binding station to (vlan_id=%d)", 6234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sta->vlan_id); 6244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return -1; 625c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else if (sta->vlan_id > 0 && vlan->vlan_id == VLAN_ID_WILDCARD) { 6264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) vlan = vlan_add_dynamic(hapd, vlan, sta->vlan_id); 6274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (vlan == NULL) { 6284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) hostapd_logger(hapd, sta->addr, 6294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) HOSTAPD_MODULE_IEEE80211, 6304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) HOSTAPD_LEVEL_DEBUG, "could not add " 6314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "dynamic VLAN interface for vlan_id=%d", 632effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch sta->vlan_id); 633effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return -1; 6344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) iface = vlan->ifname; 6374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (vlan_setup_encryption_dyn(hapd, sta->ssid, iface) != 0) { 6384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) hostapd_logger(hapd, sta->addr, 6394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) HOSTAPD_MODULE_IEEE80211, 6404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) HOSTAPD_LEVEL_DEBUG, "could not " 6414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "configure encryption for dynamic VLAN " 6424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "interface for vlan_id=%d", 6434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sta->vlan_id); 6445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 6475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) HOSTAPD_LEVEL_DEBUG, "added new dynamic VLAN " 6485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "interface '%s'", iface); 6495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (vlan && vlan->vlan_id == sta->vlan_id) { 6505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (sta->vlan_id > 0) { 6514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) vlan->dynamic_vlan++; 6524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) hostapd_logger(hapd, sta->addr, 6534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) HOSTAPD_MODULE_IEEE80211, 6545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) HOSTAPD_LEVEL_DEBUG, "updated existing " 6555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "dynamic VLAN interface '%s'", iface); 6565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /* 6594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * Update encryption configuration for statically generated 6605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * VLAN interface. This is only used for static WEP 6615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * configuration for the case where hostapd did not yet know 6624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) * which keys are to be used when the interface was added. 6634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) */ 6644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (vlan_setup_encryption_dyn(hapd, sta->ssid, iface) != 0) { 6654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) hostapd_logger(hapd, sta->addr, 666a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) HOSTAPD_MODULE_IEEE80211, 667a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) HOSTAPD_LEVEL_DEBUG, "could not " 668c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch "configure encryption for VLAN " 669a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "interface for vlan_id=%d", 670a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) sta->vlan_id); 6714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 6754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) HOSTAPD_LEVEL_DEBUG, "binding station to interface " 6764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "'%s'", iface); 677a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 678a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (wpa_auth_sta_set_vlan(sta->wpa_sm, sta->vlan_id) < 0) 679a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) wpa_printf(MSG_INFO, "Failed to update VLAN-ID for WPA"); 680a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 681a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ret = hostapd_drv_set_sta_vlan(iface, hapd, sta->addr, sta->vlan_id); 682a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (ret < 0) { 683a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 684a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) HOSTAPD_LEVEL_DEBUG, "could not bind the STA " 685a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "entry to vlan_id=%d", sta->vlan_id); 6864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return ret; 6884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#else /* CONFIG_NO_VLAN */ 6894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return 0; 6904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif /* CONFIG_NO_VLAN */ 6914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 6924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#ifdef CONFIG_IEEE80211W 695a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 696a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)int ap_check_sa_query_timeout(struct hostapd_data *hapd, struct sta_info *sta) 697a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles){ 698a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) u32 tu; 699a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) struct os_time now, passed; 700a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) os_get_time(&now); 701a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) os_time_sub(&now, &sta->sa_query_start, &passed); 702a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) tu = (passed.sec * 1000000 + passed.usec) / 1024; 703a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (hapd->conf->assoc_sa_query_max_timeout < tu) { 704a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) hostapd_logger(hapd, sta->addr, 705a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch HOSTAPD_MODULE_IEEE80211, 706a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) HOSTAPD_LEVEL_DEBUG, 707a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "association SA Query timed out"); 708a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sta->sa_query_timed_out = 1; 709a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) os_free(sta->sa_query_trans_id); 7105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sta->sa_query_trans_id = NULL; 711a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sta->sa_query_count = 0; 712a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) eloop_cancel_timeout(ap_sa_query_timer, hapd, sta); 713a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return 1; 714a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 715a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 716a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return 0; 7174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 7184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 719f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 7204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)static void ap_sa_query_timer(void *eloop_ctx, void *timeout_ctx) 721a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles){ 722a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) struct hostapd_data *hapd = eloop_ctx; 723a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) struct sta_info *sta = timeout_ctx; 724a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) unsigned int timeout, sec, usec; 725a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) u8 *trans_id, *nbuf; 7264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (sta->sa_query_count > 0 && 7284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ap_check_sa_query_timeout(hapd, sta)) 7294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 7304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) nbuf = os_realloc(sta->sa_query_trans_id, 7324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) (sta->sa_query_count + 1) * WLAN_SA_QUERY_TR_ID_LEN); 7334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (nbuf == NULL) 7344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 7354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (sta->sa_query_count == 0) { 7364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) /* Starting a new SA Query procedure */ 7374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) os_get_time(&sta->sa_query_start); 7385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 7394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) trans_id = nbuf + sta->sa_query_count * WLAN_SA_QUERY_TR_ID_LEN; 740a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sta->sa_query_trans_id = nbuf; 741f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) sta->sa_query_count++; 742a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 743f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN); 7444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) timeout = hapd->conf->assoc_sa_query_retry_timeout; 7464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sec = ((timeout / 1000) * 1024) / 1000; 7474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) usec = (timeout % 1000) * 1024; 7485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) eloop_register_timeout(sec, usec, ap_sa_query_timer, hapd, sta); 7494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, 7514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) HOSTAPD_LEVEL_DEBUG, 7524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "association SA Query attempt %d", sta->sa_query_count); 7534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#ifdef NEED_AP_MLME 7554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ieee802_11_send_sa_query_req(hapd, sta->addr, trans_id); 7565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif /* NEED_AP_MLME */ 7574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 7584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ap_sta_start_sa_query(struct hostapd_data *hapd, struct sta_info *sta) 7610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles){ 7620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) ap_sa_query_timer(hapd, sta); 7634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 764c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 765c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 766effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ap_sta_stop_sa_query(struct hostapd_data *hapd, struct sta_info *sta) 7675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){ 768c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch eloop_cancel_timeout(ap_sa_query_timer, hapd, sta); 7694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) os_free(sta->sa_query_trans_id); 770c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch sta->sa_query_trans_id = NULL; 7714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sta->sa_query_count = 0; 772c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 7735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 774c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#endif /* CONFIG_IEEE80211W */ 7754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ap_sta_set_authorized(struct hostapd_data *hapd, struct sta_info *sta, 7784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int authorized) 779c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch{ 7804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const u8 *dev_addr = NULL; 7814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!!authorized == !!(sta->flags & WLAN_STA_AUTHORIZED)) 7824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 7834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#ifdef CONFIG_P2P 7854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) dev_addr = p2p_group_get_dev_addr(hapd->p2p_group, sta->addr); 7864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif /* CONFIG_P2P */ 7874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 788f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (authorized) { 789c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (dev_addr) 7901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED 7910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) MACSTR " p2p_dev_addr=" MACSTR, 792effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch MAC2STR(sta->addr), MAC2STR(dev_addr)); 793c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch else 794c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED 795c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch MACSTR, MAC2STR(sta->addr)); 7960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (hapd->msg_ctx_parent && 797c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch hapd->msg_ctx_parent != hapd->msg_ctx && dev_addr) 798c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch wpa_msg(hapd->msg_ctx_parent, MSG_INFO, 7995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AP_STA_CONNECTED MACSTR " p2p_dev_addr=" 8000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) MACSTR, 801c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch MAC2STR(sta->addr), MAC2STR(dev_addr)); 8024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) else if (hapd->msg_ctx_parent && 8034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) hapd->msg_ctx_parent != hapd->msg_ctx) 804c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch wpa_msg(hapd->msg_ctx_parent, MSG_INFO, 805c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch AP_STA_CONNECTED MACSTR, MAC2STR(sta->addr)); 806c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 807c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch sta->flags |= WLAN_STA_AUTHORIZED; 808c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else { 809c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (dev_addr) 8104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED 8114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) MACSTR " p2p_dev_addr=" MACSTR, 8124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) MAC2STR(sta->addr), MAC2STR(dev_addr)); 813effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch else 8144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED 8150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) MACSTR, MAC2STR(sta->addr)); 8164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (hapd->msg_ctx_parent && 8174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) hapd->msg_ctx_parent != hapd->msg_ctx && dev_addr) 8185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) wpa_msg(hapd->msg_ctx_parent, MSG_INFO, 8194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AP_STA_DISCONNECTED MACSTR " p2p_dev_addr=" 8204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) MACSTR, MAC2STR(sta->addr), MAC2STR(dev_addr)); 8214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) else if (hapd->msg_ctx_parent && 8224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) hapd->msg_ctx_parent != hapd->msg_ctx) 8234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) wpa_msg(hapd->msg_ctx_parent, MSG_INFO, 8244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AP_STA_DISCONNECTED MACSTR, 8254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) MAC2STR(sta->addr)); 8264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sta->flags &= ~WLAN_STA_AUTHORIZED; 8274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 8284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 8294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (hapd->sta_authorized_cb) 830a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) hapd->sta_authorized_cb(hapd->sta_authorized_cb_ctx, 8314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sta->addr, authorized, dev_addr); 8324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 8334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 834a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 8354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void ap_sta_disconnect(struct hostapd_data *hapd, struct sta_info *sta, 8364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const u8 *addr, u16 reason) 837a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles){ 838a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 8394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (sta == NULL && addr) 8404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sta = ap_get_sta(hapd, addr); 8414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 842c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (addr) 8434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) hostapd_drv_sta_deauth(hapd, addr, reason); 844c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 8454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (sta == NULL) 8464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 847a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ap_sta_set_authorized(hapd, sta, 0); 8481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH); 8494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ieee802_1x_notify_port_enabled(sta->eapol_sm, 0); 8504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC); 8515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) eloop_cancel_timeout(ap_handle_timer, hapd, sta); 8524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) eloop_register_timeout(AP_MAX_INACTIVITY_AFTER_DEAUTH, 0, 853c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ap_handle_timer, hapd, sta); 8545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sta->timeout_next = STA_REMOVE; 8554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 8565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sta->deauth_reason = reason; 8574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) sta->flags |= WLAN_STA_PENDING_DEAUTH_CB; 8584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) eloop_cancel_timeout(ap_sta_deauth_cb_timeout, hapd, sta); 8594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) eloop_register_timeout(hapd->iface->drv_flags & 860c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS ? 2 : 0, 0, 8614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ap_sta_deauth_cb_timeout, hapd, sta); 8625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 8635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ap_sta_deauth_cb(struct hostapd_data *hapd, struct sta_info *sta) 8665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){ 8675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!(sta->flags & WLAN_STA_PENDING_DEAUTH_CB)) { 8685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) wpa_printf(MSG_DEBUG, "Ignore deauth cb for test frame"); 8694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 8704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 871f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) sta->flags &= ~WLAN_STA_PENDING_DEAUTH_CB; 8725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) eloop_cancel_timeout(ap_sta_deauth_cb_timeout, hapd, sta); 873f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ap_sta_deauth_cb_timeout(hapd, sta); 8745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 8755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 876f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 877f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void ap_sta_disassoc_cb(struct hostapd_data *hapd, struct sta_info *sta) 878c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch{ 8794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!(sta->flags & WLAN_STA_PENDING_DISASSOC_CB)) { 880c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch wpa_printf(MSG_DEBUG, "Ignore disassoc cb for test frame"); 8814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 8824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 883c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch sta->flags &= ~WLAN_STA_PENDING_DISASSOC_CB; 8844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) eloop_cancel_timeout(ap_sta_disassoc_cb_timeout, hapd, sta); 8854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ap_sta_disassoc_cb_timeout(hapd, sta); 8864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 887a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)