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 1475438200 Lines: 597 673 88.7 %
Date: 2016-10-02 Functions: 36 37 97.3 %

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

Generated by: LCOV version 1.10