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 1393793999 Lines: 323 552 58.5 %
Date: 2014-03-02 Functions: 26 33 78.8 %
Branches: 123 288 42.7 %

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

Generated by: LCOV version 1.9