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 1443382998 Lines: 520 592 87.8 %
Date: 2015-09-27 Functions: 33 34 97.1 %

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

Generated by: LCOV version 1.10