LCOV - code coverage report
Current view: top level - ap - hostapd.c (source / functions) Hit Total Coverage
Test: hostapd hwsim test run 1412854115 Lines: 941 1237 76.1 %
Date: 2014-10-09 Functions: 56 60 93.3 %

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

Generated by: LCOV version 1.10