LCOV - code coverage report
Current view: top level - src/ap - sta_info.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1401264779 Lines: 490 552 88.8 %
Date: 2014-05-28 Functions: 32 33 97.0 %

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

Generated by: LCOV version 1.10