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

Generated by: LCOV version 1.9