LCOV - code coverage report
Current view: top level - src/ap - hostapd.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1443382998 Lines: 1256 1501 83.7 %
Date: 2015-09-27 Functions: 71 74 95.9 %

          Line data    Source code
       1             : /*
       2             :  * hostapd / Initialization and configuration
       3             :  * Copyright (c) 2002-2014, 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 "radius/radius_client.h"
      16             : #include "radius/radius_das.h"
      17             : #include "eap_server/tncs.h"
      18             : #include "eapol_auth/eapol_auth_sm.h"
      19             : #include "eapol_auth/eapol_auth_sm_i.h"
      20             : #include "fst/fst.h"
      21             : #include "hostapd.h"
      22             : #include "authsrv.h"
      23             : #include "sta_info.h"
      24             : #include "accounting.h"
      25             : #include "ap_list.h"
      26             : #include "beacon.h"
      27             : #include "iapp.h"
      28             : #include "ieee802_1x.h"
      29             : #include "ieee802_11_auth.h"
      30             : #include "vlan_init.h"
      31             : #include "wpa_auth.h"
      32             : #include "wps_hostapd.h"
      33             : #include "hw_features.h"
      34             : #include "wpa_auth_glue.h"
      35             : #include "ap_drv_ops.h"
      36             : #include "ap_config.h"
      37             : #include "p2p_hostapd.h"
      38             : #include "gas_serv.h"
      39             : #include "dfs.h"
      40             : #include "ieee802_11.h"
      41             : #include "bss_load.h"
      42             : #include "x_snoop.h"
      43             : #include "dhcp_snoop.h"
      44             : #include "ndisc_snoop.h"
      45             : 
      46             : 
      47             : static int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason);
      48             : static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd);
      49             : static int hostapd_broadcast_wep_clear(struct hostapd_data *hapd);
      50             : static int setup_interface2(struct hostapd_iface *iface);
      51             : static void channel_list_update_timeout(void *eloop_ctx, void *timeout_ctx);
      52             : 
      53             : 
      54        5039 : int hostapd_for_each_interface(struct hapd_interfaces *interfaces,
      55             :                                int (*cb)(struct hostapd_iface *iface,
      56             :                                          void *ctx), void *ctx)
      57             : {
      58             :         size_t i;
      59             :         int ret;
      60             : 
      61       11097 :         for (i = 0; i < interfaces->count; i++) {
      62        6328 :                 ret = cb(interfaces->iface[i], ctx);
      63        6328 :                 if (ret)
      64         270 :                         return ret;
      65             :         }
      66             : 
      67        4769 :         return 0;
      68             : }
      69             : 
      70             : 
      71          22 : static void hostapd_reload_bss(struct hostapd_data *hapd)
      72             : {
      73             :         struct hostapd_ssid *ssid;
      74             : 
      75             : #ifndef CONFIG_NO_RADIUS
      76          22 :         radius_client_reconfig(hapd->radius, hapd->conf->radius);
      77             : #endif /* CONFIG_NO_RADIUS */
      78             : 
      79          22 :         ssid = &hapd->conf->ssid;
      80          22 :         if (!ssid->wpa_psk_set && ssid->wpa_psk && !ssid->wpa_psk->next &&
      81           3 :             ssid->wpa_passphrase_set && ssid->wpa_passphrase) {
      82             :                 /*
      83             :                  * Force PSK to be derived again since SSID or passphrase may
      84             :                  * have changed.
      85             :                  */
      86           3 :                 hostapd_config_clear_wpa_psk(&hapd->conf->ssid.wpa_psk);
      87             :         }
      88          22 :         if (hostapd_setup_wpa_psk(hapd->conf)) {
      89           0 :                 wpa_printf(MSG_ERROR, "Failed to re-configure WPA PSK "
      90             :                            "after reloading configuration");
      91             :         }
      92             : 
      93          22 :         if (hapd->conf->ieee802_1x || hapd->conf->wpa)
      94          18 :                 hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 1);
      95             :         else
      96           4 :                 hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 0);
      97             : 
      98          22 :         if ((hapd->conf->wpa || hapd->conf->osen) && hapd->wpa_auth == NULL) {
      99          16 :                 hostapd_setup_wpa(hapd);
     100          32 :                 if (hapd->wpa_auth)
     101          16 :                         wpa_init_keys(hapd->wpa_auth);
     102           6 :         } else if (hapd->conf->wpa) {
     103             :                 const u8 *wpa_ie;
     104             :                 size_t wpa_ie_len;
     105           2 :                 hostapd_reconfig_wpa(hapd);
     106           2 :                 wpa_ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &wpa_ie_len);
     107           2 :                 if (hostapd_set_generic_elem(hapd, wpa_ie, wpa_ie_len))
     108           0 :                         wpa_printf(MSG_ERROR, "Failed to configure WPA IE for "
     109             :                                    "the kernel driver.");
     110           4 :         } else if (hapd->wpa_auth) {
     111           3 :                 wpa_deinit(hapd->wpa_auth);
     112           3 :                 hapd->wpa_auth = NULL;
     113           3 :                 hostapd_set_privacy(hapd, 0);
     114           3 :                 hostapd_setup_encryption(hapd->conf->iface, hapd);
     115           3 :                 hostapd_set_generic_elem(hapd, (u8 *) "", 0);
     116             :         }
     117             : 
     118          22 :         ieee802_11_set_beacon(hapd);
     119          22 :         hostapd_update_wps(hapd);
     120             : 
     121          44 :         if (hapd->conf->ssid.ssid_set &&
     122          22 :             hostapd_set_ssid(hapd, hapd->conf->ssid.ssid,
     123          22 :                              hapd->conf->ssid.ssid_len)) {
     124           0 :                 wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver");
     125             :                 /* try to continue */
     126             :         }
     127          22 :         wpa_printf(MSG_DEBUG, "Reconfigured interface %s", hapd->conf->iface);
     128          22 : }
     129             : 
     130             : 
     131          22 : static void hostapd_clear_old(struct hostapd_iface *iface)
     132             : {
     133             :         size_t j;
     134             : 
     135             :         /*
     136             :          * Deauthenticate all stations since the new configuration may not
     137             :          * allow them to use the BSS anymore.
     138             :          */
     139          44 :         for (j = 0; j < iface->num_bss; j++) {
     140          22 :                 hostapd_flush_old_stations(iface->bss[j],
     141             :                                            WLAN_REASON_PREV_AUTH_NOT_VALID);
     142          22 :                 hostapd_broadcast_wep_clear(iface->bss[j]);
     143             : 
     144             : #ifndef CONFIG_NO_RADIUS
     145             :                 /* TODO: update dynamic data based on changed configuration
     146             :                  * items (e.g., open/close sockets, etc.) */
     147          22 :                 radius_client_flush(iface->bss[j]->radius, 0);
     148             : #endif /* CONFIG_NO_RADIUS */
     149             :         }
     150          22 : }
     151             : 
     152             : 
     153          20 : int hostapd_reload_config(struct hostapd_iface *iface)
     154             : {
     155          20 :         struct hostapd_data *hapd = iface->bss[0];
     156             :         struct hostapd_config *newconf, *oldconf;
     157             :         size_t j;
     158             : 
     159          20 :         if (iface->config_fname == NULL) {
     160             :                 /* Only in-memory config in use - assume it has been updated */
     161          19 :                 hostapd_clear_old(iface);
     162          38 :                 for (j = 0; j < iface->num_bss; j++)
     163          19 :                         hostapd_reload_bss(iface->bss[j]);
     164          19 :                 return 0;
     165             :         }
     166             : 
     167           2 :         if (iface->interfaces == NULL ||
     168           1 :             iface->interfaces->config_read_cb == NULL)
     169           0 :                 return -1;
     170           1 :         newconf = iface->interfaces->config_read_cb(iface->config_fname);
     171           1 :         if (newconf == NULL)
     172           0 :                 return -1;
     173             : 
     174           1 :         hostapd_clear_old(iface);
     175             : 
     176           1 :         oldconf = hapd->iconf;
     177           1 :         iface->conf = newconf;
     178             : 
     179           2 :         for (j = 0; j < iface->num_bss; j++) {
     180           1 :                 hapd = iface->bss[j];
     181           1 :                 hapd->iconf = newconf;
     182           1 :                 hapd->iconf->channel = oldconf->channel;
     183           1 :                 hapd->iconf->acs = oldconf->acs;
     184           1 :                 hapd->iconf->secondary_channel = oldconf->secondary_channel;
     185           1 :                 hapd->iconf->ieee80211n = oldconf->ieee80211n;
     186           1 :                 hapd->iconf->ieee80211ac = oldconf->ieee80211ac;
     187           1 :                 hapd->iconf->ht_capab = oldconf->ht_capab;
     188           1 :                 hapd->iconf->vht_capab = oldconf->vht_capab;
     189           1 :                 hapd->iconf->vht_oper_chwidth = oldconf->vht_oper_chwidth;
     190           2 :                 hapd->iconf->vht_oper_centr_freq_seg0_idx =
     191           1 :                         oldconf->vht_oper_centr_freq_seg0_idx;
     192           2 :                 hapd->iconf->vht_oper_centr_freq_seg1_idx =
     193           1 :                         oldconf->vht_oper_centr_freq_seg1_idx;
     194           1 :                 hapd->conf = newconf->bss[j];
     195           1 :                 hostapd_reload_bss(hapd);
     196             :         }
     197             : 
     198           1 :         hostapd_config_free(oldconf);
     199             : 
     200             : 
     201           1 :         return 0;
     202             : }
     203             : 
     204             : 
     205        2172 : static void hostapd_broadcast_key_clear_iface(struct hostapd_data *hapd,
     206             :                                               char *ifname)
     207             : {
     208             :         int i;
     209             : 
     210       10860 :         for (i = 0; i < NUM_WEP_KEYS; i++) {
     211        8688 :                 if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE, NULL, i,
     212             :                                         0, NULL, 0, NULL, 0)) {
     213          12 :                         wpa_printf(MSG_DEBUG, "Failed to clear default "
     214             :                                    "encryption keys (ifname=%s keyidx=%d)",
     215             :                                    ifname, i);
     216             :                 }
     217             :         }
     218             : #ifdef CONFIG_IEEE80211W
     219        2172 :         if (hapd->conf->ieee80211w) {
     220         510 :                 for (i = NUM_WEP_KEYS; i < NUM_WEP_KEYS + 2; i++) {
     221         340 :                         if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE,
     222             :                                                 NULL, i, 0, NULL,
     223             :                                                 0, NULL, 0)) {
     224           0 :                                 wpa_printf(MSG_DEBUG, "Failed to clear "
     225             :                                            "default mgmt encryption keys "
     226             :                                            "(ifname=%s keyidx=%d)", ifname, i);
     227             :                         }
     228             :                 }
     229             :         }
     230             : #endif /* CONFIG_IEEE80211W */
     231        2172 : }
     232             : 
     233             : 
     234        2172 : static int hostapd_broadcast_wep_clear(struct hostapd_data *hapd)
     235             : {
     236        2172 :         hostapd_broadcast_key_clear_iface(hapd, hapd->conf->iface);
     237        2172 :         return 0;
     238             : }
     239             : 
     240             : 
     241        2058 : static int hostapd_broadcast_wep_set(struct hostapd_data *hapd)
     242             : {
     243        2058 :         int errors = 0, idx;
     244        2058 :         struct hostapd_ssid *ssid = &hapd->conf->ssid;
     245             : 
     246        2058 :         idx = ssid->wep.idx;
     247        2061 :         if (ssid->wep.default_len &&
     248           6 :             hostapd_drv_set_key(hapd->conf->iface,
     249             :                                 hapd, WPA_ALG_WEP, broadcast_ether_addr, idx,
     250           3 :                                 1, NULL, 0, ssid->wep.key[idx],
     251             :                                 ssid->wep.len[idx])) {
     252           3 :                 wpa_printf(MSG_WARNING, "Could not set WEP encryption.");
     253           3 :                 errors++;
     254             :         }
     255             : 
     256        2058 :         return errors;
     257             : }
     258             : 
     259             : 
     260        2267 : static void hostapd_free_hapd_data(struct hostapd_data *hapd)
     261             : {
     262        2267 :         os_free(hapd->probereq_cb);
     263        2267 :         hapd->probereq_cb = NULL;
     264        2267 :         hapd->num_probereq_cb = 0;
     265             : 
     266             : #ifdef CONFIG_P2P
     267         373 :         wpabuf_free(hapd->p2p_beacon_ie);
     268         373 :         hapd->p2p_beacon_ie = NULL;
     269         373 :         wpabuf_free(hapd->p2p_probe_resp_ie);
     270         373 :         hapd->p2p_probe_resp_ie = NULL;
     271             : #endif /* CONFIG_P2P */
     272             : 
     273        2267 :         if (!hapd->started) {
     274         212 :                 wpa_printf(MSG_ERROR, "%s: Interface %s wasn't started",
     275         212 :                            __func__, hapd->conf->iface);
     276        2479 :                 return;
     277             :         }
     278        2055 :         hapd->started = 0;
     279             : 
     280        2055 :         wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface);
     281        2055 :         iapp_deinit(hapd->iapp);
     282        2055 :         hapd->iapp = NULL;
     283        2055 :         accounting_deinit(hapd);
     284        2055 :         hostapd_deinit_wpa(hapd);
     285        2055 :         vlan_deinit(hapd);
     286        2055 :         hostapd_acl_deinit(hapd);
     287             : #ifndef CONFIG_NO_RADIUS
     288        1682 :         radius_client_deinit(hapd->radius);
     289        1682 :         hapd->radius = NULL;
     290        1682 :         radius_das_deinit(hapd->radius_das);
     291        1682 :         hapd->radius_das = NULL;
     292             : #endif /* CONFIG_NO_RADIUS */
     293             : 
     294        2055 :         hostapd_deinit_wps(hapd);
     295             : 
     296        2055 :         authsrv_deinit(hapd);
     297             : 
     298        2055 :         if (hapd->interface_added) {
     299          43 :                 hapd->interface_added = 0;
     300          43 :                 if (hostapd_if_remove(hapd, WPA_IF_AP_BSS, hapd->conf->iface)) {
     301           0 :                         wpa_printf(MSG_WARNING,
     302             :                                    "Failed to remove BSS interface %s",
     303           0 :                                    hapd->conf->iface);
     304           0 :                         hapd->interface_added = 1;
     305             :                 } else {
     306             :                         /*
     307             :                          * Since this was a dynamically added interface, the
     308             :                          * driver wrapper may have removed its internal instance
     309             :                          * and hapd->drv_priv is not valid anymore.
     310             :                          */
     311          43 :                         hapd->drv_priv = NULL;
     312             :                 }
     313             :         }
     314             : 
     315        2055 :         wpabuf_free(hapd->time_adv);
     316             : 
     317             : #ifdef CONFIG_INTERWORKING
     318        2055 :         gas_serv_deinit(hapd);
     319             : #endif /* CONFIG_INTERWORKING */
     320             : 
     321        2055 :         bss_load_update_deinit(hapd);
     322        2055 :         ndisc_snoop_deinit(hapd);
     323        2055 :         dhcp_snoop_deinit(hapd);
     324        2055 :         x_snoop_deinit(hapd);
     325             : 
     326             : #ifdef CONFIG_SQLITE
     327        1682 :         bin_clear_free(hapd->tmp_eap_user.identity,
     328             :                        hapd->tmp_eap_user.identity_len);
     329        1682 :         bin_clear_free(hapd->tmp_eap_user.password,
     330             :                        hapd->tmp_eap_user.password_len);
     331             : #endif /* CONFIG_SQLITE */
     332             : 
     333             : #ifdef CONFIG_MESH
     334         373 :         wpabuf_free(hapd->mesh_pending_auth);
     335         373 :         hapd->mesh_pending_auth = NULL;
     336             : #endif /* CONFIG_MESH */
     337             : }
     338             : 
     339             : 
     340             : /**
     341             :  * hostapd_cleanup - Per-BSS cleanup (deinitialization)
     342             :  * @hapd: Pointer to BSS data
     343             :  *
     344             :  * This function is used to free all per-BSS data structures and resources.
     345             :  * Most of the modules that are initialized in hostapd_setup_bss() are
     346             :  * deinitialized here.
     347             :  */
     348        2123 : static void hostapd_cleanup(struct hostapd_data *hapd)
     349             : {
     350        2123 :         wpa_printf(MSG_DEBUG, "%s(hapd=%p (%s))", __func__, hapd,
     351        2123 :                    hapd->conf->iface);
     352        3873 :         if (hapd->iface->interfaces &&
     353        1750 :             hapd->iface->interfaces->ctrl_iface_deinit)
     354        1750 :                 hapd->iface->interfaces->ctrl_iface_deinit(hapd);
     355        2123 :         hostapd_free_hapd_data(hapd);
     356        2123 : }
     357             : 
     358             : 
     359        2235 : static void sta_track_deinit(struct hostapd_iface *iface)
     360             : {
     361             :         struct hostapd_sta_info *info;
     362             : 
     363        2235 :         if (!iface->num_sta_seen)
     364        4463 :                 return;
     365             : 
     366          23 :         while ((info = dl_list_first(&iface->sta_seen, struct hostapd_sta_info,
     367             :                                      list))) {
     368           9 :                 dl_list_del(&info->list);
     369           9 :                 iface->num_sta_seen--;
     370           9 :                 os_free(info);
     371             :         }
     372             : }
     373             : 
     374             : 
     375        2235 : static void hostapd_cleanup_iface_partial(struct hostapd_iface *iface)
     376             : {
     377        2235 :         wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
     378             : #ifdef CONFIG_IEEE80211N
     379             : #ifdef NEED_AP_MLME
     380        2235 :         hostapd_stop_setup_timers(iface);
     381             : #endif /* NEED_AP_MLME */
     382             : #endif /* CONFIG_IEEE80211N */
     383        2235 :         hostapd_free_hw_features(iface->hw_features, iface->num_hw_features);
     384        2235 :         iface->hw_features = NULL;
     385        2235 :         os_free(iface->current_rates);
     386        2235 :         iface->current_rates = NULL;
     387        2235 :         os_free(iface->basic_rates);
     388        2235 :         iface->basic_rates = NULL;
     389        2235 :         ap_list_deinit(iface);
     390        2235 :         sta_track_deinit(iface);
     391        2235 : }
     392             : 
     393             : 
     394             : /**
     395             :  * hostapd_cleanup_iface - Complete per-interface cleanup
     396             :  * @iface: Pointer to interface data
     397             :  *
     398             :  * This function is called after per-BSS data structures are deinitialized
     399             :  * with hostapd_cleanup().
     400             :  */
     401        2106 : static void hostapd_cleanup_iface(struct hostapd_iface *iface)
     402             : {
     403        2106 :         wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
     404        2106 :         eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
     405             : 
     406        2106 :         hostapd_cleanup_iface_partial(iface);
     407        2106 :         hostapd_config_free(iface->conf);
     408        2106 :         iface->conf = NULL;
     409             : 
     410        2106 :         os_free(iface->config_fname);
     411        2106 :         os_free(iface->bss);
     412        2106 :         wpa_printf(MSG_DEBUG, "%s: free iface=%p", __func__, iface);
     413        2106 :         os_free(iface);
     414        2106 : }
     415             : 
     416             : 
     417        2259 : static void hostapd_clear_wep(struct hostapd_data *hapd)
     418             : {
     419        2259 :         if (hapd->drv_priv && !hapd->iface->driver_ap_teardown) {
     420          95 :                 hostapd_set_privacy(hapd, 0);
     421          95 :                 hostapd_broadcast_wep_clear(hapd);
     422             :         }
     423        2259 : }
     424             : 
     425             : 
     426        2058 : static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd)
     427             : {
     428             :         int i;
     429             : 
     430        2058 :         hostapd_broadcast_wep_set(hapd);
     431             : 
     432        2058 :         if (hapd->conf->ssid.wep.default_len) {
     433           3 :                 hostapd_set_privacy(hapd, 1);
     434           3 :                 return 0;
     435             :         }
     436             : 
     437             :         /*
     438             :          * When IEEE 802.1X is not enabled, the driver may need to know how to
     439             :          * set authentication algorithms for static WEP.
     440             :          */
     441        2055 :         hostapd_drv_set_authmode(hapd, hapd->conf->auth_algs);
     442             : 
     443       10275 :         for (i = 0; i < 4; i++) {
     444        8235 :                 if (hapd->conf->ssid.wep.key[i] &&
     445          30 :                     hostapd_drv_set_key(iface, hapd, WPA_ALG_WEP, NULL, i,
     446          15 :                                         i == hapd->conf->ssid.wep.idx, NULL, 0,
     447          15 :                                         hapd->conf->ssid.wep.key[i],
     448          15 :                                         hapd->conf->ssid.wep.len[i])) {
     449           0 :                         wpa_printf(MSG_WARNING, "Could not set WEP "
     450             :                                    "encryption.");
     451           0 :                         return -1;
     452             :                 }
     453        8235 :                 if (hapd->conf->ssid.wep.key[i] &&
     454          15 :                     i == hapd->conf->ssid.wep.idx)
     455          13 :                         hostapd_set_privacy(hapd, 1);
     456             :         }
     457             : 
     458        2055 :         return 0;
     459             : }
     460             : 
     461             : 
     462        3998 : static int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason)
     463             : {
     464        3998 :         int ret = 0;
     465             :         u8 addr[ETH_ALEN];
     466             : 
     467        3998 :         if (hostapd_drv_none(hapd) || hapd->drv_priv == NULL)
     468         221 :                 return 0;
     469             : 
     470        3777 :         if (!hapd->iface->driver_ap_teardown) {
     471        1810 :                 wpa_dbg(hapd->msg_ctx, MSG_DEBUG,
     472             :                         "Flushing old station entries");
     473             : 
     474        1810 :                 if (hostapd_flush(hapd)) {
     475          33 :                         wpa_msg(hapd->msg_ctx, MSG_WARNING,
     476             :                                 "Could not connect to kernel driver");
     477          33 :                         ret = -1;
     478             :                 }
     479             :         }
     480        3777 :         wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "Deauthenticate all stations");
     481        3777 :         os_memset(addr, 0xff, ETH_ALEN);
     482        3777 :         hostapd_drv_sta_deauth(hapd, addr, reason);
     483        3777 :         hostapd_free_stas(hapd);
     484             : 
     485        3777 :         return ret;
     486             : }
     487             : 
     488             : 
     489        2259 : static void hostapd_bss_deinit_no_free(struct hostapd_data *hapd)
     490             : {
     491        2259 :         hostapd_free_stas(hapd);
     492        2259 :         hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING);
     493        2259 :         hostapd_clear_wep(hapd);
     494        2259 : }
     495             : 
     496             : 
     497             : /**
     498             :  * hostapd_validate_bssid_configuration - Validate BSSID configuration
     499             :  * @iface: Pointer to interface data
     500             :  * Returns: 0 on success, -1 on failure
     501             :  *
     502             :  * This function is used to validate that the configured BSSIDs are valid.
     503             :  */
     504        2023 : static int hostapd_validate_bssid_configuration(struct hostapd_iface *iface)
     505             : {
     506        2023 :         u8 mask[ETH_ALEN] = { 0 };
     507        2023 :         struct hostapd_data *hapd = iface->bss[0];
     508        2023 :         unsigned int i = iface->conf->num_bss, bits = 0, j;
     509        2023 :         int auto_addr = 0;
     510             : 
     511        2023 :         if (hostapd_drv_none(hapd))
     512          12 :                 return 0;
     513             : 
     514             :         /* Generate BSSID mask that is large enough to cover the BSSIDs. */
     515             : 
     516             :         /* Determine the bits necessary to cover the number of BSSIDs. */
     517        2023 :         for (i--; i; i >>= 1)
     518          12 :                 bits++;
     519             : 
     520             :         /* Determine the bits necessary to any configured BSSIDs,
     521             :            if they are higher than the number of BSSIDs. */
     522        4034 :         for (j = 0; j < iface->conf->num_bss; j++) {
     523        2023 :                 if (hostapd_mac_comp_empty(iface->conf->bss[j]->bssid) == 0) {
     524        1967 :                         if (j)
     525           4 :                                 auto_addr++;
     526        1967 :                         continue;
     527             :                 }
     528             : 
     529         392 :                 for (i = 0; i < ETH_ALEN; i++) {
     530         672 :                         mask[i] |=
     531         336 :                                 iface->conf->bss[j]->bssid[i] ^
     532         336 :                                 hapd->own_addr[i];
     533             :                 }
     534             :         }
     535             : 
     536        2011 :         if (!auto_addr)
     537        2007 :                 goto skip_mask_ext;
     538             : 
     539           4 :         for (i = 0; i < ETH_ALEN && mask[i] == 0; i++)
     540             :                 ;
     541           4 :         j = 0;
     542           4 :         if (i < ETH_ALEN) {
     543           0 :                 j = (5 - i) * 8;
     544             : 
     545           0 :                 while (mask[i] != 0) {
     546           0 :                         mask[i] >>= 1;
     547           0 :                         j++;
     548             :                 }
     549             :         }
     550             : 
     551           4 :         if (bits < j)
     552           0 :                 bits = j;
     553             : 
     554           4 :         if (bits > 40) {
     555           0 :                 wpa_printf(MSG_ERROR, "Too many bits in the BSSID mask (%u)",
     556             :                            bits);
     557           0 :                 return -1;
     558             :         }
     559             : 
     560           4 :         os_memset(mask, 0xff, ETH_ALEN);
     561           4 :         j = bits / 8;
     562           4 :         for (i = 5; i > 5 - j; i--)
     563           0 :                 mask[i] = 0;
     564           4 :         j = bits % 8;
     565          12 :         while (j--)
     566           4 :                 mask[i] <<= 1;
     567             : 
     568             : skip_mask_ext:
     569       14077 :         wpa_printf(MSG_DEBUG, "BSS count %lu, BSSID mask " MACSTR " (%d bits)",
     570       14077 :                    (unsigned long) iface->conf->num_bss, MAC2STR(mask), bits);
     571             : 
     572        2011 :         if (!auto_addr)
     573        2007 :                 return 0;
     574             : 
     575          28 :         for (i = 0; i < ETH_ALEN; i++) {
     576          24 :                 if ((hapd->own_addr[i] & mask[i]) != hapd->own_addr[i]) {
     577           0 :                         wpa_printf(MSG_ERROR, "Invalid BSSID mask " MACSTR
     578             :                                    " for start address " MACSTR ".",
     579           0 :                                    MAC2STR(mask), MAC2STR(hapd->own_addr));
     580           0 :                         wpa_printf(MSG_ERROR, "Start address must be the "
     581             :                                    "first address in the block (i.e., addr "
     582             :                                    "AND mask == addr).");
     583           0 :                         return -1;
     584             :                 }
     585             :         }
     586             : 
     587           4 :         return 0;
     588             : }
     589             : 
     590             : 
     591           0 : static int mac_in_conf(struct hostapd_config *conf, const void *a)
     592             : {
     593             :         size_t i;
     594             : 
     595           0 :         for (i = 0; i < conf->num_bss; i++) {
     596           0 :                 if (hostapd_mac_comp(conf->bss[i]->bssid, a) == 0) {
     597           0 :                         return 1;
     598             :                 }
     599             :         }
     600             : 
     601           0 :         return 0;
     602             : }
     603             : 
     604             : 
     605             : #ifndef CONFIG_NO_RADIUS
     606             : 
     607          22 : static int hostapd_das_nas_mismatch(struct hostapd_data *hapd,
     608             :                                     struct radius_das_attrs *attr)
     609             : {
     610          33 :         if (attr->nas_identifier &&
     611          22 :             (!hapd->conf->nas_identifier ||
     612          11 :              os_strlen(hapd->conf->nas_identifier) !=
     613          21 :              attr->nas_identifier_len ||
     614          10 :              os_memcmp(hapd->conf->nas_identifier, attr->nas_identifier,
     615             :                        attr->nas_identifier_len) != 0)) {
     616           1 :                 wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-Identifier mismatch");
     617           1 :                 return 1;
     618             :         }
     619             : 
     620          30 :         if (attr->nas_ip_addr &&
     621          18 :             (hapd->conf->own_ip_addr.af != AF_INET ||
     622           9 :              os_memcmp(&hapd->conf->own_ip_addr.u.v4, attr->nas_ip_addr, 4) !=
     623             :              0)) {
     624           1 :                 wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-IP-Address mismatch");
     625           1 :                 return 1;
     626             :         }
     627             : 
     628             : #ifdef CONFIG_IPV6
     629          20 :         if (attr->nas_ipv6_addr &&
     630           0 :             (hapd->conf->own_ip_addr.af != AF_INET6 ||
     631           0 :              os_memcmp(&hapd->conf->own_ip_addr.u.v6, attr->nas_ipv6_addr, 16)
     632             :              != 0)) {
     633           0 :                 wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-IPv6-Address mismatch");
     634           0 :                 return 1;
     635             :         }
     636             : #endif /* CONFIG_IPV6 */
     637             : 
     638          20 :         return 0;
     639             : }
     640             : 
     641             : 
     642          20 : static struct sta_info * hostapd_das_find_sta(struct hostapd_data *hapd,
     643             :                                               struct radius_das_attrs *attr,
     644             :                                               int *multi)
     645             : {
     646             :         struct sta_info *selected, *sta;
     647             :         char buf[128];
     648          20 :         int num_attr = 0;
     649             :         int count;
     650             : 
     651          20 :         *multi = 0;
     652             : 
     653          43 :         for (sta = hapd->sta_list; sta; sta = sta->next)
     654          23 :                 sta->radius_das_match = 1;
     655             : 
     656          20 :         if (attr->sta_addr) {
     657           6 :                 num_attr++;
     658           6 :                 sta = ap_get_sta(hapd, attr->sta_addr);
     659           6 :                 if (!sta) {
     660           3 :                         wpa_printf(MSG_DEBUG,
     661             :                                    "RADIUS DAS: No Calling-Station-Id match");
     662           3 :                         return NULL;
     663             :                 }
     664             : 
     665           3 :                 selected = sta;
     666           8 :                 for (sta = hapd->sta_list; sta; sta = sta->next) {
     667           5 :                         if (sta != selected)
     668           2 :                                 sta->radius_das_match = 0;
     669             :                 }
     670           3 :                 wpa_printf(MSG_DEBUG, "RADIUS DAS: Calling-Station-Id match");
     671             :         }
     672             : 
     673          17 :         if (attr->acct_session_id) {
     674           3 :                 num_attr++;
     675           3 :                 if (attr->acct_session_id_len != 17) {
     676           1 :                         wpa_printf(MSG_DEBUG,
     677             :                                    "RADIUS DAS: Acct-Session-Id cannot match");
     678           1 :                         return NULL;
     679             :                 }
     680           2 :                 count = 0;
     681             : 
     682           4 :                 for (sta = hapd->sta_list; sta; sta = sta->next) {
     683           2 :                         if (!sta->radius_das_match)
     684           0 :                                 continue;
     685           2 :                         os_snprintf(buf, sizeof(buf), "%08X-%08X",
     686             :                                     sta->acct_session_id_hi,
     687             :                                     sta->acct_session_id_lo);
     688           2 :                         if (os_memcmp(attr->acct_session_id, buf, 17) != 0)
     689           1 :                                 sta->radius_das_match = 0;
     690             :                         else
     691           1 :                                 count++;
     692             :                 }
     693             : 
     694           2 :                 if (count == 0) {
     695           1 :                         wpa_printf(MSG_DEBUG,
     696             :                                    "RADIUS DAS: No matches remaining after Acct-Session-Id check");
     697           1 :                         return NULL;
     698             :                 }
     699           1 :                 wpa_printf(MSG_DEBUG, "RADIUS DAS: Acct-Session-Id match");
     700             :         }
     701             : 
     702          15 :         if (attr->acct_multi_session_id) {
     703           4 :                 num_attr++;
     704           4 :                 if (attr->acct_multi_session_id_len != 17) {
     705           1 :                         wpa_printf(MSG_DEBUG,
     706             :                                    "RADIUS DAS: Acct-Multi-Session-Id cannot match");
     707           1 :                         return NULL;
     708             :                 }
     709           3 :                 count = 0;
     710             : 
     711           7 :                 for (sta = hapd->sta_list; sta; sta = sta->next) {
     712           4 :                         if (!sta->radius_das_match)
     713           0 :                                 continue;
     714           8 :                         if (!sta->eapol_sm ||
     715           4 :                             !sta->eapol_sm->acct_multi_session_id_hi) {
     716           0 :                                 sta->radius_das_match = 0;
     717           0 :                                 continue;
     718             :                         }
     719           8 :                         os_snprintf(buf, sizeof(buf), "%08X+%08X",
     720           4 :                                     sta->eapol_sm->acct_multi_session_id_hi,
     721           4 :                                     sta->eapol_sm->acct_multi_session_id_lo);
     722           4 :                         if (os_memcmp(attr->acct_multi_session_id, buf, 17) !=
     723             :                             0)
     724           3 :                                 sta->radius_das_match = 0;
     725             :                         else
     726           1 :                                 count++;
     727             :                 }
     728             : 
     729           3 :                 if (count == 0) {
     730           2 :                         wpa_printf(MSG_DEBUG,
     731             :                                    "RADIUS DAS: No matches remaining after Acct-Multi-Session-Id check");
     732           2 :                         return NULL;
     733             :                 }
     734           1 :                 wpa_printf(MSG_DEBUG,
     735             :                            "RADIUS DAS: Acct-Multi-Session-Id match");
     736             :         }
     737             : 
     738          12 :         if (attr->cui) {
     739           3 :                 num_attr++;
     740           3 :                 count = 0;
     741             : 
     742           6 :                 for (sta = hapd->sta_list; sta; sta = sta->next) {
     743             :                         struct wpabuf *cui;
     744             : 
     745           3 :                         if (!sta->radius_das_match)
     746           0 :                                 continue;
     747           3 :                         cui = ieee802_1x_get_radius_cui(sta->eapol_sm);
     748           4 :                         if (!cui || wpabuf_len(cui) != attr->cui_len ||
     749           1 :                             os_memcmp(wpabuf_head(cui), attr->cui,
     750             :                                       attr->cui_len) != 0)
     751           2 :                                 sta->radius_das_match = 0;
     752             :                         else
     753           1 :                                 count++;
     754             :                 }
     755             : 
     756           3 :                 if (count == 0) {
     757           2 :                         wpa_printf(MSG_DEBUG,
     758             :                                    "RADIUS DAS: No matches remaining after Chargeable-User-Identity check");
     759           2 :                         return NULL;
     760             :                 }
     761           1 :                 wpa_printf(MSG_DEBUG,
     762             :                            "RADIUS DAS: Chargeable-User-Identity match");
     763             :         }
     764             : 
     765          10 :         if (attr->user_name) {
     766           5 :                 num_attr++;
     767           5 :                 count = 0;
     768             : 
     769          14 :                 for (sta = hapd->sta_list; sta; sta = sta->next) {
     770             :                         u8 *identity;
     771             :                         size_t identity_len;
     772             : 
     773           9 :                         if (!sta->radius_das_match)
     774           2 :                                 continue;
     775           7 :                         identity = ieee802_1x_get_identity(sta->eapol_sm,
     776             :                                                            &identity_len);
     777          14 :                         if (!identity ||
     778          11 :                             identity_len != attr->user_name_len ||
     779           4 :                             os_memcmp(identity, attr->user_name, identity_len)
     780             :                             != 0)
     781           3 :                                 sta->radius_das_match = 0;
     782             :                         else
     783           4 :                                 count++;
     784             :                 }
     785             : 
     786           5 :                 if (count == 0) {
     787           2 :                         wpa_printf(MSG_DEBUG,
     788             :                                    "RADIUS DAS: No matches remaining after User-Name check");
     789           2 :                         return NULL;
     790             :                 }
     791           3 :                 wpa_printf(MSG_DEBUG,
     792             :                            "RADIUS DAS: User-Name match");
     793             :         }
     794             : 
     795           8 :         if (num_attr == 0) {
     796             :                 /*
     797             :                  * In theory, we could match all current associations, but it
     798             :                  * seems safer to just reject requests that do not include any
     799             :                  * session identification attributes.
     800             :                  */
     801           1 :                 wpa_printf(MSG_DEBUG,
     802             :                            "RADIUS DAS: No session identification attributes included");
     803           1 :                 return NULL;
     804             :         }
     805             : 
     806           7 :         selected = NULL;
     807          18 :         for (sta = hapd->sta_list; sta; sta = sta->next) {
     808          12 :                 if (sta->radius_das_match) {
     809           8 :                         if (selected) {
     810           1 :                                 *multi = 1;
     811           1 :                                 return NULL;
     812             :                         }
     813           7 :                         selected = sta;
     814             :                 }
     815             :         }
     816             : 
     817           6 :         return selected;
     818             : }
     819             : 
     820             : 
     821          13 : static int hostapd_das_disconnect_pmksa(struct hostapd_data *hapd,
     822             :                                         struct radius_das_attrs *attr)
     823             : {
     824          13 :         if (!hapd->wpa_auth)
     825           0 :                 return -1;
     826          13 :         return wpa_auth_radius_das_disconnect_pmksa(hapd->wpa_auth, attr);
     827             : }
     828             : 
     829             : 
     830             : static enum radius_das_res
     831          22 : hostapd_das_disconnect(void *ctx, struct radius_das_attrs *attr)
     832             : {
     833          22 :         struct hostapd_data *hapd = ctx;
     834             :         struct sta_info *sta;
     835             :         int multi;
     836             : 
     837          22 :         if (hostapd_das_nas_mismatch(hapd, attr))
     838           2 :                 return RADIUS_DAS_NAS_MISMATCH;
     839             : 
     840          20 :         sta = hostapd_das_find_sta(hapd, attr, &multi);
     841          20 :         if (sta == NULL) {
     842          14 :                 if (multi) {
     843           1 :                         wpa_printf(MSG_DEBUG,
     844             :                                    "RADIUS DAS: Multiple sessions match - not supported");
     845           1 :                         return RADIUS_DAS_MULTI_SESSION_MATCH;
     846             :                 }
     847          13 :                 if (hostapd_das_disconnect_pmksa(hapd, attr) == 0) {
     848           4 :                         wpa_printf(MSG_DEBUG,
     849             :                                    "RADIUS DAS: PMKSA cache entry matched");
     850           4 :                         return RADIUS_DAS_SUCCESS;
     851             :                 }
     852           9 :                 wpa_printf(MSG_DEBUG, "RADIUS DAS: No matching session found");
     853           9 :                 return RADIUS_DAS_SESSION_NOT_FOUND;
     854             :         }
     855             : 
     856          36 :         wpa_printf(MSG_DEBUG, "RADIUS DAS: Found a matching session " MACSTR
     857          36 :                    " - disconnecting", MAC2STR(sta->addr));
     858           6 :         wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
     859             : 
     860           6 :         hostapd_drv_sta_deauth(hapd, sta->addr,
     861             :                                WLAN_REASON_PREV_AUTH_NOT_VALID);
     862           6 :         ap_sta_deauthenticate(hapd, sta, WLAN_REASON_PREV_AUTH_NOT_VALID);
     863             : 
     864           6 :         return RADIUS_DAS_SUCCESS;
     865             : }
     866             : 
     867             : #endif /* CONFIG_NO_RADIUS */
     868             : 
     869             : 
     870             : /**
     871             :  * hostapd_setup_bss - Per-BSS setup (initialization)
     872             :  * @hapd: Pointer to BSS data
     873             :  * @first: Whether this BSS is the first BSS of an interface; -1 = not first,
     874             :  *      but interface may exist
     875             :  *
     876             :  * This function is used to initialize all per-BSS data structures and
     877             :  * resources. This gets called in a loop for each BSS when an interface is
     878             :  * initialized. Most of the modules that are initialized here will be
     879             :  * deinitialized in hostapd_cleanup().
     880             :  */
     881        2055 : static int hostapd_setup_bss(struct hostapd_data *hapd, int first)
     882             : {
     883        2055 :         struct hostapd_bss_config *conf = hapd->conf;
     884             :         u8 ssid[SSID_MAX_LEN + 1];
     885             :         int ssid_len, set_ssid;
     886             :         char force_ifname[IFNAMSIZ];
     887             :         u8 if_addr[ETH_ALEN];
     888        2055 :         int flush_old_stations = 1;
     889             : 
     890        2055 :         wpa_printf(MSG_DEBUG, "%s(hapd=%p (%s), first=%d)",
     891        2055 :                    __func__, hapd, conf->iface, first);
     892             : 
     893             : #ifdef EAP_SERVER_TNC
     894        1682 :         if (conf->tnc && tncs_global_init() < 0) {
     895           0 :                 wpa_printf(MSG_ERROR, "Failed to initialize TNCS");
     896           0 :                 return -1;
     897             :         }
     898             : #endif /* EAP_SERVER_TNC */
     899             : 
     900        2055 :         if (hapd->started) {
     901           0 :                 wpa_printf(MSG_ERROR, "%s: Interface %s was already started",
     902           0 :                            __func__, conf->iface);
     903           0 :                 return -1;
     904             :         }
     905        2055 :         hapd->started = 1;
     906             : 
     907        2055 :         if (!first || first == -1) {
     908          43 :                 if (hostapd_mac_comp_empty(conf->bssid) == 0) {
     909             :                         /* Allocate the next available BSSID. */
     910             :                         do {
     911           0 :                                 inc_byte_array(hapd->own_addr, ETH_ALEN);
     912           0 :                         } while (mac_in_conf(hapd->iconf, hapd->own_addr));
     913             :                 } else {
     914             :                         /* Allocate the configured BSSID. */
     915          43 :                         os_memcpy(hapd->own_addr, conf->bssid, ETH_ALEN);
     916             : 
     917          43 :                         if (hostapd_mac_comp(hapd->own_addr,
     918          43 :                                              hapd->iface->bss[0]->own_addr) ==
     919             :                             0) {
     920           0 :                                 wpa_printf(MSG_ERROR, "BSS '%s' may not have "
     921             :                                            "BSSID set to the MAC address of "
     922           0 :                                            "the radio", conf->iface);
     923           0 :                                 return -1;
     924             :                         }
     925             :                 }
     926             : 
     927          43 :                 hapd->interface_added = 1;
     928         129 :                 if (hostapd_if_add(hapd->iface->bss[0], WPA_IF_AP_BSS,
     929          43 :                                    conf->iface, hapd->own_addr, hapd,
     930             :                                    &hapd->drv_priv, force_ifname, if_addr,
     931          43 :                                    conf->bridge[0] ? conf->bridge : NULL,
     932             :                                    first == -1)) {
     933           0 :                         wpa_printf(MSG_ERROR, "Failed to add BSS (BSSID="
     934           0 :                                    MACSTR ")", MAC2STR(hapd->own_addr));
     935           0 :                         hapd->interface_added = 0;
     936           0 :                         return -1;
     937             :                 }
     938             :         }
     939             : 
     940        2055 :         if (conf->wmm_enabled < 0)
     941        1683 :                 conf->wmm_enabled = hapd->iconf->ieee80211n;
     942             : 
     943             : #ifdef CONFIG_MESH
     944         373 :         if (hapd->iface->mconf == NULL)
     945         338 :                 flush_old_stations = 0;
     946             : #endif /* CONFIG_MESH */
     947             : 
     948        2055 :         if (flush_old_stations)
     949        1717 :                 hostapd_flush_old_stations(hapd,
     950             :                                            WLAN_REASON_PREV_AUTH_NOT_VALID);
     951        2055 :         hostapd_set_privacy(hapd, 0);
     952             : 
     953        2055 :         hostapd_broadcast_wep_clear(hapd);
     954        2055 :         if (hostapd_setup_encryption(conf->iface, hapd))
     955           0 :                 return -1;
     956             : 
     957             :         /*
     958             :          * Fetch the SSID from the system and use it or,
     959             :          * if one was specified in the config file, verify they
     960             :          * match.
     961             :          */
     962        2055 :         ssid_len = hostapd_get_ssid(hapd, ssid, sizeof(ssid));
     963        2055 :         if (ssid_len < 0) {
     964           0 :                 wpa_printf(MSG_ERROR, "Could not read SSID from system");
     965           0 :                 return -1;
     966             :         }
     967        2055 :         if (conf->ssid.ssid_set) {
     968             :                 /*
     969             :                  * If SSID is specified in the config file and it differs
     970             :                  * from what is being used then force installation of the
     971             :                  * new SSID.
     972             :                  */
     973        2008 :                 set_ssid = (conf->ssid.ssid_len != (size_t) ssid_len ||
     974           0 :                             os_memcmp(conf->ssid.ssid, ssid, ssid_len) != 0);
     975             :         } else {
     976             :                 /*
     977             :                  * No SSID in the config file; just use the one we got
     978             :                  * from the system.
     979             :                  */
     980          47 :                 set_ssid = 0;
     981          47 :                 conf->ssid.ssid_len = ssid_len;
     982          47 :                 os_memcpy(conf->ssid.ssid, ssid, conf->ssid.ssid_len);
     983             :         }
     984             : 
     985        2055 :         if (!hostapd_drv_none(hapd)) {
     986       18387 :                 wpa_printf(MSG_ERROR, "Using interface %s with hwaddr " MACSTR
     987             :                            " and ssid \"%s\"",
     988       14301 :                            conf->iface, MAC2STR(hapd->own_addr),
     989        2043 :                            wpa_ssid_txt(conf->ssid.ssid, conf->ssid.ssid_len));
     990             :         }
     991             : 
     992        2055 :         if (hostapd_setup_wpa_psk(conf)) {
     993           4 :                 wpa_printf(MSG_ERROR, "WPA-PSK setup failed.");
     994           4 :                 return -1;
     995             :         }
     996             : 
     997             :         /* Set SSID for the kernel driver (to be used in beacon and probe
     998             :          * response frames) */
     999        2051 :         if (set_ssid && hostapd_set_ssid(hapd, conf->ssid.ssid,
    1000             :                                          conf->ssid.ssid_len)) {
    1001           0 :                 wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver");
    1002           0 :                 return -1;
    1003             :         }
    1004             : 
    1005        2051 :         if (wpa_debug_level <= MSG_MSGDUMP)
    1006        2051 :                 conf->radius->msg_dumps = 1;
    1007             : #ifndef CONFIG_NO_RADIUS
    1008        1678 :         hapd->radius = radius_client_init(hapd, conf->radius);
    1009        1678 :         if (hapd->radius == NULL) {
    1010           0 :                 wpa_printf(MSG_ERROR, "RADIUS client initialization failed.");
    1011           0 :                 return -1;
    1012             :         }
    1013             : 
    1014        1678 :         if (conf->radius_das_port) {
    1015             :                 struct radius_das_conf das_conf;
    1016           2 :                 os_memset(&das_conf, 0, sizeof(das_conf));
    1017           2 :                 das_conf.port = conf->radius_das_port;
    1018           2 :                 das_conf.shared_secret = conf->radius_das_shared_secret;
    1019           2 :                 das_conf.shared_secret_len =
    1020           2 :                         conf->radius_das_shared_secret_len;
    1021           2 :                 das_conf.client_addr = &conf->radius_das_client_addr;
    1022           2 :                 das_conf.time_window = conf->radius_das_time_window;
    1023           2 :                 das_conf.require_event_timestamp =
    1024           2 :                         conf->radius_das_require_event_timestamp;
    1025           2 :                 das_conf.ctx = hapd;
    1026           2 :                 das_conf.disconnect = hostapd_das_disconnect;
    1027           2 :                 hapd->radius_das = radius_das_init(&das_conf);
    1028           2 :                 if (hapd->radius_das == NULL) {
    1029           0 :                         wpa_printf(MSG_ERROR, "RADIUS DAS initialization "
    1030             :                                    "failed.");
    1031           0 :                         return -1;
    1032             :                 }
    1033             :         }
    1034             : #endif /* CONFIG_NO_RADIUS */
    1035             : 
    1036        2051 :         if (hostapd_acl_init(hapd)) {
    1037           0 :                 wpa_printf(MSG_ERROR, "ACL initialization failed.");
    1038           0 :                 return -1;
    1039             :         }
    1040        2051 :         if (hostapd_init_wps(hapd, conf))
    1041           0 :                 return -1;
    1042             : 
    1043        2051 :         if (authsrv_init(hapd) < 0)
    1044           3 :                 return -1;
    1045             : 
    1046        2048 :         if (ieee802_1x_init(hapd)) {
    1047           0 :                 wpa_printf(MSG_ERROR, "IEEE 802.1X initialization failed.");
    1048           0 :                 return -1;
    1049             :         }
    1050             : 
    1051        2048 :         if ((conf->wpa || conf->osen) && hostapd_setup_wpa(hapd))
    1052           0 :                 return -1;
    1053             : 
    1054        2048 :         if (accounting_init(hapd)) {
    1055           1 :                 wpa_printf(MSG_ERROR, "Accounting initialization failed.");
    1056           1 :                 return -1;
    1057             :         }
    1058             : 
    1059        2047 :         if (conf->ieee802_11f &&
    1060           0 :             (hapd->iapp = iapp_init(hapd, conf->iapp_iface)) == NULL) {
    1061           0 :                 wpa_printf(MSG_ERROR, "IEEE 802.11F (IAPP) initialization "
    1062             :                            "failed.");
    1063           0 :                 return -1;
    1064             :         }
    1065             : 
    1066             : #ifdef CONFIG_INTERWORKING
    1067        2047 :         if (gas_serv_init(hapd)) {
    1068           0 :                 wpa_printf(MSG_ERROR, "GAS server initialization failed");
    1069           0 :                 return -1;
    1070             :         }
    1071             : 
    1072        2048 :         if (conf->qos_map_set_len &&
    1073           1 :             hostapd_drv_set_qos_map(hapd, conf->qos_map_set,
    1074           1 :                                     conf->qos_map_set_len)) {
    1075           0 :                 wpa_printf(MSG_ERROR, "Failed to initialize QoS Map");
    1076           0 :                 return -1;
    1077             :         }
    1078             : #endif /* CONFIG_INTERWORKING */
    1079             : 
    1080        2047 :         if (conf->bss_load_update_period && bss_load_update_init(hapd)) {
    1081           0 :                 wpa_printf(MSG_ERROR, "BSS Load initialization failed");
    1082           0 :                 return -1;
    1083             :         }
    1084             : 
    1085        2047 :         if (conf->proxy_arp) {
    1086           7 :                 if (x_snoop_init(hapd)) {
    1087           2 :                         wpa_printf(MSG_ERROR,
    1088             :                                    "Generic snooping infrastructure initialization failed");
    1089           2 :                         return -1;
    1090             :                 }
    1091             : 
    1092           5 :                 if (dhcp_snoop_init(hapd)) {
    1093           0 :                         wpa_printf(MSG_ERROR,
    1094             :                                    "DHCP snooping initialization failed");
    1095           0 :                         return -1;
    1096             :                 }
    1097             : 
    1098           5 :                 if (ndisc_snoop_init(hapd)) {
    1099           0 :                         wpa_printf(MSG_ERROR,
    1100             :                                    "Neighbor Discovery snooping initialization failed");
    1101           0 :                         return -1;
    1102             :                 }
    1103             :         }
    1104             : 
    1105        2045 :         if (!hostapd_drv_none(hapd) && vlan_init(hapd)) {
    1106           0 :                 wpa_printf(MSG_ERROR, "VLAN initialization failed.");
    1107           0 :                 return -1;
    1108             :         }
    1109             : 
    1110        2045 :         if (!conf->start_disabled && ieee802_11_set_beacon(hapd) < 0)
    1111           3 :                 return -1;
    1112             : 
    1113        2042 :         if (hapd->wpa_auth && wpa_init_keys(hapd->wpa_auth) < 0)
    1114           0 :                 return -1;
    1115             : 
    1116        2042 :         if (hapd->driver && hapd->driver->set_operstate)
    1117        2030 :                 hapd->driver->set_operstate(hapd->drv_priv, 1);
    1118             : 
    1119        2042 :         return 0;
    1120             : }
    1121             : 
    1122             : 
    1123        2000 : static void hostapd_tx_queue_params(struct hostapd_iface *iface)
    1124             : {
    1125        2000 :         struct hostapd_data *hapd = iface->bss[0];
    1126             :         int i;
    1127             :         struct hostapd_tx_queue_params *p;
    1128             : 
    1129             : #ifdef CONFIG_MESH
    1130         373 :         if (iface->mconf == NULL)
    1131         711 :                 return;
    1132             : #endif /* CONFIG_MESH */
    1133             : 
    1134        8310 :         for (i = 0; i < NUM_TX_QUEUES; i++) {
    1135        6648 :                 p = &iface->conf->tx_queue[i];
    1136             : 
    1137        6648 :                 if (hostapd_set_tx_queue_params(hapd, i, p->aifs, p->cwmin,
    1138             :                                                 p->cwmax, p->burst)) {
    1139         140 :                         wpa_printf(MSG_DEBUG, "Failed to set TX queue "
    1140             :                                    "parameters for queue %d.", i);
    1141             :                         /* Continue anyway */
    1142             :                 }
    1143             :         }
    1144        1627 : }
    1145             : 
    1146             : 
    1147           0 : static int hostapd_set_acl_list(struct hostapd_data *hapd,
    1148             :                                 struct mac_acl_entry *mac_acl,
    1149             :                                 int n_entries, u8 accept_acl)
    1150             : {
    1151             :         struct hostapd_acl_params *acl_params;
    1152             :         int i, err;
    1153             : 
    1154           0 :         acl_params = os_zalloc(sizeof(*acl_params) +
    1155           0 :                                (n_entries * sizeof(acl_params->mac_acl[0])));
    1156           0 :         if (!acl_params)
    1157           0 :                 return -ENOMEM;
    1158             : 
    1159           0 :         for (i = 0; i < n_entries; i++)
    1160           0 :                 os_memcpy(acl_params->mac_acl[i].addr, mac_acl[i].addr,
    1161             :                           ETH_ALEN);
    1162             : 
    1163           0 :         acl_params->acl_policy = accept_acl;
    1164           0 :         acl_params->num_mac_acl = n_entries;
    1165             : 
    1166           0 :         err = hostapd_drv_set_acl(hapd, acl_params);
    1167             : 
    1168           0 :         os_free(acl_params);
    1169             : 
    1170           0 :         return err;
    1171             : }
    1172             : 
    1173             : 
    1174        2000 : static void hostapd_set_acl(struct hostapd_data *hapd)
    1175             : {
    1176        2000 :         struct hostapd_config *conf = hapd->iconf;
    1177             :         int err;
    1178             :         u8 accept_acl;
    1179             : 
    1180        2000 :         if (hapd->iface->drv_max_acl_mac_addrs == 0)
    1181        2000 :                 return;
    1182             : 
    1183           0 :         if (conf->bss[0]->macaddr_acl == DENY_UNLESS_ACCEPTED) {
    1184           0 :                 accept_acl = 1;
    1185           0 :                 err = hostapd_set_acl_list(hapd, conf->bss[0]->accept_mac,
    1186           0 :                                            conf->bss[0]->num_accept_mac,
    1187             :                                            accept_acl);
    1188           0 :                 if (err) {
    1189           0 :                         wpa_printf(MSG_DEBUG, "Failed to set accept acl");
    1190           0 :                         return;
    1191             :                 }
    1192           0 :         } else if (conf->bss[0]->macaddr_acl == ACCEPT_UNLESS_DENIED) {
    1193           0 :                 accept_acl = 0;
    1194           0 :                 err = hostapd_set_acl_list(hapd, conf->bss[0]->deny_mac,
    1195           0 :                                            conf->bss[0]->num_deny_mac,
    1196             :                                            accept_acl);
    1197           0 :                 if (err) {
    1198           0 :                         wpa_printf(MSG_DEBUG, "Failed to set deny acl");
    1199           0 :                         return;
    1200             :                 }
    1201             :         }
    1202             : }
    1203             : 
    1204             : 
    1205          37 : static int start_ctrl_iface_bss(struct hostapd_data *hapd)
    1206             : {
    1207          74 :         if (!hapd->iface->interfaces ||
    1208          37 :             !hapd->iface->interfaces->ctrl_iface_init)
    1209           0 :                 return 0;
    1210             : 
    1211          37 :         if (hapd->iface->interfaces->ctrl_iface_init(hapd)) {
    1212           0 :                 wpa_printf(MSG_ERROR,
    1213             :                            "Failed to setup control interface for %s",
    1214           0 :                            hapd->conf->iface);
    1215           0 :                 return -1;
    1216             :         }
    1217             : 
    1218          37 :         return 0;
    1219             : }
    1220             : 
    1221             : 
    1222        3687 : static int start_ctrl_iface(struct hostapd_iface *iface)
    1223             : {
    1224             :         size_t i;
    1225             : 
    1226        3687 :         if (!iface->interfaces || !iface->interfaces->ctrl_iface_init)
    1227         373 :                 return 0;
    1228             : 
    1229        6637 :         for (i = 0; i < iface->num_bss; i++) {
    1230        3329 :                 struct hostapd_data *hapd = iface->bss[i];
    1231        3329 :                 if (iface->interfaces->ctrl_iface_init(hapd)) {
    1232           6 :                         wpa_printf(MSG_ERROR,
    1233             :                                    "Failed to setup control interface for %s",
    1234           6 :                                    hapd->conf->iface);
    1235           6 :                         return -1;
    1236             :                 }
    1237             :         }
    1238             : 
    1239        3308 :         return 0;
    1240             : }
    1241             : 
    1242             : 
    1243           4 : static void channel_list_update_timeout(void *eloop_ctx, void *timeout_ctx)
    1244             : {
    1245           4 :         struct hostapd_iface *iface = eloop_ctx;
    1246             : 
    1247           4 :         if (!iface->wait_channel_update) {
    1248           0 :                 wpa_printf(MSG_INFO, "Channel list update timeout, but interface was not waiting for it");
    1249           4 :                 return;
    1250             :         }
    1251             : 
    1252             :         /*
    1253             :          * It is possible that the existing channel list is acceptable, so try
    1254             :          * to proceed.
    1255             :          */
    1256           4 :         wpa_printf(MSG_DEBUG, "Channel list update timeout - try to continue anyway");
    1257           4 :         setup_interface2(iface);
    1258             : }
    1259             : 
    1260             : 
    1261        2751 : void hostapd_channel_list_updated(struct hostapd_iface *iface, int initiator)
    1262             : {
    1263        2751 :         if (!iface->wait_channel_update || initiator != REGDOM_SET_BY_USER)
    1264        5317 :                 return;
    1265             : 
    1266         185 :         wpa_printf(MSG_DEBUG, "Channel list updated - continue setup");
    1267         185 :         eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
    1268         185 :         setup_interface2(iface);
    1269             : }
    1270             : 
    1271             : 
    1272        2023 : static int setup_interface(struct hostapd_iface *iface)
    1273             : {
    1274        2023 :         struct hostapd_data *hapd = iface->bss[0];
    1275             :         size_t i;
    1276             : 
    1277             :         /*
    1278             :          * It is possible that setup_interface() is called after the interface
    1279             :          * was disabled etc., in which case driver_ap_teardown is possibly set
    1280             :          * to 1. Clear it here so any other key/station deletion, which is not
    1281             :          * part of a teardown flow, would also call the relevant driver
    1282             :          * callbacks.
    1283             :          */
    1284        2023 :         iface->driver_ap_teardown = 0;
    1285             : 
    1286        2023 :         if (!iface->phy[0]) {
    1287        1967 :                 const char *phy = hostapd_drv_get_radio_name(hapd);
    1288        1967 :                 if (phy) {
    1289        1955 :                         wpa_printf(MSG_DEBUG, "phy: %s", phy);
    1290        1955 :                         os_strlcpy(iface->phy, phy, sizeof(iface->phy));
    1291             :                 }
    1292             :         }
    1293             : 
    1294             :         /*
    1295             :          * Make sure that all BSSes get configured with a pointer to the same
    1296             :          * driver interface.
    1297             :          */
    1298        2031 :         for (i = 1; i < iface->num_bss; i++) {
    1299           8 :                 iface->bss[i]->driver = hapd->driver;
    1300           8 :                 iface->bss[i]->drv_priv = hapd->drv_priv;
    1301             :         }
    1302             : 
    1303        2023 :         if (hostapd_validate_bssid_configuration(iface))
    1304           0 :                 return -1;
    1305             : 
    1306             :         /*
    1307             :          * Initialize control interfaces early to allow external monitoring of
    1308             :          * channel setup operations that may take considerable amount of time
    1309             :          * especially for DFS cases.
    1310             :          */
    1311        2023 :         if (start_ctrl_iface(iface))
    1312           0 :                 return -1;
    1313             : 
    1314        2023 :         if (hapd->iconf->country[0] && hapd->iconf->country[1]) {
    1315             :                 char country[4], previous_country[4];
    1316             : 
    1317         339 :                 hostapd_set_state(iface, HAPD_IFACE_COUNTRY_UPDATE);
    1318         339 :                 if (hostapd_get_country(hapd, previous_country) < 0)
    1319           0 :                         previous_country[0] = '\0';
    1320             : 
    1321         339 :                 os_memcpy(country, hapd->iconf->country, 3);
    1322         339 :                 country[3] = '\0';
    1323         339 :                 if (hostapd_set_country(hapd, country) < 0) {
    1324           0 :                         wpa_printf(MSG_ERROR, "Failed to set country code");
    1325         189 :                         return -1;
    1326             :                 }
    1327             : 
    1328         339 :                 wpa_printf(MSG_DEBUG, "Previous country code %s, new country code %s",
    1329             :                            previous_country, country);
    1330             : 
    1331         339 :                 if (os_strncmp(previous_country, country, 2) != 0) {
    1332         189 :                         wpa_printf(MSG_DEBUG, "Continue interface setup after channel list update");
    1333         189 :                         iface->wait_channel_update = 1;
    1334         189 :                         eloop_register_timeout(5, 0,
    1335             :                                                channel_list_update_timeout,
    1336             :                                                iface, NULL);
    1337         189 :                         return 0;
    1338             :                 }
    1339             :         }
    1340             : 
    1341        1834 :         return setup_interface2(iface);
    1342             : }
    1343             : 
    1344             : 
    1345        2023 : static int setup_interface2(struct hostapd_iface *iface)
    1346             : {
    1347        2023 :         iface->wait_channel_update = 0;
    1348             : 
    1349        2023 :         if (hostapd_get_hw_features(iface)) {
    1350             :                 /* Not all drivers support this yet, so continue without hw
    1351             :                  * feature data. */
    1352             :         } else {
    1353        2011 :                 int ret = hostapd_select_hw_mode(iface);
    1354        2011 :                 if (ret < 0) {
    1355           2 :                         wpa_printf(MSG_ERROR, "Could not select hw_mode and "
    1356             :                                    "channel. (%d)", ret);
    1357           2 :                         goto fail;
    1358             :                 }
    1359        2009 :                 if (ret == 1) {
    1360          11 :                         wpa_printf(MSG_DEBUG, "Interface initialization will be completed in a callback (ACS)");
    1361          11 :                         return 0;
    1362             :                 }
    1363        1998 :                 ret = hostapd_check_ht_capab(iface);
    1364        1998 :                 if (ret < 0)
    1365           2 :                         goto fail;
    1366        1996 :                 if (ret == 1) {
    1367          55 :                         wpa_printf(MSG_DEBUG, "Interface initialization will "
    1368             :                                    "be completed in a callback");
    1369          55 :                         return 0;
    1370             :                 }
    1371             : 
    1372        1941 :                 if (iface->conf->ieee80211h)
    1373           6 :                         wpa_printf(MSG_DEBUG, "DFS support is enabled");
    1374             :         }
    1375        1953 :         return hostapd_setup_interface_complete(iface, 0);
    1376             : 
    1377             : fail:
    1378           4 :         hostapd_set_state(iface, HAPD_IFACE_DISABLED);
    1379           4 :         wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
    1380           4 :         if (iface->interfaces && iface->interfaces->terminate_on_error)
    1381           0 :                 eloop_terminate();
    1382           4 :         return -1;
    1383             : }
    1384             : 
    1385             : 
    1386             : #ifdef CONFIG_FST
    1387             : 
    1388         532 : static const u8 * fst_hostapd_get_bssid_cb(void *ctx)
    1389             : {
    1390         532 :         struct hostapd_data *hapd = ctx;
    1391             : 
    1392         532 :         return hapd->own_addr;
    1393             : }
    1394             : 
    1395             : 
    1396        1193 : static void fst_hostapd_get_channel_info_cb(void *ctx,
    1397             :                                             enum hostapd_hw_mode *hw_mode,
    1398             :                                             u8 *channel)
    1399             : {
    1400        1193 :         struct hostapd_data *hapd = ctx;
    1401             : 
    1402        1193 :         *hw_mode = ieee80211_freq_to_chan(hapd->iface->freq, channel);
    1403        1193 : }
    1404             : 
    1405             : 
    1406         804 : static void fst_hostapd_set_ies_cb(void *ctx, const struct wpabuf *fst_ies)
    1407             : {
    1408         804 :         struct hostapd_data *hapd = ctx;
    1409             : 
    1410         804 :         if (hapd->iface->fst_ies != fst_ies) {
    1411         532 :                 hapd->iface->fst_ies = fst_ies;
    1412         532 :                 if (ieee802_11_set_beacon(hapd))
    1413           0 :                         wpa_printf(MSG_WARNING, "FST: Cannot set beacon");
    1414             :         }
    1415         804 : }
    1416             : 
    1417             : 
    1418         345 : static int fst_hostapd_send_action_cb(void *ctx, const u8 *da,
    1419             :                                       struct wpabuf *buf)
    1420             : {
    1421         345 :         struct hostapd_data *hapd = ctx;
    1422             : 
    1423         690 :         return hostapd_drv_send_action(hapd, hapd->iface->freq, 0, da,
    1424         345 :                                        wpabuf_head(buf), wpabuf_len(buf));
    1425             : }
    1426             : 
    1427             : 
    1428         300 : static const struct wpabuf * fst_hostapd_get_mb_ie_cb(void *ctx, const u8 *addr)
    1429             : {
    1430         300 :         struct hostapd_data *hapd = ctx;
    1431         300 :         struct sta_info *sta = ap_get_sta(hapd, addr);
    1432             : 
    1433         300 :         return sta ? sta->mb_ies : NULL;
    1434             : }
    1435             : 
    1436             : 
    1437         291 : static void fst_hostapd_update_mb_ie_cb(void *ctx, const u8 *addr,
    1438             :                                         const u8 *buf, size_t size)
    1439             : {
    1440         291 :         struct hostapd_data *hapd = ctx;
    1441         291 :         struct sta_info *sta = ap_get_sta(hapd, addr);
    1442             : 
    1443         291 :         if (sta) {
    1444             :                 struct mb_ies_info info;
    1445             : 
    1446         291 :                 if (!mb_ies_info_by_ies(&info, buf, size)) {
    1447         291 :                         wpabuf_free(sta->mb_ies);
    1448         291 :                         sta->mb_ies = mb_ies_by_info(&info);
    1449             :                 }
    1450             :         }
    1451         291 : }
    1452             : 
    1453             : 
    1454        1785 : static const u8 * fst_hostapd_get_sta(struct fst_get_peer_ctx **get_ctx,
    1455             :                                       Boolean mb_only)
    1456             : {
    1457        1785 :         struct sta_info *s = (struct sta_info *) *get_ctx;
    1458             : 
    1459        1785 :         if (mb_only) {
    1460        1783 :                 for (; s && !s->mb_ies; s = s->next)
    1461             :                         ;
    1462             :         }
    1463             : 
    1464        1785 :         if (s) {
    1465        1516 :                 *get_ctx = (struct fst_get_peer_ctx *) s->next;
    1466             : 
    1467        1516 :                 return s->addr;
    1468             :         }
    1469             : 
    1470         269 :         *get_ctx = NULL;
    1471         269 :         return NULL;
    1472             : }
    1473             : 
    1474             : 
    1475        1518 : static const u8 * fst_hostapd_get_peer_first(void *ctx,
    1476             :                                              struct fst_get_peer_ctx **get_ctx,
    1477             :                                              Boolean mb_only)
    1478             : {
    1479        1518 :         struct hostapd_data *hapd = ctx;
    1480             : 
    1481        1518 :         *get_ctx = (struct fst_get_peer_ctx *) hapd->sta_list;
    1482             : 
    1483        1518 :         return fst_hostapd_get_sta(get_ctx, mb_only);
    1484             : }
    1485             : 
    1486             : 
    1487         267 : static const u8 * fst_hostapd_get_peer_next(void *ctx,
    1488             :                                             struct fst_get_peer_ctx **get_ctx,
    1489             :                                             Boolean mb_only)
    1490             : {
    1491         267 :         return fst_hostapd_get_sta(get_ctx, mb_only);
    1492             : }
    1493             : 
    1494             : 
    1495         272 : void fst_hostapd_fill_iface_obj(struct hostapd_data *hapd,
    1496             :                                 struct fst_wpa_obj *iface_obj)
    1497             : {
    1498         272 :         iface_obj->ctx = hapd;
    1499         272 :         iface_obj->get_bssid = fst_hostapd_get_bssid_cb;
    1500         272 :         iface_obj->get_channel_info = fst_hostapd_get_channel_info_cb;
    1501         272 :         iface_obj->set_ies = fst_hostapd_set_ies_cb;
    1502         272 :         iface_obj->send_action = fst_hostapd_send_action_cb;
    1503         272 :         iface_obj->get_mb_ie = fst_hostapd_get_mb_ie_cb;
    1504         272 :         iface_obj->update_mb_ie = fst_hostapd_update_mb_ie_cb;
    1505         272 :         iface_obj->get_peer_first = fst_hostapd_get_peer_first;
    1506         272 :         iface_obj->get_peer_next = fst_hostapd_get_peer_next;
    1507         272 : }
    1508             : 
    1509             : #endif /* CONFIG_FST */
    1510             : 
    1511             : 
    1512             : /**
    1513             :  * hostapd_setup_interface_complete - Complete interface setup
    1514             :  *
    1515             :  * This function is called when previous steps in the interface setup has been
    1516             :  * completed. This can also start operations, e.g., DFS, that will require
    1517             :  * additional processing before interface is ready to be enabled. Such
    1518             :  * operations will call this function from eloop callbacks when finished.
    1519             :  */
    1520        2026 : int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err)
    1521             : {
    1522        2026 :         struct hostapd_data *hapd = iface->bss[0];
    1523             :         size_t j;
    1524             :         u8 *prev_addr;
    1525        2026 :         int delay_apply_cfg = 0;
    1526        2026 :         int res_dfs_offload = 0;
    1527             : 
    1528        2026 :         if (err)
    1529           1 :                 goto fail;
    1530             : 
    1531        2025 :         wpa_printf(MSG_DEBUG, "Completing interface initialization");
    1532        2025 :         if (iface->conf->channel) {
    1533             : #ifdef NEED_AP_MLME
    1534             :                 int res;
    1535             : #endif /* NEED_AP_MLME */
    1536             : 
    1537        2013 :                 iface->freq = hostapd_hw_get_freq(hapd, iface->conf->channel);
    1538        6039 :                 wpa_printf(MSG_DEBUG, "Mode: %s  Channel: %d  "
    1539             :                            "Frequency: %d MHz",
    1540        2013 :                            hostapd_hw_mode_txt(iface->conf->hw_mode),
    1541        2013 :                            iface->conf->channel, iface->freq);
    1542             : 
    1543             : #ifdef NEED_AP_MLME
    1544             :                 /* Handle DFS only if it is not offloaded to the driver */
    1545        2013 :                 if (!(iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)) {
    1546             :                         /* Check DFS */
    1547        2013 :                         res = hostapd_handle_dfs(iface);
    1548        2013 :                         if (res <= 0) {
    1549          13 :                                 if (res < 0)
    1550           1 :                                         goto fail;
    1551          12 :                                 return res;
    1552             :                         }
    1553             :                 } else {
    1554             :                         /* If DFS is offloaded to the driver */
    1555           0 :                         res_dfs_offload = hostapd_handle_dfs_offload(iface);
    1556           0 :                         if (res_dfs_offload <= 0) {
    1557           0 :                                 if (res_dfs_offload < 0)
    1558           0 :                                         goto fail;
    1559             :                         } else {
    1560           0 :                                 wpa_printf(MSG_DEBUG,
    1561             :                                            "Proceed with AP/channel setup");
    1562             :                                 /*
    1563             :                                  * If this is a DFS channel, move to completing
    1564             :                                  * AP setup.
    1565             :                                  */
    1566           0 :                                 if (res_dfs_offload == 1)
    1567           0 :                                         goto dfs_offload;
    1568             :                                 /* Otherwise fall through. */
    1569             :                         }
    1570             :                 }
    1571             : #endif /* NEED_AP_MLME */
    1572             : 
    1573             : #ifdef CONFIG_MESH
    1574         373 :                 if (iface->mconf != NULL) {
    1575          35 :                         wpa_printf(MSG_DEBUG,
    1576             :                                    "%s: Mesh configuration will be applied while joining the mesh network",
    1577          35 :                                    iface->bss[0]->conf->iface);
    1578          35 :                         delay_apply_cfg = 1;
    1579             :                 }
    1580             : #endif /* CONFIG_MESH */
    1581             : 
    1582        3965 :                 if (!delay_apply_cfg &&
    1583       13755 :                     hostapd_set_freq(hapd, hapd->iconf->hw_mode, iface->freq,
    1584        1965 :                                      hapd->iconf->channel,
    1585        1965 :                                      hapd->iconf->ieee80211n,
    1586        1965 :                                      hapd->iconf->ieee80211ac,
    1587        1965 :                                      hapd->iconf->secondary_channel,
    1588        1965 :                                      hapd->iconf->vht_oper_chwidth,
    1589        1965 :                                      hapd->iconf->vht_oper_centr_freq_seg0_idx,
    1590        1965 :                                      hapd->iconf->vht_oper_centr_freq_seg1_idx)) {
    1591           0 :                         wpa_printf(MSG_ERROR, "Could not set channel for "
    1592             :                                    "kernel driver");
    1593           0 :                         goto fail;
    1594             :                 }
    1595             :         }
    1596             : 
    1597        2012 :         if (iface->current_mode) {
    1598        2000 :                 if (hostapd_prepare_rates(iface, iface->current_mode)) {
    1599           0 :                         wpa_printf(MSG_ERROR, "Failed to prepare rates "
    1600             :                                    "table.");
    1601           0 :                         hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
    1602             :                                        HOSTAPD_LEVEL_WARNING,
    1603             :                                        "Failed to prepare rates table.");
    1604           0 :                         goto fail;
    1605             :                 }
    1606             :         }
    1607             : 
    1608        2013 :         if (hapd->iconf->rts_threshold > -1 &&
    1609           1 :             hostapd_set_rts(hapd, hapd->iconf->rts_threshold)) {
    1610           0 :                 wpa_printf(MSG_ERROR, "Could not set RTS threshold for "
    1611             :                            "kernel driver");
    1612           0 :                 goto fail;
    1613             :         }
    1614             : 
    1615        2015 :         if (hapd->iconf->fragm_threshold > -1 &&
    1616           3 :             hostapd_set_frag(hapd, hapd->iconf->fragm_threshold)) {
    1617           0 :                 wpa_printf(MSG_ERROR, "Could not set fragmentation threshold "
    1618             :                            "for kernel driver");
    1619           0 :                 goto fail;
    1620             :         }
    1621             : 
    1622        2012 :         prev_addr = hapd->own_addr;
    1623             : 
    1624        4021 :         for (j = 0; j < iface->num_bss; j++) {
    1625        2021 :                 hapd = iface->bss[j];
    1626        2021 :                 if (j)
    1627           9 :                         os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN);
    1628        2021 :                 if (hostapd_setup_bss(hapd, j == 0)) {
    1629             :                         do {
    1630          12 :                                 hapd = iface->bss[j];
    1631          12 :                                 hostapd_bss_deinit_no_free(hapd);
    1632          12 :                                 hostapd_free_hapd_data(hapd);
    1633          12 :                         } while (j-- > 0);
    1634          12 :                         goto fail;
    1635             :                 }
    1636        2009 :                 if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0)
    1637        1954 :                         prev_addr = hapd->own_addr;
    1638             :         }
    1639        2000 :         hapd = iface->bss[0];
    1640             : 
    1641        2000 :         hostapd_tx_queue_params(iface);
    1642             : 
    1643        2000 :         ap_list_init(iface);
    1644        2000 :         dl_list_init(&iface->sta_seen);
    1645             : 
    1646        2000 :         hostapd_set_acl(hapd);
    1647             : 
    1648        2000 :         if (hostapd_driver_commit(hapd) < 0) {
    1649           0 :                 wpa_printf(MSG_ERROR, "%s: Failed to commit driver "
    1650             :                            "configuration", __func__);
    1651           0 :                 goto fail;
    1652             :         }
    1653             : 
    1654             :         /*
    1655             :          * WPS UPnP module can be initialized only when the "upnp_iface" is up.
    1656             :          * If "interface" and "upnp_iface" are the same (e.g., non-bridge
    1657             :          * mode), the interface is up only after driver_commit, so initialize
    1658             :          * WPS after driver_commit.
    1659             :          */
    1660        4007 :         for (j = 0; j < iface->num_bss; j++) {
    1661        2009 :                 if (hostapd_init_wps_complete(iface->bss[j]))
    1662           2 :                         goto fail;
    1663             :         }
    1664             : 
    1665        1998 :         if ((iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) &&
    1666             :             !res_dfs_offload) {
    1667             :                 /*
    1668             :                  * If freq is DFS, and DFS is offloaded to the driver, then wait
    1669             :                  * for CAC to complete.
    1670             :                  */
    1671           0 :                 wpa_printf(MSG_DEBUG, "%s: Wait for CAC to complete", __func__);
    1672           0 :                 return res_dfs_offload;
    1673             :         }
    1674             : 
    1675             : #ifdef NEED_AP_MLME
    1676             : dfs_offload:
    1677             : #endif /* NEED_AP_MLME */
    1678             : 
    1679             : #ifdef CONFIG_FST
    1680        1998 :         if (hapd->iconf->fst_cfg.group_id[0]) {
    1681             :                 struct fst_wpa_obj iface_obj;
    1682             : 
    1683           7 :                 fst_hostapd_fill_iface_obj(hapd, &iface_obj);
    1684           7 :                 iface->fst = fst_attach(hapd->conf->iface, hapd->own_addr,
    1685           7 :                                         &iface_obj, &hapd->iconf->fst_cfg);
    1686           7 :                 if (!iface->fst) {
    1687           0 :                         wpa_printf(MSG_ERROR, "Could not attach to FST %s",
    1688           0 :                                    hapd->iconf->fst_cfg.group_id);
    1689           0 :                         goto fail;
    1690             :                 }
    1691             :         }
    1692             : #endif /* CONFIG_FST */
    1693             : 
    1694        1998 :         hostapd_set_state(iface, HAPD_IFACE_ENABLED);
    1695        1998 :         wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_ENABLED);
    1696        1998 :         if (hapd->setup_complete_cb)
    1697         338 :                 hapd->setup_complete_cb(hapd->setup_complete_cb_ctx);
    1698             : 
    1699        1998 :         wpa_printf(MSG_DEBUG, "%s: Setup of interface done.",
    1700        1998 :                    iface->bss[0]->conf->iface);
    1701        1998 :         if (iface->interfaces && iface->interfaces->terminate_on_error > 0)
    1702          19 :                 iface->interfaces->terminate_on_error--;
    1703             : 
    1704        1998 :         return 0;
    1705             : 
    1706             : fail:
    1707          16 :         wpa_printf(MSG_ERROR, "Interface initialization failed");
    1708          16 :         hostapd_set_state(iface, HAPD_IFACE_DISABLED);
    1709          16 :         wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
    1710             : #ifdef CONFIG_FST
    1711          16 :         if (iface->fst) {
    1712           0 :                 fst_detach(iface->fst);
    1713           0 :                 iface->fst = NULL;
    1714             :         }
    1715             : #endif /* CONFIG_FST */
    1716          16 :         if (iface->interfaces && iface->interfaces->terminate_on_error)
    1717           0 :                 eloop_terminate();
    1718          16 :         return -1;
    1719             : }
    1720             : 
    1721             : 
    1722             : /**
    1723             :  * hostapd_setup_interface - Setup of an interface
    1724             :  * @iface: Pointer to interface data.
    1725             :  * Returns: 0 on success, -1 on failure
    1726             :  *
    1727             :  * Initializes the driver interface, validates the configuration,
    1728             :  * and sets driver parameters based on the configuration.
    1729             :  * Flushes old stations, sets the channel, encryption,
    1730             :  * beacons, and WDS links based on the configuration.
    1731             :  *
    1732             :  * If interface setup requires more time, e.g., to perform HT co-ex scans, ACS,
    1733             :  * or DFS operations, this function returns 0 before such operations have been
    1734             :  * completed. The pending operations are registered into eloop and will be
    1735             :  * completed from eloop callbacks. Those callbacks end up calling
    1736             :  * hostapd_setup_interface_complete() once setup has been completed.
    1737             :  */
    1738        2023 : int hostapd_setup_interface(struct hostapd_iface *iface)
    1739             : {
    1740             :         int ret;
    1741             : 
    1742        2023 :         ret = setup_interface(iface);
    1743        2023 :         if (ret) {
    1744          17 :                 wpa_printf(MSG_ERROR, "%s: Unable to setup interface.",
    1745          17 :                            iface->bss[0]->conf->iface);
    1746          17 :                 return -1;
    1747             :         }
    1748             : 
    1749        2006 :         return 0;
    1750             : }
    1751             : 
    1752             : 
    1753             : /**
    1754             :  * hostapd_alloc_bss_data - Allocate and initialize per-BSS data
    1755             :  * @hapd_iface: Pointer to interface data
    1756             :  * @conf: Pointer to per-interface configuration
    1757             :  * @bss: Pointer to per-BSS configuration for this BSS
    1758             :  * Returns: Pointer to allocated BSS data
    1759             :  *
    1760             :  * This function is used to allocate per-BSS data structure. This data will be
    1761             :  * freed after hostapd_cleanup() is called for it during interface
    1762             :  * deinitialization.
    1763             :  */
    1764             : struct hostapd_data *
    1765        2092 : hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface,
    1766             :                        struct hostapd_config *conf,
    1767             :                        struct hostapd_bss_config *bss)
    1768             : {
    1769             :         struct hostapd_data *hapd;
    1770             : 
    1771        2092 :         hapd = os_zalloc(sizeof(*hapd));
    1772        2092 :         if (hapd == NULL)
    1773           4 :                 return NULL;
    1774             : 
    1775        2088 :         hapd->new_assoc_sta_cb = hostapd_new_assoc_sta;
    1776        2088 :         hapd->iconf = conf;
    1777        2088 :         hapd->conf = bss;
    1778        2088 :         hapd->iface = hapd_iface;
    1779        2088 :         hapd->driver = hapd->iconf->driver;
    1780        2088 :         hapd->ctrl_sock = -1;
    1781             : 
    1782        2088 :         return hapd;
    1783             : }
    1784             : 
    1785             : 
    1786        2115 : static void hostapd_bss_deinit(struct hostapd_data *hapd)
    1787             : {
    1788        2115 :         wpa_printf(MSG_DEBUG, "%s: deinit bss %s", __func__,
    1789        2115 :                    hapd->conf->iface);
    1790        2115 :         hostapd_bss_deinit_no_free(hapd);
    1791        2115 :         wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
    1792        2115 :         hostapd_cleanup(hapd);
    1793        2115 : }
    1794             : 
    1795             : 
    1796        2072 : void hostapd_interface_deinit(struct hostapd_iface *iface)
    1797             : {
    1798             :         int j;
    1799             : 
    1800        2072 :         wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
    1801        2072 :         if (iface == NULL)
    1802        2072 :                 return;
    1803             : 
    1804        2072 :         hostapd_set_state(iface, HAPD_IFACE_DISABLED);
    1805             : 
    1806             : #ifdef CONFIG_IEEE80211N
    1807             : #ifdef NEED_AP_MLME
    1808        2072 :         hostapd_stop_setup_timers(iface);
    1809        2072 :         eloop_cancel_timeout(ap_ht2040_timeout, iface, NULL);
    1810             : #endif /* NEED_AP_MLME */
    1811             : #endif /* CONFIG_IEEE80211N */
    1812        2072 :         eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
    1813        2072 :         iface->wait_channel_update = 0;
    1814             : 
    1815             : #ifdef CONFIG_FST
    1816        2072 :         if (iface->fst) {
    1817          15 :                 fst_detach(iface->fst);
    1818          15 :                 iface->fst = NULL;
    1819             :         }
    1820             : #endif /* CONFIG_FST */
    1821             : 
    1822        4149 :         for (j = iface->num_bss - 1; j >= 0; j--)
    1823        2077 :                 hostapd_bss_deinit(iface->bss[j]);
    1824             : }
    1825             : 
    1826             : 
    1827        2072 : void hostapd_interface_free(struct hostapd_iface *iface)
    1828             : {
    1829             :         size_t j;
    1830        2072 :         wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
    1831        4149 :         for (j = 0; j < iface->num_bss; j++) {
    1832        2077 :                 wpa_printf(MSG_DEBUG, "%s: free hapd %p",
    1833        2077 :                            __func__, iface->bss[j]);
    1834        2077 :                 os_free(iface->bss[j]);
    1835             :         }
    1836        2072 :         hostapd_cleanup_iface(iface);
    1837        2072 : }
    1838             : 
    1839             : 
    1840             : /**
    1841             :  * hostapd_init - Allocate and initialize per-interface data
    1842             :  * @config_file: Path to the configuration file
    1843             :  * Returns: Pointer to the allocated interface data or %NULL on failure
    1844             :  *
    1845             :  * This function is used to allocate main data structures for per-interface
    1846             :  * data. The allocated data buffer will be freed by calling
    1847             :  * hostapd_cleanup_iface().
    1848             :  */
    1849          54 : struct hostapd_iface * hostapd_init(struct hapd_interfaces *interfaces,
    1850             :                                     const char *config_file)
    1851             : {
    1852          54 :         struct hostapd_iface *hapd_iface = NULL;
    1853          54 :         struct hostapd_config *conf = NULL;
    1854             :         struct hostapd_data *hapd;
    1855             :         size_t i;
    1856             : 
    1857          54 :         hapd_iface = os_zalloc(sizeof(*hapd_iface));
    1858          54 :         if (hapd_iface == NULL)
    1859           2 :                 goto fail;
    1860             : 
    1861          52 :         hapd_iface->config_fname = os_strdup(config_file);
    1862          52 :         if (hapd_iface->config_fname == NULL)
    1863           1 :                 goto fail;
    1864             : 
    1865          51 :         conf = interfaces->config_read_cb(hapd_iface->config_fname);
    1866          51 :         if (conf == NULL)
    1867           9 :                 goto fail;
    1868          42 :         hapd_iface->conf = conf;
    1869             : 
    1870          42 :         hapd_iface->num_bss = conf->num_bss;
    1871          42 :         hapd_iface->bss = os_calloc(conf->num_bss,
    1872             :                                     sizeof(struct hostapd_data *));
    1873          42 :         if (hapd_iface->bss == NULL)
    1874           0 :                 goto fail;
    1875             : 
    1876          84 :         for (i = 0; i < conf->num_bss; i++) {
    1877          84 :                 hapd = hapd_iface->bss[i] =
    1878          42 :                         hostapd_alloc_bss_data(hapd_iface, conf,
    1879          42 :                                                conf->bss[i]);
    1880          42 :                 if (hapd == NULL)
    1881           0 :                         goto fail;
    1882          42 :                 hapd->msg_ctx = hapd;
    1883             :         }
    1884             : 
    1885          42 :         return hapd_iface;
    1886             : 
    1887             : fail:
    1888          12 :         wpa_printf(MSG_ERROR, "Failed to set up interface with %s",
    1889             :                    config_file);
    1890          12 :         if (conf)
    1891           0 :                 hostapd_config_free(conf);
    1892          12 :         if (hapd_iface) {
    1893          10 :                 os_free(hapd_iface->config_fname);
    1894          10 :                 os_free(hapd_iface->bss);
    1895          10 :                 wpa_printf(MSG_DEBUG, "%s: free iface %p",
    1896             :                            __func__, hapd_iface);
    1897          10 :                 os_free(hapd_iface);
    1898             :         }
    1899          12 :         return NULL;
    1900             : }
    1901             : 
    1902             : 
    1903          38 : static int ifname_in_use(struct hapd_interfaces *interfaces, const char *ifname)
    1904             : {
    1905             :         size_t i, j;
    1906             : 
    1907          77 :         for (i = 0; i < interfaces->count; i++) {
    1908          40 :                 struct hostapd_iface *iface = interfaces->iface[i];
    1909         208 :                 for (j = 0; j < iface->num_bss; j++) {
    1910         169 :                         struct hostapd_data *hapd = iface->bss[j];
    1911         169 :                         if (os_strcmp(ifname, hapd->conf->iface) == 0)
    1912           1 :                                 return 1;
    1913             :                 }
    1914             :         }
    1915             : 
    1916          37 :         return 0;
    1917             : }
    1918             : 
    1919             : 
    1920             : /**
    1921             :  * hostapd_interface_init_bss - Read configuration file and init BSS data
    1922             :  *
    1923             :  * This function is used to parse configuration file for a BSS. This BSS is
    1924             :  * added to an existing interface sharing the same radio (if any) or a new
    1925             :  * interface is created if this is the first interface on a radio. This
    1926             :  * allocate memory for the BSS. No actual driver operations are started.
    1927             :  *
    1928             :  * This is similar to hostapd_interface_init(), but for a case where the
    1929             :  * configuration is used to add a single BSS instead of all BSSes for a radio.
    1930             :  */
    1931             : struct hostapd_iface *
    1932          56 : hostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy,
    1933             :                            const char *config_fname, int debug)
    1934             : {
    1935          56 :         struct hostapd_iface *new_iface = NULL, *iface = NULL;
    1936             :         struct hostapd_data *hapd;
    1937             :         int k;
    1938             :         size_t i, bss_idx;
    1939             : 
    1940          56 :         if (!phy || !*phy)
    1941           0 :                 return NULL;
    1942             : 
    1943          64 :         for (i = 0; i < interfaces->count; i++) {
    1944          47 :                 if (os_strcmp(interfaces->iface[i]->phy, phy) == 0) {
    1945          39 :                         iface = interfaces->iface[i];
    1946          39 :                         break;
    1947             :                 }
    1948             :         }
    1949             : 
    1950          56 :         wpa_printf(MSG_INFO, "Configuration file: %s (phy %s)%s",
    1951             :                    config_fname, phy, iface ? "" : " --> new PHY");
    1952          56 :         if (iface) {
    1953             :                 struct hostapd_config *conf;
    1954             :                 struct hostapd_bss_config **tmp_conf;
    1955             :                 struct hostapd_data **tmp_bss;
    1956             :                 struct hostapd_bss_config *bss;
    1957             :                 const char *ifname;
    1958             : 
    1959             :                 /* Add new BSS to existing iface */
    1960          39 :                 conf = interfaces->config_read_cb(config_fname);
    1961          39 :                 if (conf == NULL)
    1962           1 :                         return NULL;
    1963          38 :                 if (conf->num_bss > 1) {
    1964           0 :                         wpa_printf(MSG_ERROR, "Multiple BSSes specified in BSS-config");
    1965           0 :                         hostapd_config_free(conf);
    1966           0 :                         return NULL;
    1967             :                 }
    1968             : 
    1969          38 :                 ifname = conf->bss[0]->iface;
    1970          38 :                 if (ifname[0] != '\0' && ifname_in_use(interfaces, ifname)) {
    1971           1 :                         wpa_printf(MSG_ERROR,
    1972             :                                    "Interface name %s already in use", ifname);
    1973           1 :                         hostapd_config_free(conf);
    1974           1 :                         return NULL;
    1975             :                 }
    1976             : 
    1977          74 :                 tmp_conf = os_realloc_array(
    1978          74 :                         iface->conf->bss, iface->conf->num_bss + 1,
    1979             :                         sizeof(struct hostapd_bss_config *));
    1980          37 :                 tmp_bss = os_realloc_array(iface->bss, iface->num_bss + 1,
    1981             :                                            sizeof(struct hostapd_data *));
    1982          37 :                 if (tmp_bss)
    1983          37 :                         iface->bss = tmp_bss;
    1984          37 :                 if (tmp_conf) {
    1985          37 :                         iface->conf->bss = tmp_conf;
    1986          37 :                         iface->conf->last_bss = tmp_conf[0];
    1987             :                 }
    1988          37 :                 if (tmp_bss == NULL || tmp_conf == NULL) {
    1989           0 :                         hostapd_config_free(conf);
    1990           0 :                         return NULL;
    1991             :                 }
    1992          37 :                 bss = iface->conf->bss[iface->conf->num_bss] = conf->bss[0];
    1993          37 :                 iface->conf->num_bss++;
    1994             : 
    1995          37 :                 hapd = hostapd_alloc_bss_data(iface, iface->conf, bss);
    1996          37 :                 if (hapd == NULL) {
    1997           0 :                         iface->conf->num_bss--;
    1998           0 :                         hostapd_config_free(conf);
    1999           0 :                         return NULL;
    2000             :                 }
    2001          37 :                 iface->conf->last_bss = bss;
    2002          37 :                 iface->bss[iface->num_bss] = hapd;
    2003          37 :                 hapd->msg_ctx = hapd;
    2004             : 
    2005          37 :                 bss_idx = iface->num_bss++;
    2006          37 :                 conf->num_bss--;
    2007          37 :                 conf->bss[0] = NULL;
    2008          37 :                 hostapd_config_free(conf);
    2009             :         } else {
    2010             :                 /* Add a new iface with the first BSS */
    2011          17 :                 new_iface = iface = hostapd_init(interfaces, config_fname);
    2012          17 :                 if (!iface)
    2013           3 :                         return NULL;
    2014          14 :                 os_strlcpy(iface->phy, phy, sizeof(iface->phy));
    2015          14 :                 iface->interfaces = interfaces;
    2016          14 :                 bss_idx = 0;
    2017             :         }
    2018             : 
    2019          51 :         for (k = 0; k < debug; k++) {
    2020           0 :                 if (iface->bss[bss_idx]->conf->logger_stdout_level > 0)
    2021           0 :                         iface->bss[bss_idx]->conf->logger_stdout_level--;
    2022             :         }
    2023             : 
    2024          51 :         if (iface->conf->bss[bss_idx]->iface[0] == '\0' &&
    2025           0 :             !hostapd_drv_none(iface->bss[bss_idx])) {
    2026           0 :                 wpa_printf(MSG_ERROR, "Interface name not specified in %s",
    2027             :                            config_fname);
    2028           0 :                 if (new_iface)
    2029           0 :                         hostapd_interface_deinit_free(new_iface);
    2030           0 :                 return NULL;
    2031             :         }
    2032             : 
    2033          51 :         return iface;
    2034             : }
    2035             : 
    2036             : 
    2037        1699 : void hostapd_interface_deinit_free(struct hostapd_iface *iface)
    2038             : {
    2039             :         const struct wpa_driver_ops *driver;
    2040             :         void *drv_priv;
    2041             : 
    2042        1699 :         wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
    2043        1699 :         if (iface == NULL)
    2044        1699 :                 return;
    2045        3398 :         wpa_printf(MSG_DEBUG, "%s: num_bss=%u conf->num_bss=%u",
    2046        1699 :                    __func__, (unsigned int) iface->num_bss,
    2047        1699 :                    (unsigned int) iface->conf->num_bss);
    2048        1699 :         driver = iface->bss[0]->driver;
    2049        1699 :         drv_priv = iface->bss[0]->drv_priv;
    2050        1699 :         hostapd_interface_deinit(iface);
    2051        1699 :         wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit",
    2052             :                    __func__, driver, drv_priv);
    2053        1699 :         if (driver && driver->hapd_deinit && drv_priv) {
    2054        1504 :                 driver->hapd_deinit(drv_priv);
    2055        1504 :                 iface->bss[0]->drv_priv = NULL;
    2056             :         }
    2057        1699 :         hostapd_interface_free(iface);
    2058             : }
    2059             : 
    2060             : 
    2061         146 : static void hostapd_deinit_driver(const struct wpa_driver_ops *driver,
    2062             :                                   void *drv_priv,
    2063             :                                   struct hostapd_iface *hapd_iface)
    2064             : {
    2065             :         size_t j;
    2066             : 
    2067         146 :         wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit",
    2068             :                    __func__, driver, drv_priv);
    2069         146 :         if (driver && driver->hapd_deinit && drv_priv) {
    2070         146 :                 driver->hapd_deinit(drv_priv);
    2071         295 :                 for (j = 0; j < hapd_iface->num_bss; j++) {
    2072         149 :                         wpa_printf(MSG_DEBUG, "%s:bss[%d]->drv_priv=%p",
    2073             :                                    __func__, (int) j,
    2074         149 :                                    hapd_iface->bss[j]->drv_priv);
    2075         149 :                         if (hapd_iface->bss[j]->drv_priv == drv_priv)
    2076         146 :                                 hapd_iface->bss[j]->drv_priv = NULL;
    2077             :                 }
    2078             :         }
    2079         146 : }
    2080             : 
    2081             : 
    2082        1642 : int hostapd_enable_iface(struct hostapd_iface *hapd_iface)
    2083             : {
    2084             :         size_t j;
    2085             : 
    2086        1642 :         if (hapd_iface->bss[0]->drv_priv != NULL) {
    2087           0 :                 wpa_printf(MSG_ERROR, "Interface %s already enabled",
    2088           0 :                            hapd_iface->conf->bss[0]->iface);
    2089           0 :                 return -1;
    2090             :         }
    2091             : 
    2092        1642 :         wpa_printf(MSG_DEBUG, "Enable interface %s",
    2093        1642 :                    hapd_iface->conf->bss[0]->iface);
    2094             : 
    2095        3292 :         for (j = 0; j < hapd_iface->num_bss; j++)
    2096        1650 :                 hostapd_set_security_params(hapd_iface->conf->bss[j], 1);
    2097        1642 :         if (hostapd_config_check(hapd_iface->conf, 1) < 0) {
    2098           8 :                 wpa_printf(MSG_INFO, "Invalid configuration - cannot enable");
    2099           8 :                 return -1;
    2100             :         }
    2101             : 
    2102        3268 :         if (hapd_iface->interfaces == NULL ||
    2103        3268 :             hapd_iface->interfaces->driver_init == NULL ||
    2104        1634 :             hapd_iface->interfaces->driver_init(hapd_iface))
    2105          17 :                 return -1;
    2106             : 
    2107        1617 :         if (hostapd_setup_interface(hapd_iface)) {
    2108          16 :                 hostapd_deinit_driver(hapd_iface->bss[0]->driver,
    2109          16 :                                       hapd_iface->bss[0]->drv_priv,
    2110             :                                       hapd_iface);
    2111          16 :                 return -1;
    2112             :         }
    2113             : 
    2114        1601 :         return 0;
    2115             : }
    2116             : 
    2117             : 
    2118           2 : int hostapd_reload_iface(struct hostapd_iface *hapd_iface)
    2119             : {
    2120             :         size_t j;
    2121             : 
    2122           2 :         wpa_printf(MSG_DEBUG, "Reload interface %s",
    2123           2 :                    hapd_iface->conf->bss[0]->iface);
    2124           4 :         for (j = 0; j < hapd_iface->num_bss; j++)
    2125           2 :                 hostapd_set_security_params(hapd_iface->conf->bss[j], 1);
    2126           2 :         if (hostapd_config_check(hapd_iface->conf, 1) < 0) {
    2127           0 :                 wpa_printf(MSG_ERROR, "Updated configuration is invalid");
    2128           0 :                 return -1;
    2129             :         }
    2130           2 :         hostapd_clear_old(hapd_iface);
    2131           4 :         for (j = 0; j < hapd_iface->num_bss; j++)
    2132           2 :                 hostapd_reload_bss(hapd_iface->bss[j]);
    2133             : 
    2134           2 :         return 0;
    2135             : }
    2136             : 
    2137             : 
    2138         135 : int hostapd_disable_iface(struct hostapd_iface *hapd_iface)
    2139             : {
    2140             :         size_t j;
    2141             :         const struct wpa_driver_ops *driver;
    2142             :         void *drv_priv;
    2143             : 
    2144         135 :         if (hapd_iface == NULL)
    2145           0 :                 return -1;
    2146             : 
    2147         135 :         if (hapd_iface->bss[0]->drv_priv == NULL) {
    2148           6 :                 wpa_printf(MSG_INFO, "Interface %s already disabled",
    2149           6 :                            hapd_iface->conf->bss[0]->iface);
    2150           6 :                 return -1;
    2151             :         }
    2152             : 
    2153         129 :         wpa_msg(hapd_iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
    2154         129 :         driver = hapd_iface->bss[0]->driver;
    2155         129 :         drv_priv = hapd_iface->bss[0]->drv_priv;
    2156             : 
    2157         129 :         hapd_iface->driver_ap_teardown =
    2158         129 :                 !!(hapd_iface->drv_flags &
    2159             :                    WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
    2160             : 
    2161             :         /* same as hostapd_interface_deinit without deinitializing ctrl-iface */
    2162         261 :         for (j = 0; j < hapd_iface->num_bss; j++) {
    2163         132 :                 struct hostapd_data *hapd = hapd_iface->bss[j];
    2164         132 :                 hostapd_bss_deinit_no_free(hapd);
    2165         132 :                 hostapd_free_hapd_data(hapd);
    2166             :         }
    2167             : 
    2168         129 :         hostapd_deinit_driver(driver, drv_priv, hapd_iface);
    2169             : 
    2170             :         /* From hostapd_cleanup_iface: These were initialized in
    2171             :          * hostapd_setup_interface and hostapd_setup_interface_complete
    2172             :          */
    2173         129 :         hostapd_cleanup_iface_partial(hapd_iface);
    2174             : 
    2175         129 :         wpa_printf(MSG_DEBUG, "Interface %s disabled",
    2176         129 :                    hapd_iface->bss[0]->conf->iface);
    2177         129 :         hostapd_set_state(hapd_iface, HAPD_IFACE_DISABLED);
    2178         129 :         return 0;
    2179             : }
    2180             : 
    2181             : 
    2182             : static struct hostapd_iface *
    2183        1699 : hostapd_iface_alloc(struct hapd_interfaces *interfaces)
    2184             : {
    2185             :         struct hostapd_iface **iface, *hapd_iface;
    2186             : 
    2187        1699 :         iface = os_realloc_array(interfaces->iface, interfaces->count + 1,
    2188             :                                  sizeof(struct hostapd_iface *));
    2189        1699 :         if (iface == NULL)
    2190           4 :                 return NULL;
    2191        1695 :         interfaces->iface = iface;
    2192        3390 :         hapd_iface = interfaces->iface[interfaces->count] =
    2193        1695 :                 os_zalloc(sizeof(*hapd_iface));
    2194        1695 :         if (hapd_iface == NULL) {
    2195           4 :                 wpa_printf(MSG_ERROR, "%s: Failed to allocate memory for "
    2196             :                            "the interface", __func__);
    2197           4 :                 return NULL;
    2198             :         }
    2199        1691 :         interfaces->count++;
    2200        1691 :         hapd_iface->interfaces = interfaces;
    2201             : 
    2202        1691 :         return hapd_iface;
    2203             : }
    2204             : 
    2205             : 
    2206             : static struct hostapd_config *
    2207        1687 : hostapd_config_alloc(struct hapd_interfaces *interfaces, const char *ifname,
    2208             :                      const char *ctrl_iface, const char *driver)
    2209             : {
    2210             :         struct hostapd_bss_config *bss;
    2211             :         struct hostapd_config *conf;
    2212             : 
    2213             :         /* Allocates memory for bss and conf */
    2214        1687 :         conf = hostapd_config_defaults();
    2215        1687 :         if (conf == NULL) {
    2216          17 :                  wpa_printf(MSG_ERROR, "%s: Failed to allocate memory for "
    2217             :                                 "configuration", __func__);
    2218          17 :                 return NULL;
    2219             :         }
    2220             : 
    2221        1670 :         if (driver) {
    2222             :                 int j;
    2223             : 
    2224           1 :                 for (j = 0; wpa_drivers[j]; j++) {
    2225           1 :                         if (os_strcmp(driver, wpa_drivers[j]->name) == 0) {
    2226           1 :                                 conf->driver = wpa_drivers[j];
    2227           1 :                                 goto skip;
    2228             :                         }
    2229             :                 }
    2230             : 
    2231           0 :                 wpa_printf(MSG_ERROR,
    2232             :                            "Invalid/unknown driver '%s' - registering the default driver",
    2233             :                            driver);
    2234             :         }
    2235             : 
    2236        1669 :         conf->driver = wpa_drivers[0];
    2237        1669 :         if (conf->driver == NULL) {
    2238           0 :                 wpa_printf(MSG_ERROR, "No driver wrappers registered!");
    2239           0 :                 hostapd_config_free(conf);
    2240           0 :                 return NULL;
    2241             :         }
    2242             : 
    2243             : skip:
    2244        1670 :         bss = conf->last_bss = conf->bss[0];
    2245             : 
    2246        1670 :         os_strlcpy(bss->iface, ifname, sizeof(bss->iface));
    2247        1670 :         bss->ctrl_interface = os_strdup(ctrl_iface);
    2248        1670 :         if (bss->ctrl_interface == NULL) {
    2249           3 :                 hostapd_config_free(conf);
    2250           3 :                 return NULL;
    2251             :         }
    2252             : 
    2253             :         /* Reading configuration file skipped, will be done in SET!
    2254             :          * From reading the configuration till the end has to be done in
    2255             :          * SET
    2256             :          */
    2257        1667 :         return conf;
    2258             : }
    2259             : 
    2260             : 
    2261        1671 : static int hostapd_data_alloc(struct hostapd_iface *hapd_iface,
    2262             :                               struct hostapd_config *conf)
    2263             : {
    2264             :         size_t i;
    2265             :         struct hostapd_data *hapd;
    2266             : 
    2267        1671 :         hapd_iface->bss = os_calloc(conf->num_bss,
    2268             :                                     sizeof(struct hostapd_data *));
    2269        1671 :         if (hapd_iface->bss == NULL)
    2270           3 :                 return -1;
    2271             : 
    2272        3339 :         for (i = 0; i < conf->num_bss; i++) {
    2273        3350 :                 hapd = hapd_iface->bss[i] =
    2274        1675 :                         hostapd_alloc_bss_data(hapd_iface, conf, conf->bss[i]);
    2275        1675 :                 if (hapd == NULL) {
    2276           8 :                         while (i > 0) {
    2277           0 :                                 i--;
    2278           0 :                                 os_free(hapd_iface->bss[i]);
    2279           0 :                                 hapd_iface->bss[i] = NULL;
    2280             :                         }
    2281           4 :                         os_free(hapd_iface->bss);
    2282           4 :                         hapd_iface->bss = NULL;
    2283           4 :                         return -1;
    2284             :                 }
    2285        1671 :                 hapd->msg_ctx = hapd;
    2286             :         }
    2287             : 
    2288        1664 :         hapd_iface->conf = conf;
    2289        1664 :         hapd_iface->num_bss = conf->num_bss;
    2290             : 
    2291        1664 :         return 0;
    2292             : }
    2293             : 
    2294             : 
    2295        1755 : int hostapd_add_iface(struct hapd_interfaces *interfaces, char *buf)
    2296             : {
    2297        1755 :         struct hostapd_config *conf = NULL;
    2298        1755 :         struct hostapd_iface *hapd_iface = NULL, *new_iface = NULL;
    2299             :         struct hostapd_data *hapd;
    2300             :         char *ptr;
    2301             :         size_t i, j;
    2302        1755 :         const char *conf_file = NULL, *phy_name = NULL;
    2303             : 
    2304        1755 :         if (os_strncmp(buf, "bss_config=", 11) == 0) {
    2305             :                 char *pos;
    2306          56 :                 phy_name = buf + 11;
    2307          56 :                 pos = os_strchr(phy_name, ':');
    2308          56 :                 if (!pos)
    2309           0 :                         return -1;
    2310          56 :                 *pos++ = '\0';
    2311          56 :                 conf_file = pos;
    2312          56 :                 if (!os_strlen(conf_file))
    2313           0 :                         return -1;
    2314             : 
    2315          56 :                 hapd_iface = hostapd_interface_init_bss(interfaces, phy_name,
    2316             :                                                         conf_file, 0);
    2317          56 :                 if (!hapd_iface)
    2318           5 :                         return -1;
    2319          55 :                 for (j = 0; j < interfaces->count; j++) {
    2320          41 :                         if (interfaces->iface[j] == hapd_iface)
    2321          37 :                                 break;
    2322             :                 }
    2323          51 :                 if (j == interfaces->count) {
    2324             :                         struct hostapd_iface **tmp;
    2325          14 :                         tmp = os_realloc_array(interfaces->iface,
    2326          14 :                                                interfaces->count + 1,
    2327             :                                                sizeof(struct hostapd_iface *));
    2328          14 :                         if (!tmp) {
    2329           0 :                                 hostapd_interface_deinit_free(hapd_iface);
    2330           0 :                                 return -1;
    2331             :                         }
    2332          14 :                         interfaces->iface = tmp;
    2333          14 :                         interfaces->iface[interfaces->count++] = hapd_iface;
    2334          14 :                         new_iface = hapd_iface;
    2335             :                 }
    2336             : 
    2337          51 :                 if (new_iface) {
    2338          14 :                         if (interfaces->driver_init(hapd_iface))
    2339           0 :                                 goto fail;
    2340             : 
    2341          14 :                         if (hostapd_setup_interface(hapd_iface)) {
    2342           2 :                                 hostapd_deinit_driver(
    2343           1 :                                         hapd_iface->bss[0]->driver,
    2344           1 :                                         hapd_iface->bss[0]->drv_priv,
    2345             :                                         hapd_iface);
    2346           1 :                                 goto fail;
    2347             :                         }
    2348             :                 } else {
    2349             :                         /* Assign new BSS with bss[0]'s driver info */
    2350          37 :                         hapd = hapd_iface->bss[hapd_iface->num_bss - 1];
    2351          37 :                         hapd->driver = hapd_iface->bss[0]->driver;
    2352          37 :                         hapd->drv_priv = hapd_iface->bss[0]->drv_priv;
    2353          37 :                         os_memcpy(hapd->own_addr, hapd_iface->bss[0]->own_addr,
    2354             :                                   ETH_ALEN);
    2355             : 
    2356          74 :                         if (start_ctrl_iface_bss(hapd) < 0 ||
    2357          71 :                             (hapd_iface->state == HAPD_IFACE_ENABLED &&
    2358          34 :                              hostapd_setup_bss(hapd, -1))) {
    2359           1 :                                 hostapd_cleanup(hapd);
    2360           1 :                                 hapd_iface->bss[hapd_iface->num_bss - 1] = NULL;
    2361           1 :                                 hapd_iface->conf->num_bss--;
    2362           1 :                                 hapd_iface->num_bss--;
    2363           1 :                                 wpa_printf(MSG_DEBUG, "%s: free hapd %p %s",
    2364           1 :                                            __func__, hapd, hapd->conf->iface);
    2365           1 :                                 hostapd_config_free_bss(hapd->conf);
    2366           1 :                                 hapd->conf = NULL;
    2367           1 :                                 os_free(hapd);
    2368           1 :                                 return -1;
    2369             :                         }
    2370             :                 }
    2371          49 :                 return 0;
    2372             :         }
    2373             : 
    2374        1699 :         ptr = os_strchr(buf, ' ');
    2375        1699 :         if (ptr == NULL)
    2376           0 :                 return -1;
    2377        1699 :         *ptr++ = '\0';
    2378             : 
    2379        1699 :         if (os_strncmp(ptr, "config=", 7) == 0)
    2380           4 :                 conf_file = ptr + 7;
    2381             : 
    2382        2170 :         for (i = 0; i < interfaces->count; i++) {
    2383         471 :                 if (!os_strcmp(interfaces->iface[i]->conf->bss[0]->iface,
    2384             :                                buf)) {
    2385           0 :                         wpa_printf(MSG_INFO, "Cannot add interface - it "
    2386             :                                    "already exists");
    2387           0 :                         return -1;
    2388             :                 }
    2389             :         }
    2390             : 
    2391        1699 :         hapd_iface = hostapd_iface_alloc(interfaces);
    2392        1699 :         if (hapd_iface == NULL) {
    2393           8 :                 wpa_printf(MSG_ERROR, "%s: Failed to allocate memory "
    2394             :                            "for interface", __func__);
    2395           8 :                 goto fail;
    2396             :         }
    2397        1691 :         new_iface = hapd_iface;
    2398             : 
    2399        1691 :         if (conf_file && interfaces->config_read_cb) {
    2400           4 :                 conf = interfaces->config_read_cb(conf_file);
    2401           8 :                 if (conf && conf->bss)
    2402           4 :                         os_strlcpy(conf->bss[0]->iface, buf,
    2403             :                                    sizeof(conf->bss[0]->iface));
    2404             :         } else {
    2405        1687 :                 char *driver = os_strchr(ptr, ' ');
    2406             : 
    2407        1687 :                 if (driver)
    2408           1 :                         *driver++ = '\0';
    2409        1687 :                 conf = hostapd_config_alloc(interfaces, buf, ptr, driver);
    2410             :         }
    2411             : 
    2412        1691 :         if (conf == NULL || conf->bss == NULL) {
    2413          20 :                 wpa_printf(MSG_ERROR, "%s: Failed to allocate memory "
    2414             :                            "for configuration", __func__);
    2415          20 :                 goto fail;
    2416             :         }
    2417             : 
    2418        1671 :         if (hostapd_data_alloc(hapd_iface, conf) < 0) {
    2419           7 :                 wpa_printf(MSG_ERROR, "%s: Failed to allocate memory "
    2420             :                            "for hostapd", __func__);
    2421           7 :                 goto fail;
    2422             :         }
    2423        1664 :         conf = NULL;
    2424             : 
    2425        1664 :         if (start_ctrl_iface(hapd_iface) < 0)
    2426           6 :                 goto fail;
    2427             : 
    2428        1658 :         wpa_printf(MSG_INFO, "Add interface '%s'",
    2429        1658 :                    hapd_iface->conf->bss[0]->iface);
    2430             : 
    2431        1658 :         return 0;
    2432             : 
    2433             : fail:
    2434          42 :         if (conf)
    2435           7 :                 hostapd_config_free(conf);
    2436          42 :         if (hapd_iface) {
    2437          34 :                 if (hapd_iface->bss) {
    2438          14 :                         for (i = 0; i < hapd_iface->num_bss; i++) {
    2439           7 :                                 hapd = hapd_iface->bss[i];
    2440           7 :                                 if (!hapd)
    2441           0 :                                         continue;
    2442          14 :                                 if (hapd_iface->interfaces &&
    2443           7 :                                     hapd_iface->interfaces->ctrl_iface_deinit)
    2444           7 :                                         hapd_iface->interfaces->
    2445           7 :                                                 ctrl_iface_deinit(hapd);
    2446           7 :                                 wpa_printf(MSG_DEBUG, "%s: free hapd %p (%s)",
    2447           7 :                                            __func__, hapd_iface->bss[i],
    2448           7 :                                            hapd->conf->iface);
    2449           7 :                                 hostapd_cleanup(hapd);
    2450           7 :                                 os_free(hapd);
    2451           7 :                                 hapd_iface->bss[i] = NULL;
    2452             :                         }
    2453           7 :                         os_free(hapd_iface->bss);
    2454           7 :                         hapd_iface->bss = NULL;
    2455             :                 }
    2456          34 :                 if (new_iface) {
    2457          34 :                         interfaces->count--;
    2458          34 :                         interfaces->iface[interfaces->count] = NULL;
    2459             :                 }
    2460          34 :                 hostapd_cleanup_iface(hapd_iface);
    2461             :         }
    2462          42 :         return -1;
    2463             : }
    2464             : 
    2465             : 
    2466          40 : static int hostapd_remove_bss(struct hostapd_iface *iface, unsigned int idx)
    2467             : {
    2468             :         size_t i;
    2469             : 
    2470          40 :         wpa_printf(MSG_INFO, "Remove BSS '%s'", iface->conf->bss[idx]->iface);
    2471             : 
    2472             :         /* Remove hostapd_data only if it has already been initialized */
    2473          40 :         if (idx < iface->num_bss) {
    2474          38 :                 struct hostapd_data *hapd = iface->bss[idx];
    2475             : 
    2476          38 :                 hostapd_bss_deinit(hapd);
    2477          38 :                 wpa_printf(MSG_DEBUG, "%s: free hapd %p (%s)",
    2478          38 :                            __func__, hapd, hapd->conf->iface);
    2479          38 :                 hostapd_config_free_bss(hapd->conf);
    2480          38 :                 hapd->conf = NULL;
    2481          38 :                 os_free(hapd);
    2482             : 
    2483          38 :                 iface->num_bss--;
    2484             : 
    2485         161 :                 for (i = idx; i < iface->num_bss; i++)
    2486         123 :                         iface->bss[i] = iface->bss[i + 1];
    2487             :         } else {
    2488           2 :                 hostapd_config_free_bss(iface->conf->bss[idx]);
    2489           2 :                 iface->conf->bss[idx] = NULL;
    2490             :         }
    2491             : 
    2492          40 :         iface->conf->num_bss--;
    2493         163 :         for (i = idx; i < iface->conf->num_bss; i++)
    2494         123 :                 iface->conf->bss[i] = iface->conf->bss[i + 1];
    2495             : 
    2496          40 :         return 0;
    2497             : }
    2498             : 
    2499             : 
    2500        8350 : int hostapd_remove_iface(struct hapd_interfaces *interfaces, char *buf)
    2501             : {
    2502             :         struct hostapd_iface *hapd_iface;
    2503        8350 :         size_t i, j, k = 0;
    2504             : 
    2505       11804 :         for (i = 0; i < interfaces->count; i++) {
    2506        5165 :                 hapd_iface = interfaces->iface[i];
    2507        5165 :                 if (hapd_iface == NULL)
    2508           0 :                         return -1;
    2509        5165 :                 if (!os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) {
    2510        1671 :                         wpa_printf(MSG_INFO, "Remove interface '%s'", buf);
    2511        1671 :                         hapd_iface->driver_ap_teardown =
    2512        1671 :                                 !!(hapd_iface->drv_flags &
    2513             :                                    WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
    2514             : 
    2515        1671 :                         hostapd_interface_deinit_free(hapd_iface);
    2516        1671 :                         k = i;
    2517        3591 :                         while (k < (interfaces->count - 1)) {
    2518         498 :                                 interfaces->iface[k] =
    2519         249 :                                         interfaces->iface[k + 1];
    2520         249 :                                 k++;
    2521             :                         }
    2522        1671 :                         interfaces->count--;
    2523        1671 :                         return 0;
    2524             :                 }
    2525             : 
    2526        6999 :                 for (j = 0; j < hapd_iface->conf->num_bss; j++) {
    2527        3545 :                         if (!os_strcmp(hapd_iface->conf->bss[j]->iface, buf)) {
    2528          40 :                                 hapd_iface->driver_ap_teardown =
    2529          40 :                                         !(hapd_iface->drv_flags &
    2530             :                                           WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
    2531          40 :                                 return hostapd_remove_bss(hapd_iface, j);
    2532             :                         }
    2533             :                 }
    2534             :         }
    2535        6639 :         return -1;
    2536             : }
    2537             : 
    2538             : 
    2539             : /**
    2540             :  * hostapd_new_assoc_sta - Notify that a new station associated with the AP
    2541             :  * @hapd: Pointer to BSS data
    2542             :  * @sta: Pointer to the associated STA data
    2543             :  * @reassoc: 1 to indicate this was a re-association; 0 = first association
    2544             :  *
    2545             :  * This function will be called whenever a station associates with the AP. It
    2546             :  * can be called from ieee802_11.c for drivers that export MLME to hostapd and
    2547             :  * from drv_callbacks.c based on driver events for drivers that take care of
    2548             :  * management frames (IEEE 802.11 authentication and association) internally.
    2549             :  */
    2550        3307 : void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
    2551             :                            int reassoc)
    2552             : {
    2553        3307 :         if (hapd->tkip_countermeasures) {
    2554           0 :                 hostapd_drv_sta_deauth(hapd, sta->addr,
    2555             :                                        WLAN_REASON_MICHAEL_MIC_FAILURE);
    2556        3307 :                 return;
    2557             :         }
    2558             : 
    2559        3307 :         hostapd_prune_associations(hapd, sta->addr);
    2560             : 
    2561             :         /* IEEE 802.11F (IAPP) */
    2562        3307 :         if (hapd->conf->ieee802_11f)
    2563           0 :                 iapp_new_station(hapd->iapp, sta);
    2564             : 
    2565             : #ifdef CONFIG_P2P
    2566         435 :         if (sta->p2p_ie == NULL && !sta->no_p2p_set) {
    2567          40 :                 sta->no_p2p_set = 1;
    2568          40 :                 hapd->num_sta_no_p2p++;
    2569          40 :                 if (hapd->num_sta_no_p2p == 1)
    2570          36 :                         hostapd_p2p_non_p2p_sta_connected(hapd);
    2571             :         }
    2572             : #endif /* CONFIG_P2P */
    2573             : 
    2574             :         /* Start accounting here, if IEEE 802.1X and WPA are not used.
    2575             :          * IEEE 802.1X/WPA code will start accounting after the station has
    2576             :          * been authorized. */
    2577        3307 :         if (!hapd->conf->ieee802_1x && !hapd->conf->wpa && !hapd->conf->osen) {
    2578         653 :                 ap_sta_set_authorized(hapd, sta, 1);
    2579         653 :                 os_get_reltime(&sta->connected_time);
    2580         653 :                 accounting_sta_start(hapd, sta);
    2581             :         }
    2582             : 
    2583             :         /* Start IEEE 802.1X authentication process for new stations */
    2584        3307 :         ieee802_1x_new_station(hapd, sta);
    2585        3307 :         if (reassoc) {
    2586          32 :                 if (sta->auth_alg != WLAN_AUTH_FT &&
    2587          16 :                     !(sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS)))
    2588          16 :                         wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH);
    2589             :         } else
    2590        3291 :                 wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm);
    2591             : 
    2592        3307 :         if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_INACTIVITY_TIMER)) {
    2593       23149 :                 wpa_printf(MSG_DEBUG, "%s: reschedule ap_handle_timer timeout "
    2594             :                            "for " MACSTR " (%d seconds - ap_max_inactivity)",
    2595       19842 :                            __func__, MAC2STR(sta->addr),
    2596        3307 :                            hapd->conf->ap_max_inactivity);
    2597        3307 :                 eloop_cancel_timeout(ap_handle_timer, hapd, sta);
    2598        3307 :                 eloop_register_timeout(hapd->conf->ap_max_inactivity, 0,
    2599             :                                        ap_handle_timer, hapd, sta);
    2600             :         }
    2601             : }
    2602             : 
    2603             : 
    2604        9967 : const char * hostapd_state_text(enum hostapd_iface_state s)
    2605             : {
    2606        9967 :         switch (s) {
    2607             :         case HAPD_IFACE_UNINITIALIZED:
    2608        2073 :                 return "UNINITIALIZED";
    2609             :         case HAPD_IFACE_DISABLED:
    2610        2369 :                 return "DISABLED";
    2611             :         case HAPD_IFACE_COUNTRY_UPDATE:
    2612         682 :                 return "COUNTRY_UPDATE";
    2613             :         case HAPD_IFACE_ACS:
    2614          30 :                 return "ACS";
    2615             :         case HAPD_IFACE_HT_SCAN:
    2616         127 :                 return "HT_SCAN";
    2617             :         case HAPD_IFACE_DFS:
    2618          36 :                 return "DFS";
    2619             :         case HAPD_IFACE_ENABLED:
    2620        4650 :                 return "ENABLED";
    2621             :         }
    2622             : 
    2623           0 :         return "UNKNOWN";
    2624             : }
    2625             : 
    2626             : 
    2627        4640 : void hostapd_set_state(struct hostapd_iface *iface, enum hostapd_iface_state s)
    2628             : {
    2629        9280 :         wpa_printf(MSG_INFO, "%s: interface state %s->%s",
    2630        4640 :                    iface->conf->bss[0]->iface, hostapd_state_text(iface->state),
    2631             :                    hostapd_state_text(s));
    2632        4640 :         iface->state = s;
    2633        4640 : }
    2634             : 
    2635             : 
    2636             : #ifdef NEED_AP_MLME
    2637             : 
    2638          46 : static void free_beacon_data(struct beacon_data *beacon)
    2639             : {
    2640          46 :         os_free(beacon->head);
    2641          46 :         beacon->head = NULL;
    2642          46 :         os_free(beacon->tail);
    2643          46 :         beacon->tail = NULL;
    2644          46 :         os_free(beacon->probe_resp);
    2645          46 :         beacon->probe_resp = NULL;
    2646          46 :         os_free(beacon->beacon_ies);
    2647          46 :         beacon->beacon_ies = NULL;
    2648          46 :         os_free(beacon->proberesp_ies);
    2649          46 :         beacon->proberesp_ies = NULL;
    2650          46 :         os_free(beacon->assocresp_ies);
    2651          46 :         beacon->assocresp_ies = NULL;
    2652          46 : }
    2653             : 
    2654             : 
    2655          46 : static int hostapd_build_beacon_data(struct hostapd_data *hapd,
    2656             :                                      struct beacon_data *beacon)
    2657             : {
    2658             :         struct wpabuf *beacon_extra, *proberesp_extra, *assocresp_extra;
    2659             :         struct wpa_driver_ap_params params;
    2660             :         int ret;
    2661             : 
    2662          46 :         os_memset(beacon, 0, sizeof(*beacon));
    2663          46 :         ret = ieee802_11_build_ap_params(hapd, &params);
    2664          46 :         if (ret < 0)
    2665           0 :                 return ret;
    2666             : 
    2667          46 :         ret = hostapd_build_ap_extra_ies(hapd, &beacon_extra,
    2668             :                                          &proberesp_extra,
    2669             :                                          &assocresp_extra);
    2670          46 :         if (ret)
    2671           0 :                 goto free_ap_params;
    2672             : 
    2673          46 :         ret = -1;
    2674          46 :         beacon->head = os_malloc(params.head_len);
    2675          46 :         if (!beacon->head)
    2676           0 :                 goto free_ap_extra_ies;
    2677             : 
    2678          46 :         os_memcpy(beacon->head, params.head, params.head_len);
    2679          46 :         beacon->head_len = params.head_len;
    2680             : 
    2681          46 :         beacon->tail = os_malloc(params.tail_len);
    2682          46 :         if (!beacon->tail)
    2683           0 :                 goto free_beacon;
    2684             : 
    2685          46 :         os_memcpy(beacon->tail, params.tail, params.tail_len);
    2686          46 :         beacon->tail_len = params.tail_len;
    2687             : 
    2688          46 :         if (params.proberesp != NULL) {
    2689           0 :                 beacon->probe_resp = os_malloc(params.proberesp_len);
    2690           0 :                 if (!beacon->probe_resp)
    2691           0 :                         goto free_beacon;
    2692             : 
    2693           0 :                 os_memcpy(beacon->probe_resp, params.proberesp,
    2694             :                           params.proberesp_len);
    2695           0 :                 beacon->probe_resp_len = params.proberesp_len;
    2696             :         }
    2697             : 
    2698             :         /* copy the extra ies */
    2699          46 :         if (beacon_extra) {
    2700          46 :                 beacon->beacon_ies = os_malloc(wpabuf_len(beacon_extra));
    2701          46 :                 if (!beacon->beacon_ies)
    2702           0 :                         goto free_beacon;
    2703             : 
    2704          46 :                 os_memcpy(beacon->beacon_ies,
    2705             :                           beacon_extra->buf, wpabuf_len(beacon_extra));
    2706          46 :                 beacon->beacon_ies_len = wpabuf_len(beacon_extra);
    2707             :         }
    2708             : 
    2709          46 :         if (proberesp_extra) {
    2710          46 :                 beacon->proberesp_ies =
    2711          46 :                         os_malloc(wpabuf_len(proberesp_extra));
    2712          46 :                 if (!beacon->proberesp_ies)
    2713           0 :                         goto free_beacon;
    2714             : 
    2715          46 :                 os_memcpy(beacon->proberesp_ies, proberesp_extra->buf,
    2716             :                           wpabuf_len(proberesp_extra));
    2717          46 :                 beacon->proberesp_ies_len = wpabuf_len(proberesp_extra);
    2718             :         }
    2719             : 
    2720          46 :         if (assocresp_extra) {
    2721          46 :                 beacon->assocresp_ies =
    2722          46 :                         os_malloc(wpabuf_len(assocresp_extra));
    2723          46 :                 if (!beacon->assocresp_ies)
    2724           0 :                         goto free_beacon;
    2725             : 
    2726          46 :                 os_memcpy(beacon->assocresp_ies, assocresp_extra->buf,
    2727             :                           wpabuf_len(assocresp_extra));
    2728          46 :                 beacon->assocresp_ies_len = wpabuf_len(assocresp_extra);
    2729             :         }
    2730             : 
    2731          46 :         ret = 0;
    2732             : free_beacon:
    2733             :         /* if the function fails, the caller should not free beacon data */
    2734          46 :         if (ret)
    2735           0 :                 free_beacon_data(beacon);
    2736             : 
    2737             : free_ap_extra_ies:
    2738          46 :         hostapd_free_ap_extra_ies(hapd, beacon_extra, proberesp_extra,
    2739             :                                   assocresp_extra);
    2740             : free_ap_params:
    2741          46 :         ieee802_11_free_ap_params(&params);
    2742          46 :         return ret;
    2743             : }
    2744             : 
    2745             : 
    2746             : /*
    2747             :  * TODO: This flow currently supports only changing frequency within the
    2748             :  * same hw_mode. Any other changes to MAC parameters or provided settings (even
    2749             :  * width) are not supported.
    2750             :  */
    2751          46 : static int hostapd_change_config_freq(struct hostapd_data *hapd,
    2752             :                                       struct hostapd_config *conf,
    2753             :                                       struct hostapd_freq_params *params,
    2754             :                                       struct hostapd_freq_params *old_params)
    2755             : {
    2756             :         int channel;
    2757             : 
    2758          46 :         if (!params->channel) {
    2759             :                 /* check if the new channel is supported by hw */
    2760          21 :                 params->channel = hostapd_hw_get_channel(hapd, params->freq);
    2761             :         }
    2762             : 
    2763          46 :         channel = params->channel;
    2764          46 :         if (!channel)
    2765           0 :                 return -1;
    2766             : 
    2767             :         /* if a pointer to old_params is provided we save previous state */
    2768          46 :         if (old_params) {
    2769          23 :                 old_params->channel = conf->channel;
    2770          23 :                 old_params->ht_enabled = conf->ieee80211n;
    2771          23 :                 old_params->sec_channel_offset = conf->secondary_channel;
    2772             :         }
    2773             : 
    2774          46 :         conf->channel = channel;
    2775          46 :         conf->ieee80211n = params->ht_enabled;
    2776          46 :         conf->secondary_channel = params->sec_channel_offset;
    2777             : 
    2778             :         /* TODO: maybe call here hostapd_config_check here? */
    2779             : 
    2780          46 :         return 0;
    2781             : }
    2782             : 
    2783             : 
    2784          23 : static int hostapd_fill_csa_settings(struct hostapd_data *hapd,
    2785             :                                      struct csa_settings *settings)
    2786             : {
    2787          23 :         struct hostapd_iface *iface = hapd->iface;
    2788             :         struct hostapd_freq_params old_freq;
    2789             :         int ret;
    2790             : 
    2791          23 :         os_memset(&old_freq, 0, sizeof(old_freq));
    2792          23 :         if (!iface || !iface->freq || hapd->csa_in_progress)
    2793           0 :                 return -1;
    2794             : 
    2795          23 :         ret = hostapd_change_config_freq(iface->bss[0], iface->conf,
    2796             :                                          &settings->freq_params,
    2797             :                                          &old_freq);
    2798          23 :         if (ret)
    2799           0 :                 return ret;
    2800             : 
    2801          23 :         ret = hostapd_build_beacon_data(hapd, &settings->beacon_after);
    2802             : 
    2803             :         /* change back the configuration */
    2804          23 :         hostapd_change_config_freq(iface->bss[0], iface->conf,
    2805             :                                    &old_freq, NULL);
    2806             : 
    2807          23 :         if (ret)
    2808           0 :                 return ret;
    2809             : 
    2810             :         /* set channel switch parameters for csa ie */
    2811          23 :         hapd->cs_freq_params = settings->freq_params;
    2812          23 :         hapd->cs_count = settings->cs_count;
    2813          23 :         hapd->cs_block_tx = settings->block_tx;
    2814             : 
    2815          23 :         ret = hostapd_build_beacon_data(hapd, &settings->beacon_csa);
    2816          23 :         if (ret) {
    2817           0 :                 free_beacon_data(&settings->beacon_after);
    2818           0 :                 return ret;
    2819             :         }
    2820             : 
    2821          23 :         settings->counter_offset_beacon = hapd->cs_c_off_beacon;
    2822          23 :         settings->counter_offset_presp = hapd->cs_c_off_proberesp;
    2823             : 
    2824          23 :         return 0;
    2825             : }
    2826             : 
    2827             : 
    2828          23 : void hostapd_cleanup_cs_params(struct hostapd_data *hapd)
    2829             : {
    2830          23 :         os_memset(&hapd->cs_freq_params, 0, sizeof(hapd->cs_freq_params));
    2831          23 :         hapd->cs_count = 0;
    2832          23 :         hapd->cs_block_tx = 0;
    2833          23 :         hapd->cs_c_off_beacon = 0;
    2834          23 :         hapd->cs_c_off_proberesp = 0;
    2835          23 :         hapd->csa_in_progress = 0;
    2836          23 : }
    2837             : 
    2838             : 
    2839          23 : int hostapd_switch_channel(struct hostapd_data *hapd,
    2840             :                            struct csa_settings *settings)
    2841             : {
    2842             :         int ret;
    2843             : 
    2844          23 :         if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA)) {
    2845           0 :                 wpa_printf(MSG_INFO, "CSA is not supported");
    2846           0 :                 return -1;
    2847             :         }
    2848             : 
    2849          23 :         ret = hostapd_fill_csa_settings(hapd, settings);
    2850          23 :         if (ret)
    2851           0 :                 return ret;
    2852             : 
    2853          23 :         ret = hostapd_drv_switch_channel(hapd, settings);
    2854          23 :         free_beacon_data(&settings->beacon_csa);
    2855          23 :         free_beacon_data(&settings->beacon_after);
    2856             : 
    2857          23 :         if (ret) {
    2858             :                 /* if we failed, clean cs parameters */
    2859           2 :                 hostapd_cleanup_cs_params(hapd);
    2860           2 :                 return ret;
    2861             :         }
    2862             : 
    2863          21 :         hapd->csa_in_progress = 1;
    2864          21 :         return 0;
    2865             : }
    2866             : 
    2867             : 
    2868             : void
    2869           0 : hostapd_switch_channel_fallback(struct hostapd_iface *iface,
    2870             :                                 const struct hostapd_freq_params *freq_params)
    2871             : {
    2872           0 :         int vht_seg0_idx = 0, vht_seg1_idx = 0, vht_bw = VHT_CHANWIDTH_USE_HT;
    2873             :         unsigned int i;
    2874             : 
    2875           0 :         wpa_printf(MSG_DEBUG, "Restarting all CSA-related BSSes");
    2876             : 
    2877           0 :         if (freq_params->center_freq1)
    2878           0 :                 vht_seg0_idx = 36 + (freq_params->center_freq1 - 5180) / 5;
    2879           0 :         if (freq_params->center_freq2)
    2880           0 :                 vht_seg1_idx = 36 + (freq_params->center_freq2 - 5180) / 5;
    2881             : 
    2882           0 :         switch (freq_params->bandwidth) {
    2883             :         case 0:
    2884             :         case 20:
    2885             :         case 40:
    2886           0 :                 vht_bw = VHT_CHANWIDTH_USE_HT;
    2887           0 :                 break;
    2888             :         case 80:
    2889           0 :                 if (freq_params->center_freq2)
    2890           0 :                         vht_bw = VHT_CHANWIDTH_80P80MHZ;
    2891             :                 else
    2892           0 :                         vht_bw = VHT_CHANWIDTH_80MHZ;
    2893           0 :                 break;
    2894             :         case 160:
    2895           0 :                 vht_bw = VHT_CHANWIDTH_160MHZ;
    2896           0 :                 break;
    2897             :         default:
    2898           0 :                 wpa_printf(MSG_WARNING, "Unknown CSA bandwidth: %d",
    2899             :                            freq_params->bandwidth);
    2900           0 :                 break;
    2901             :         }
    2902             : 
    2903           0 :         iface->freq = freq_params->freq;
    2904           0 :         iface->conf->channel = freq_params->channel;
    2905           0 :         iface->conf->secondary_channel = freq_params->sec_channel_offset;
    2906           0 :         iface->conf->vht_oper_centr_freq_seg0_idx = vht_seg0_idx;
    2907           0 :         iface->conf->vht_oper_centr_freq_seg1_idx = vht_seg1_idx;
    2908           0 :         iface->conf->vht_oper_chwidth = vht_bw;
    2909           0 :         iface->conf->ieee80211n = freq_params->ht_enabled;
    2910           0 :         iface->conf->ieee80211ac = freq_params->vht_enabled;
    2911             : 
    2912             :         /*
    2913             :          * cs_params must not be cleared earlier because the freq_params
    2914             :          * argument may actually point to one of these.
    2915             :          */
    2916           0 :         for (i = 0; i < iface->num_bss; i++)
    2917           0 :                 hostapd_cleanup_cs_params(iface->bss[i]);
    2918             : 
    2919           0 :         hostapd_disable_iface(iface);
    2920           0 :         hostapd_enable_iface(iface);
    2921           0 : }
    2922             : 
    2923             : 
    2924         530 : struct hostapd_data * hostapd_get_iface(struct hapd_interfaces *interfaces,
    2925             :                                         const char *ifname)
    2926             : {
    2927             :         size_t i, j;
    2928             : 
    2929         792 :         for (i = 0; i < interfaces->count; i++) {
    2930         790 :                 struct hostapd_iface *iface = interfaces->iface[i];
    2931             : 
    2932        1052 :                 for (j = 0; j < iface->num_bss; j++) {
    2933         790 :                         struct hostapd_data *hapd = iface->bss[j];
    2934             : 
    2935         790 :                         if (os_strcmp(ifname, hapd->conf->iface) == 0)
    2936         528 :                                 return hapd;
    2937             :                 }
    2938             :         }
    2939             : 
    2940           2 :         return NULL;
    2941             : }
    2942             : 
    2943             : #endif /* NEED_AP_MLME */
    2944             : 
    2945             : 
    2946        1749 : void hostapd_periodic_iface(struct hostapd_iface *iface)
    2947             : {
    2948             :         size_t i;
    2949             : 
    2950        1749 :         ap_list_timer(iface);
    2951             : 
    2952        3502 :         for (i = 0; i < iface->num_bss; i++) {
    2953        1753 :                 struct hostapd_data *hapd = iface->bss[i];
    2954             : 
    2955        1753 :                 if (!hapd->started)
    2956          51 :                         continue;
    2957             : 
    2958             : #ifndef CONFIG_NO_RADIUS
    2959        1433 :                 hostapd_acl_expire(hapd);
    2960             : #endif /* CONFIG_NO_RADIUS */
    2961             :         }
    2962        1749 : }

Generated by: LCOV version 1.10