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

Generated by: LCOV version 1.10