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

Generated by: LCOV version 1.10