18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd / Initialization and configuration 3344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt * Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/eloop.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h" 14cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#include "common/wpa_ctrl.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "radius/radius_client.h" 1604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "radius/radius_das.h" 1750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt#include "eap_server/tncs.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "hostapd.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "authsrv.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "sta_info.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "accounting.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_list.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "beacon.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "iapp.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ieee802_1x.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ieee802_11_auth.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "vlan_init.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_auth.h" 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps_hostapd.h" 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "hw_features.h" 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_auth_glue.h" 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_drv_ops.h" 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_config.h" 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_hostapd.h" 3504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "gas_serv.h" 36051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#include "dfs.h" 377832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt#include "ieee802_11.h" 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason); 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd); 42c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidtstatic int hostapd_broadcast_wep_clear(struct hostapd_data *hapd); 43cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic int setup_interface2(struct hostapd_iface *iface); 44cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic void channel_list_update_timeout(void *eloop_ctx, void *timeout_ctx); 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint hostapd_for_each_interface(struct hapd_interfaces *interfaces, 4804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int (*cb)(struct hostapd_iface *iface, 4904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt void *ctx), void *ctx) 5004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 5104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt size_t i; 5204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int ret; 5304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 5404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (i = 0; i < interfaces->count; i++) { 5504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ret = cb(interfaces->iface[i], ctx); 5604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ret) 5704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return ret; 5804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 5904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 6004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 6104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 6204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 6304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_reload_bss(struct hostapd_data *hapd) 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 66cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_ssid *ssid; 67cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_client_reconfig(hapd->radius, hapd->conf->radius); 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 72cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt ssid = &hapd->conf->ssid; 73cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!ssid->wpa_psk_set && ssid->wpa_psk && !ssid->wpa_psk->next && 74cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt ssid->wpa_passphrase_set && ssid->wpa_passphrase) { 75cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* 76cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * Force PSK to be derived again since SSID or passphrase may 77cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * have changed. 78cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 79cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_free(ssid->wpa_psk); 80cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt ssid->wpa_psk = NULL; 81cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_setup_wpa_psk(hapd->conf)) { 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to re-configure WPA PSK " 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "after reloading configuration"); 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ieee802_1x || hapd->conf->wpa) 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 1); 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 0); 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 92f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if ((hapd->conf->wpa || hapd->conf->osen) && hapd->wpa_auth == NULL) { 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_setup_wpa(hapd); 941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (hapd->wpa_auth) 951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_init_keys(hapd->wpa_auth); 961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else if (hapd->conf->wpa) { 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *wpa_ie; 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t wpa_ie_len; 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_reconfig_wpa(hapd); 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &wpa_ie_len); 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_set_generic_elem(hapd, wpa_ie, wpa_ie_len)) 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to configure WPA IE for " 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "the kernel driver."); 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (hapd->wpa_auth) { 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_deinit(hapd->wpa_auth); 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->wpa_auth = NULL; 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_privacy(hapd, 0); 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_setup_encryption(hapd->conf->iface, hapd); 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_generic_elem(hapd, (u8 *) "", 0); 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_11_set_beacon(hapd); 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_update_wps(hapd); 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ssid.ssid_set && 11661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_set_ssid(hapd, hapd->conf->ssid.ssid, 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->ssid.ssid_len)) { 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver"); 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* try to continue */ 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Reconfigured interface %s", hapd->conf->iface); 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 125444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidtstatic void hostapd_clear_old(struct hostapd_iface *iface) 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t j; 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Deauthenticate all stations since the new configuration may not 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * allow them to use the BSS anymore. 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 13404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_flush_old_stations(iface->bss[j], 13504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt WLAN_REASON_PREV_AUTH_NOT_VALID); 136c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt hostapd_broadcast_wep_clear(iface->bss[j]); 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: update dynamic data based on changed configuration 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * items (e.g., open/close sockets, etc.) */ 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_client_flush(iface->bss[j]->radius, 0); 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 144444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt} 145444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt 146444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt 147444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidtint hostapd_reload_config(struct hostapd_iface *iface) 148444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt{ 149444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt struct hostapd_data *hapd = iface->bss[0]; 150444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt struct hostapd_config *newconf, *oldconf; 151444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt size_t j; 152444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt 153444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt if (iface->config_fname == NULL) { 154444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt /* Only in-memory config in use - assume it has been updated */ 155444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt hostapd_clear_old(iface); 156444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) 157444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt hostapd_reload_bss(iface->bss[j]); 158444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt return 0; 159444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt } 160444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt 161444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt if (iface->interfaces == NULL || 162444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt iface->interfaces->config_read_cb == NULL) 163444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt return -1; 164444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt newconf = iface->interfaces->config_read_cb(iface->config_fname); 165444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt if (newconf == NULL) 166444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt return -1; 167444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt 168444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt hostapd_clear_old(iface); 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt oldconf = hapd->iconf; 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->conf = newconf; 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd = iface->bss[j]; 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iconf = newconf; 176d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt hapd->iconf->channel = oldconf->channel; 177df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt hapd->iconf->secondary_channel = oldconf->secondary_channel; 178d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt hapd->iconf->ieee80211n = oldconf->ieee80211n; 179d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt hapd->iconf->ieee80211ac = oldconf->ieee80211ac; 180d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt hapd->iconf->ht_capab = oldconf->ht_capab; 181d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt hapd->iconf->vht_capab = oldconf->vht_capab; 182d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt hapd->iconf->vht_oper_chwidth = oldconf->vht_oper_chwidth; 183d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt hapd->iconf->vht_oper_centr_freq_seg0_idx = 184d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt oldconf->vht_oper_centr_freq_seg0_idx; 185d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt hapd->iconf->vht_oper_centr_freq_seg1_idx = 186d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt oldconf->vht_oper_centr_freq_seg1_idx; 187cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->conf = newconf->bss[j]; 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_reload_bss(hapd); 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_config_free(oldconf); 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_broadcast_key_clear_iface(struct hostapd_data *hapd, 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *ifname) 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < NUM_WEP_KEYS; i++) { 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE, NULL, i, 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, NULL, 0, NULL, 0)) { 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to clear default " 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "encryption keys (ifname=%s keyidx=%d)", 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ifname, i); 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ieee80211w) { 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = NUM_WEP_KEYS; i < NUM_WEP_KEYS + 2; i++) { 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE, 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, i, 0, NULL, 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, NULL, 0)) { 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to clear " 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "default mgmt encryption keys " 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(ifname=%s keyidx=%d)", ifname, i); 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_broadcast_wep_clear(struct hostapd_data *hapd) 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_broadcast_key_clear_iface(hapd, hapd->conf->iface); 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_broadcast_wep_set(struct hostapd_data *hapd) 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int errors = 0, idx; 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_ssid *ssid = &hapd->conf->ssid; 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idx = ssid->wep.idx; 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->wep.default_len && 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_drv_set_key(hapd->conf->iface, 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd, WPA_ALG_WEP, broadcast_ether_addr, idx, 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1, NULL, 0, ssid->wep.key[idx], 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->wep.len[idx])) { 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "Could not set WEP encryption."); 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt errors++; 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return errors; 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25304949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void hostapd_free_hapd_data(struct hostapd_data *hapd) 25404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 255fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt if (!hapd->started) { 256fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Interface %s wasn't started", 257fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt __func__, hapd->conf->iface); 258fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt return; 259fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt } 260fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt hapd->started = 0; 261fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt 2625460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface); 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iapp_deinit(hapd->iapp); 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iapp = NULL; 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt accounting_deinit(hapd); 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_deinit_wpa(hapd); 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt vlan_deinit(hapd); 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_acl_deinit(hapd); 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_client_deinit(hapd->radius); 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->radius = NULL; 27204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt radius_das_deinit(hapd->radius_das); 27304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hapd->radius_das = NULL; 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_deinit_wps(hapd); 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt authsrv_deinit(hapd); 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 280717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (hapd->interface_added) { 281717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hapd->interface_added = 0; 282717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (hostapd_if_remove(hapd, WPA_IF_AP_BSS, hapd->conf->iface)) { 283717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt wpa_printf(MSG_WARNING, 284717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt "Failed to remove BSS interface %s", 285717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hapd->conf->iface); 286717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hapd->interface_added = 1; 287717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt } else { 288717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt /* 289717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt * Since this was a dynamically added interface, the 290717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt * driver wrapper may have removed its internal instance 291717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt * and hapd->drv_priv is not valid anymore. 292717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt */ 293717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hapd->drv_priv = NULL; 294717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt } 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(hapd->probereq_cb); 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->probereq_cb = NULL; 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(hapd->p2p_beacon_ie); 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->p2p_beacon_ie = NULL; 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(hapd->p2p_probe_resp_ie); 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->p2p_probe_resp_ie = NULL; 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */ 3061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_free(hapd->time_adv); 30804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 30904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_INTERWORKING 31004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt gas_serv_deinit(hapd); 31104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_INTERWORKING */ 312d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 313d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SQLITE 314c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt bin_clear_free(hapd->tmp_eap_user.identity, 315c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt hapd->tmp_eap_user.identity_len); 316c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt bin_clear_free(hapd->tmp_eap_user.password, 317c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt hapd->tmp_eap_user.password_len); 318d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SQLITE */ 31904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 32004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 32104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 32204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/** 32304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * hostapd_cleanup - Per-BSS cleanup (deinitialization) 32404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @hapd: Pointer to BSS data 32504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * 32604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * This function is used to free all per-BSS data structures and resources. 3275460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt * Most of the modules that are initialized in hostapd_setup_bss() are 3285460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt * deinitialized here. 32904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 33004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void hostapd_cleanup(struct hostapd_data *hapd) 33104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 3325460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(hapd=%p (%s))", __func__, hapd, 3335460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd->conf->iface); 33461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd->iface->interfaces && 33561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd->iface->interfaces->ctrl_iface_deinit) 33661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd->iface->interfaces->ctrl_iface_deinit(hapd); 33704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_free_hapd_data(hapd); 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 34104949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void hostapd_cleanup_iface_partial(struct hostapd_iface *iface) 34204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 3435460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); 34404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_free_hw_features(iface->hw_features, iface->num_hw_features); 34504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt iface->hw_features = NULL; 34604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(iface->current_rates); 34704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt iface->current_rates = NULL; 34804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(iface->basic_rates); 34904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt iface->basic_rates = NULL; 35004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ap_list_deinit(iface); 35104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 35204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 35304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_cleanup_iface - Complete per-interface cleanup 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @iface: Pointer to interface data 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called after per-BSS data structures are deinitialized 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * with hostapd_cleanup(). 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_cleanup_iface(struct hostapd_iface *iface) 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3635460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); 364cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt eloop_cancel_timeout(channel_list_update_timeout, iface, NULL); 365cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 36604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_cleanup_iface_partial(iface); 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_config_free(iface->conf); 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->conf = NULL; 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(iface->config_fname); 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(iface->bss); 3725460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: free iface=%p", __func__, iface); 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(iface); 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void hostapd_clear_wep(struct hostapd_data *hapd) 37804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 379a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt if (hapd->drv_priv && !hapd->iface->driver_ap_teardown) { 38004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_set_privacy(hapd, 0); 38104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_broadcast_wep_clear(hapd); 38204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 38304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 38404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 38504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd) 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_broadcast_wep_set(hapd); 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ssid.wep.default_len) { 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_privacy(hapd, 1); 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 39875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * When IEEE 802.1X is not enabled, the driver may need to know how to 39975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * set authentication algorithms for static WEP. 40075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 40175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen hostapd_drv_set_authmode(hapd, hapd->conf->auth_algs); 40275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 4; i++) { 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ssid.wep.key[i] && 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_drv_set_key(iface, hapd, WPA_ALG_WEP, NULL, i, 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i == hapd->conf->ssid.wep.idx, NULL, 0, 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->ssid.wep.key[i], 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->ssid.wep.len[i])) { 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "Could not set WEP " 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "encryption."); 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ssid.wep.key[i] && 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i == hapd->conf->ssid.wep.idx) 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_privacy(hapd, 1); 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42204949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason) 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 addr[ETH_ALEN]; 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_drv_none(hapd) || hapd->drv_priv == NULL) 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 430a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt if (!hapd->iface->driver_ap_teardown) { 431a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt wpa_dbg(hapd->msg_ctx, MSG_DEBUG, 432a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt "Flushing old station entries"); 433a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt 434a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt if (hostapd_flush(hapd)) { 435a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt wpa_msg(hapd->msg_ctx, MSG_WARNING, 436a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt "Could not connect to kernel driver"); 437a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt ret = -1; 438a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt } 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "Deauthenticate all stations"); 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(addr, 0xff, ETH_ALEN); 44204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_drv_sta_deauth(hapd, addr, reason); 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_free_stas(hapd); 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 449717574375e969e8272c6d1a26137286eac158abbDmitry Shmidtstatic void hostapd_bss_deinit_no_free(struct hostapd_data *hapd) 450717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt{ 451717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_free_stas(hapd); 452717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING); 453717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_clear_wep(hapd); 454717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt} 455717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 456717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_validate_bssid_configuration - Validate BSSID configuration 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @iface: Pointer to interface data 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to validate that the configured BSSIDs are valid. 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_validate_bssid_configuration(struct hostapd_iface *iface) 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 mask[ETH_ALEN] = { 0 }; 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = iface->bss[0]; 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int i = iface->conf->num_bss, bits = 0, j; 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int auto_addr = 0; 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_drv_none(hapd)) 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Generate BSSID mask that is large enough to cover the BSSIDs. */ 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Determine the bits necessary to cover the number of BSSIDs. */ 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i--; i; i >>= 1) 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bits++; 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Determine the bits necessary to any configured BSSIDs, 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if they are higher than the number of BSSIDs. */ 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < iface->conf->num_bss; j++) { 483cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hostapd_mac_comp_empty(iface->conf->bss[j]->bssid) == 0) { 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (j) 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auto_addr++; 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < ETH_ALEN; i++) { 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mask[i] |= 491cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->bss[j]->bssid[i] ^ 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->own_addr[i]; 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!auto_addr) 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto skip_mask_ext; 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < ETH_ALEN && mask[i] == 0; i++) 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ; 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt j = 0; 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i < ETH_ALEN) { 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt j = (5 - i) * 8; 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (mask[i] != 0) { 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mask[i] >>= 1; 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt j++; 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bits < j) 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bits = j; 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bits > 40) { 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Too many bits in the BSSID mask (%u)", 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bits); 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(mask, 0xff, ETH_ALEN); 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt j = bits / 8; 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 5; i > 5 - j; i--) 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mask[i] = 0; 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt j = bits % 8; 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (j--) 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mask[i] <<= 1; 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtskip_mask_ext: 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "BSS count %lu, BSSID mask " MACSTR " (%d bits)", 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) iface->conf->num_bss, MAC2STR(mask), bits); 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!auto_addr) 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < ETH_ALEN; i++) { 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((hapd->own_addr[i] & mask[i]) != hapd->own_addr[i]) { 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Invalid BSSID mask " MACSTR 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " for start address " MACSTR ".", 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mask), MAC2STR(hapd->own_addr)); 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Start address must be the " 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "first address in the block (i.e., addr " 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "AND mask == addr)."); 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int mac_in_conf(struct hostapd_config *conf, const void *a) 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < conf->num_bss; i++) { 556cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hostapd_mac_comp(conf->bss[i]->bssid, a) == 0) { 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 56504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifndef CONFIG_NO_RADIUS 56604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 56704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int hostapd_das_nas_mismatch(struct hostapd_data *hapd, 56804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct radius_das_attrs *attr) 56904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 57013ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt if (attr->nas_identifier && 57113ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt (!hapd->conf->nas_identifier || 57213ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt os_strlen(hapd->conf->nas_identifier) != 57313ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt attr->nas_identifier_len || 57413ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt os_memcmp(hapd->conf->nas_identifier, attr->nas_identifier, 57513ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt attr->nas_identifier_len) != 0)) { 57613ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-Identifier mismatch"); 57713ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt return 1; 57813ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt } 57913ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt 58013ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt if (attr->nas_ip_addr && 58113ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt (hapd->conf->own_ip_addr.af != AF_INET || 58213ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt os_memcmp(&hapd->conf->own_ip_addr.u.v4, attr->nas_ip_addr, 4) != 58313ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt 0)) { 58413ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-IP-Address mismatch"); 58513ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt return 1; 58613ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt } 58713ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt 58813ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt#ifdef CONFIG_IPV6 58913ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt if (attr->nas_ipv6_addr && 59013ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt (hapd->conf->own_ip_addr.af != AF_INET6 || 59113ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt os_memcmp(&hapd->conf->own_ip_addr.u.v6, attr->nas_ipv6_addr, 16) 59213ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt != 0)) { 59313ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-IPv6-Address mismatch"); 59413ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt return 1; 59513ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt } 59613ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt#endif /* CONFIG_IPV6 */ 59713ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt 59804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 59904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 60004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 60104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 60204949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic struct sta_info * hostapd_das_find_sta(struct hostapd_data *hapd, 60304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct radius_das_attrs *attr) 60404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 60504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct sta_info *sta = NULL; 60604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt char buf[128]; 60704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 60804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (attr->sta_addr) 60904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sta = ap_get_sta(hapd, attr->sta_addr); 61004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 61104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (sta == NULL && attr->acct_session_id && 61204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt attr->acct_session_id_len == 17) { 61304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (sta = hapd->sta_list; sta; sta = sta->next) { 61404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_snprintf(buf, sizeof(buf), "%08X-%08X", 61504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sta->acct_session_id_hi, 61604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sta->acct_session_id_lo); 61704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (os_memcmp(attr->acct_session_id, buf, 17) == 0) 61804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 61904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 62004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 62104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 62204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (sta == NULL && attr->cui) { 62304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (sta = hapd->sta_list; sta; sta = sta->next) { 62404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpabuf *cui; 62504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cui = ieee802_1x_get_radius_cui(sta->eapol_sm); 62604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (cui && wpabuf_len(cui) == attr->cui_len && 62704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcmp(wpabuf_head(cui), attr->cui, 62804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt attr->cui_len) == 0) 62904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 63004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 63104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 63204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 63304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (sta == NULL && attr->user_name) { 63404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (sta = hapd->sta_list; sta; sta = sta->next) { 63504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 *identity; 63604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt size_t identity_len; 63704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt identity = ieee802_1x_get_identity(sta->eapol_sm, 63804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt &identity_len); 63904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (identity && 64004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt identity_len == attr->user_name_len && 64104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcmp(identity, attr->user_name, identity_len) 64204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt == 0) 64304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 64404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 64504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 64604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 64704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return sta; 64804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 64904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 65004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 65104949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic enum radius_das_res 65204949598a23f501be6eec21697465fd46a28840aDmitry Shmidthostapd_das_disconnect(void *ctx, struct radius_das_attrs *attr) 65304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 65404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct hostapd_data *hapd = ctx; 65504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct sta_info *sta; 65604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 65704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (hostapd_das_nas_mismatch(hapd, attr)) 65804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return RADIUS_DAS_NAS_MISMATCH; 65904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 66004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sta = hostapd_das_find_sta(hapd, attr); 66104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (sta == NULL) 66204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return RADIUS_DAS_SESSION_NOT_FOUND; 66304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 66413ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr); 66513ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt 66604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_drv_sta_deauth(hapd, sta->addr, 66704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt WLAN_REASON_PREV_AUTH_NOT_VALID); 66804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ap_sta_deauthenticate(hapd, sta, WLAN_REASON_PREV_AUTH_NOT_VALID); 66904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 67004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return RADIUS_DAS_SUCCESS; 67104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 67204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 67304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_setup_bss - Per-BSS setup (initialization) 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hapd: Pointer to BSS data 679cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * @first: Whether this BSS is the first BSS of an interface; -1 = not first, 680cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * but interface may exist 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to initialize all per-BSS data structures and 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * resources. This gets called in a loop for each BSS when an interface is 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * initialized. Most of the modules that are initialized here will be 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * deinitialized in hostapd_cleanup(). 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_setup_bss(struct hostapd_data *hapd, int first) 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_bss_config *conf = hapd->conf; 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ssid[HOSTAPD_MAX_SSID_LEN + 1]; 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ssid_len, set_ssid; 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char force_ifname[IFNAMSIZ]; 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 if_addr[ETH_ALEN]; 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6955460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(hapd=%p (%s), first=%d)", 696661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt __func__, hapd, conf->iface, first); 6975460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 69850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt#ifdef EAP_SERVER_TNC 699661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (conf->tnc && tncs_global_init() < 0) { 70050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to initialize TNCS"); 70150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt return -1; 70250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt } 70350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt#endif /* EAP_SERVER_TNC */ 70450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 7055460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt if (hapd->started) { 7065460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Interface %s was already started", 707661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt __func__, conf->iface); 7085460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt return -1; 7095460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt } 7105460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd->started = 1; 7115460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 712cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!first || first == -1) { 713661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (hostapd_mac_comp_empty(conf->bssid) == 0) { 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Allocate the next available BSSID. */ 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt do { 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt inc_byte_array(hapd->own_addr, ETH_ALEN); 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } while (mac_in_conf(hapd->iconf, hapd->own_addr)); 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Allocate the configured BSSID. */ 720661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt os_memcpy(hapd->own_addr, conf->bssid, ETH_ALEN); 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_mac_comp(hapd->own_addr, 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface->bss[0]->own_addr) == 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "BSS '%s' may not have " 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "BSSID set to the MAC address of " 727661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt "the radio", conf->iface); 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7325460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd->interface_added = 1; 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_if_add(hapd->iface->bss[0], WPA_IF_AP_BSS, 734661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt conf->iface, hapd->own_addr, hapd, 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &hapd->drv_priv, force_ifname, if_addr, 736661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt conf->bridge[0] ? conf->bridge : NULL, 737661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt first == -1)) { 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to add BSS (BSSID=" 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR ")", MAC2STR(hapd->own_addr)); 7403cf6f79011d16f23e60cbf2846aab0fd440511daDmitry Shmidt hapd->interface_added = 0; 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->wmm_enabled < 0) 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->wmm_enabled = hapd->iconf->ieee80211n; 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 74804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_flush_old_stations(hapd, WLAN_REASON_PREV_AUTH_NOT_VALID); 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_privacy(hapd, 0); 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_broadcast_wep_clear(hapd); 752661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (hostapd_setup_encryption(conf->iface, hapd)) 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Fetch the SSID from the system and use it or, 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * if one was specified in the config file, verify they 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * match. 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid_len = hostapd_get_ssid(hapd, ssid, sizeof(ssid)); 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid_len < 0) { 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not read SSID from system"); 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->ssid.ssid_set) { 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If SSID is specified in the config file and it differs 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * from what is being used then force installation of the 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * new SSID. 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt set_ssid = (conf->ssid.ssid_len != (size_t) ssid_len || 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(conf->ssid.ssid, ssid, ssid_len) != 0); 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * No SSID in the config file; just use the one we got 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * from the system. 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt set_ssid = 0; 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->ssid.ssid_len = ssid_len; 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conf->ssid.ssid, ssid, conf->ssid.ssid_len); 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!hostapd_drv_none(hapd)) { 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Using interface %s with hwaddr " MACSTR 78561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt " and ssid \"%s\"", 786661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt conf->iface, MAC2STR(hapd->own_addr), 787661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt wpa_ssid_txt(conf->ssid.ssid, conf->ssid.ssid_len)); 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_setup_wpa_psk(conf)) { 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "WPA-PSK setup failed."); 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Set SSID for the kernel driver (to be used in beacon and probe 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * response frames) */ 79761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (set_ssid && hostapd_set_ssid(hapd, conf->ssid.ssid, 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->ssid.ssid_len)) { 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver"); 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 803818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (wpa_debug_level <= MSG_MSGDUMP) 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->radius->msg_dumps = 1; 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->radius = radius_client_init(hapd, conf->radius); 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->radius == NULL) { 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "RADIUS client initialization failed."); 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 81104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 812661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (conf->radius_das_port) { 81304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct radius_das_conf das_conf; 81404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memset(&das_conf, 0, sizeof(das_conf)); 815661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt das_conf.port = conf->radius_das_port; 816661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt das_conf.shared_secret = conf->radius_das_shared_secret; 81704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt das_conf.shared_secret_len = 818661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt conf->radius_das_shared_secret_len; 819661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt das_conf.client_addr = &conf->radius_das_client_addr; 820661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt das_conf.time_window = conf->radius_das_time_window; 82104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt das_conf.require_event_timestamp = 822661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt conf->radius_das_require_event_timestamp; 82304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt das_conf.ctx = hapd; 82404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt das_conf.disconnect = hostapd_das_disconnect; 82504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hapd->radius_das = radius_das_init(&das_conf); 82604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (hapd->radius_das == NULL) { 82704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_ERROR, "RADIUS DAS initialization " 82804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "failed."); 82904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 83004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 83104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_acl_init(hapd)) { 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ACL initialization failed."); 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_init_wps(hapd, conf)) 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (authsrv_init(hapd) < 0) 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ieee802_1x_init(hapd)) { 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "IEEE 802.1X initialization failed."); 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 849661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if ((conf->wpa || conf->osen) && hostapd_setup_wpa(hapd)) 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (accounting_init(hapd)) { 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Accounting initialization failed."); 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 857661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (conf->ieee802_11f && 858661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt (hapd->iapp = iapp_init(hapd, conf->iapp_iface)) == NULL) { 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "IEEE 802.11F (IAPP) initialization " 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed."); 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 86404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_INTERWORKING 86504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (gas_serv_init(hapd)) { 86604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_ERROR, "GAS server initialization failed"); 86704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 86804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 86904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 870cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (conf->qos_map_set_len && 871cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_drv_set_qos_map(hapd, conf->qos_map_set, 872cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf->qos_map_set_len)) { 873cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to initialize QoS Map"); 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 876cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#endif /* CONFIG_INTERWORKING */ 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!hostapd_drv_none(hapd) && vlan_init(hapd)) { 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "VLAN initialization failed."); 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 883661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (!conf->start_disabled && ieee802_11_set_beacon(hapd) < 0) 884fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return -1; 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (hapd->wpa_auth && wpa_init_keys(hapd->wpa_auth) < 0) 8871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 8881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->driver && hapd->driver->set_operstate) 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->driver->set_operstate(hapd->drv_priv, 1); 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_tx_queue_params(struct hostapd_iface *iface) 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = iface->bss[0]; 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_tx_queue_params *p; 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < NUM_TX_QUEUES; i++) { 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = &iface->conf->tx_queue[i]; 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_set_tx_queue_params(hapd, i, p->aifs, p->cwmin, 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p->cwmax, p->burst)) { 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to set TX queue " 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "parameters for queue %d.", i); 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Continue anyway */ 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9158bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidtstatic int hostapd_set_acl_list(struct hostapd_data *hapd, 9168bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt struct mac_acl_entry *mac_acl, 9178bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt int n_entries, u8 accept_acl) 9188bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt{ 9198bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt struct hostapd_acl_params *acl_params; 9208bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt int i, err; 9218bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 9228bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt acl_params = os_zalloc(sizeof(*acl_params) + 9238bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt (n_entries * sizeof(acl_params->mac_acl[0]))); 9248bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt if (!acl_params) 9258bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt return -ENOMEM; 9268bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 9278bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt for (i = 0; i < n_entries; i++) 9288bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt os_memcpy(acl_params->mac_acl[i].addr, mac_acl[i].addr, 9298bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt ETH_ALEN); 9308bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 9318bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt acl_params->acl_policy = accept_acl; 9328bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt acl_params->num_mac_acl = n_entries; 9338bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 9348bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt err = hostapd_drv_set_acl(hapd, acl_params); 9358bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 9368bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt os_free(acl_params); 9378bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 9388bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt return err; 9398bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt} 9408bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 9418bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 9428bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidtstatic void hostapd_set_acl(struct hostapd_data *hapd) 9438bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt{ 9448bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt struct hostapd_config *conf = hapd->iconf; 9458bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt int err; 9468bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt u8 accept_acl; 9478bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 9488bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt if (hapd->iface->drv_max_acl_mac_addrs == 0) 9498bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt return; 9508bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 951cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (conf->bss[0]->macaddr_acl == DENY_UNLESS_ACCEPTED) { 95243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt accept_acl = 1; 95343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt err = hostapd_set_acl_list(hapd, conf->bss[0]->accept_mac, 95443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt conf->bss[0]->num_accept_mac, 95543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt accept_acl); 95643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (err) { 95743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to set accept acl"); 95843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt return; 9598bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } 960cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } else if (conf->bss[0]->macaddr_acl == ACCEPT_UNLESS_DENIED) { 96143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt accept_acl = 0; 96243cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt err = hostapd_set_acl_list(hapd, conf->bss[0]->deny_mac, 96343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt conf->bss[0]->num_deny_mac, 96443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt accept_acl); 96543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (err) { 96643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to set deny acl"); 96743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt return; 9688bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } 9698bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } 9708bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt} 9718bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 9728bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 973cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic int start_ctrl_iface_bss(struct hostapd_data *hapd) 974cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 975cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!hapd->iface->interfaces || 976cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt !hapd->iface->interfaces->ctrl_iface_init) 977cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 978cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 979cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd->iface->interfaces->ctrl_iface_init(hapd)) { 980cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, 981cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "Failed to setup control interface for %s", 982cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->conf->iface); 983cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 984cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 985cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 986cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 987cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 988cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 989cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 990cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic int start_ctrl_iface(struct hostapd_iface *iface) 991cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 992cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i; 993cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 994cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!iface->interfaces || !iface->interfaces->ctrl_iface_init) 995cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 996cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 997cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (i = 0; i < iface->num_bss; i++) { 998cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_data *hapd = iface->bss[i]; 999cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (iface->interfaces->ctrl_iface_init(hapd)) { 1000cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, 1001cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "Failed to setup control interface for %s", 1002cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->conf->iface); 1003cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 1004cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1005cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1006cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1007cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 1008cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 1009cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1010cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1011cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic void channel_list_update_timeout(void *eloop_ctx, void *timeout_ctx) 1012cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 1013cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface *iface = eloop_ctx; 1014cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1015cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!iface->wait_channel_update) { 1016cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "Channel list update timeout, but interface was not waiting for it"); 1017cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return; 1018cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1019cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1020cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* 1021cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * It is possible that the existing channel list is acceptable, so try 1022cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * to proceed. 1023cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 1024cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_DEBUG, "Channel list update timeout - try to continue anyway"); 1025cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt setup_interface2(iface); 1026cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 1027cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1028cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1029e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtvoid hostapd_channel_list_updated(struct hostapd_iface *iface, int initiator) 1030cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 1031e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!iface->wait_channel_update || initiator != REGDOM_SET_BY_USER) 1032cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return; 1033cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1034cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_DEBUG, "Channel list updated - continue setup"); 1035cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt eloop_cancel_timeout(channel_list_update_timeout, iface, NULL); 1036cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt setup_interface2(iface); 1037cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 1038cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1039cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int setup_interface(struct hostapd_iface *iface) 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = iface->bss[0]; 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 1044cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1045a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt /* 1046a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt * It is possible that setup_interface() is called after the interface 1047a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt * was disabled etc., in which case driver_ap_teardown is possibly set 1048a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt * to 1. Clear it here so any other key/station deletion, which is not 1049a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt * part of a teardown flow, would also call the relevant driver 1050a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt * callbacks. 1051a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt */ 1052a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt iface->driver_ap_teardown = 0; 1053a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt 1054cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!iface->phy[0]) { 1055cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt const char *phy = hostapd_drv_get_radio_name(hapd); 1056cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (phy) { 1057cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_DEBUG, "phy: %s", phy); 1058cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_strlcpy(iface->phy, phy, sizeof(iface->phy)); 1059cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1060cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Make sure that all BSSes get configured with a pointer to the same 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * driver interface. 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 1; i < iface->num_bss; i++) { 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->bss[i]->driver = hapd->driver; 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->bss[i]->drv_priv = hapd->drv_priv; 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_validate_bssid_configuration(iface)) 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1074cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* 1075cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * Initialize control interfaces early to allow external monitoring of 1076cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * channel setup operations that may take considerable amount of time 1077cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * especially for DFS cases. 1078cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 1079cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (start_ctrl_iface(iface)) 1080cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 1081cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iconf->country[0] && hapd->iconf->country[1]) { 1083cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt char country[4], previous_country[4]; 1084cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1085cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_set_state(iface, HAPD_IFACE_COUNTRY_UPDATE); 1086cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hostapd_get_country(hapd, previous_country) < 0) 1087cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt previous_country[0] = '\0'; 1088cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(country, hapd->iconf->country, 3); 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt country[3] = '\0'; 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_set_country(hapd, country) < 0) { 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to set country code"); 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1095cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1096cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_DEBUG, "Previous country code %s, new country code %s", 1097cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt previous_country, country); 1098cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1099cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (os_strncmp(previous_country, country, 2) != 0) { 1100cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_DEBUG, "Continue interface setup after channel list update"); 1101cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->wait_channel_update = 1; 11029767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt eloop_register_timeout(5, 0, 1103cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt channel_list_update_timeout, 1104cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface, NULL); 1105cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 1106cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1109cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return setup_interface2(iface); 1110cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 1111cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1112cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1113cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic int setup_interface2(struct hostapd_iface *iface) 1114cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 1115cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->wait_channel_update = 0; 1116cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_get_hw_features(iface)) { 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Not all drivers support this yet, so continue without hw 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * feature data. */ 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = hostapd_select_hw_mode(iface); 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) { 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not select hw_mode and " 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel. (%d)", ret); 1125b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1127391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (ret == 1) { 1128391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_DEBUG, "Interface initialization will be completed in a callback (ACS)"); 1129391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return 0; 1130391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = hostapd_check_ht_capab(iface); 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) 1133b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret == 1) { 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Interface initialization will " 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "be completed in a callback"); 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1139051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1140051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (iface->conf->ieee80211h) 1141051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_printf(MSG_DEBUG, "DFS support is enabled"); 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return hostapd_setup_interface_complete(iface, 0); 1144b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt 1145b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidtfail: 1146b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt hostapd_set_state(iface, HAPD_IFACE_DISABLED); 1147b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_DISABLED); 1148b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (iface->interfaces && iface->interfaces->terminate_on_error) 1149b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt eloop_terminate(); 1150b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt return -1; 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1154cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt/** 1155cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_setup_interface_complete - Complete interface setup 1156cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * 1157cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * This function is called when previous steps in the interface setup has been 1158cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * completed. This can also start operations, e.g., DFS, that will require 1159cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * additional processing before interface is ready to be enabled. Such 1160cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * operations will call this function from eloop callbacks when finished. 1161cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_setup_interface_complete(struct hostapd_iface *iface, int err) 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = iface->bss[0]; 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t j; 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *prev_addr; 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1168b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (err) 1169b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Completing interface initialization"); 1172cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (iface->conf->channel) { 1173051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#ifdef NEED_AP_MLME 1174051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt int res; 1175051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#endif /* NEED_AP_MLME */ 1176051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1177cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->freq = hostapd_hw_get_freq(hapd, iface->conf->channel); 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Mode: %s Channel: %d " 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Frequency: %d MHz", 1180cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_hw_mode_txt(iface->conf->hw_mode), 1181cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->channel, iface->freq); 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1183051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#ifdef NEED_AP_MLME 1184661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt /* Handle DFS only if it is not offloaded to the driver */ 1185661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (!(iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)) { 1186661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt /* Check DFS */ 1187661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt res = hostapd_handle_dfs(iface); 1188661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (res <= 0) { 1189661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (res < 0) 1190661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt goto fail; 1191661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return res; 1192661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt } 1193b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt } 1194051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#endif /* NEED_AP_MLME */ 1195051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_set_freq(hapd, hapd->iconf->hw_mode, iface->freq, 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iconf->channel, 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iconf->ieee80211n, 1199a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hapd->iconf->ieee80211ac, 1200a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hapd->iconf->secondary_channel, 1201a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hapd->iconf->vht_oper_chwidth, 1202a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hapd->iconf->vht_oper_centr_freq_seg0_idx, 1203a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hapd->iconf->vht_oper_centr_freq_seg1_idx)) { 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not set channel for " 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "kernel driver"); 1206b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface->current_mode) { 12111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (hostapd_prepare_rates(iface, iface->current_mode)) { 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to prepare rates " 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "table."); 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_WARNING, 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to prepare rates table."); 1217b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iconf->rts_threshold > -1 && 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_rts(hapd, hapd->iconf->rts_threshold)) { 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not set RTS threshold for " 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "kernel driver"); 1225b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iconf->fragm_threshold > -1 && 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_frag(hapd, hapd->iconf->fragm_threshold)) { 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not set fragmentation threshold " 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for kernel driver"); 1232b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev_addr = hapd->own_addr; 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd = iface->bss[j]; 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (j) 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN); 1241717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (hostapd_setup_bss(hapd, j == 0)) { 1242717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt do { 1243717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hapd = iface->bss[j]; 1244717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_bss_deinit_no_free(hapd); 1245717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_free_hapd_data(hapd); 1246717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt } while (j-- > 0); 1247b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 1248717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt } 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0) 12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev_addr = hapd->own_addr; 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1252cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd = iface->bss[0]; 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_tx_queue_params(iface); 12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_list_init(iface); 12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12588bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt hostapd_set_acl(hapd); 12598bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_driver_commit(hapd) < 0) { 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Failed to commit driver " 12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "configuration", __func__); 1263b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 126687fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen /* 126787fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen * WPS UPnP module can be initialized only when the "upnp_iface" is up. 126887fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen * If "interface" and "upnp_iface" are the same (e.g., non-bridge 126987fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen * mode), the interface is up only after driver_commit, so initialize 127087fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen * WPS after driver_commit. 127187fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen */ 127287fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen for (j = 0; j < iface->num_bss; j++) { 127387fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen if (hostapd_init_wps_complete(iface->bss[j])) 1274b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 127587fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen } 127687fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen 1277cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_set_state(iface, HAPD_IFACE_ENABLED); 1278cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_ENABLED); 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->setup_complete_cb) 12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->setup_complete_cb(hapd->setup_complete_cb_ctx); 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: Setup of interface done.", 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->bss[0]->conf->iface); 1284b96dad47218788efffa3db0fe7f1b54a7d19e366Dmitry Shmidt if (iface->interfaces && iface->interfaces->terminate_on_error > 0) 1285b96dad47218788efffa3db0fe7f1b54a7d19e366Dmitry Shmidt iface->interfaces->terminate_on_error--; 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1288b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt 1289b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidtfail: 1290b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt wpa_printf(MSG_ERROR, "Interface initialization failed"); 1291b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt hostapd_set_state(iface, HAPD_IFACE_DISABLED); 1292b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED); 1293b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (iface->interfaces && iface->interfaces->terminate_on_error) 1294b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt eloop_terminate(); 1295b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt return -1; 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_setup_interface - Setup of an interface 13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @iface: Pointer to interface data. 13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Initializes the driver interface, validates the configuration, 13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * and sets driver parameters based on the configuration. 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Flushes old stations, sets the channel, encryption, 13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * beacons, and WDS links based on the configuration. 1308cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * 1309cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * If interface setup requires more time, e.g., to perform HT co-ex scans, ACS, 1310cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * or DFS operations, this function returns 0 before such operations have been 1311cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * completed. The pending operations are registered into eloop and will be 1312cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * completed from eloop callbacks. Those callbacks end up calling 1313cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_setup_interface_complete() once setup has been completed. 13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_setup_interface(struct hostapd_iface *iface) 13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = setup_interface(iface); 13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) { 13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Unable to setup interface.", 13228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->bss[0]->conf->iface); 13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 13278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_alloc_bss_data - Allocate and initialize per-BSS data 13328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hapd_iface: Pointer to interface data 13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conf: Pointer to per-interface configuration 13348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @bss: Pointer to per-BSS configuration for this BSS 13358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to allocated BSS data 13368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to allocate per-BSS data structure. This data will be 13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * freed after hostapd_cleanup() is called for it during interface 13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * deinitialization. 13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct hostapd_data * 13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidthostapd_alloc_bss_data(struct hostapd_iface *hapd_iface, 13438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_config *conf, 13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_bss_config *bss) 13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd; 13478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd = os_zalloc(sizeof(*hapd)); 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd == NULL) 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->new_assoc_sta_cb = hostapd_new_assoc_sta; 13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iconf = conf; 13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf = bss; 13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface = hapd_iface; 13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->driver = hapd->iconf->driver; 135704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hapd->ctrl_sock = -1; 13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return hapd; 13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13635460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidtstatic void hostapd_bss_deinit(struct hostapd_data *hapd) 13645460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt{ 13655460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: deinit bss %s", __func__, 13665460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd->conf->iface); 1367717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_bss_deinit_no_free(hapd); 13685460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_cleanup(hapd); 13695460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt} 13705460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 13715460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid hostapd_interface_deinit(struct hostapd_iface *iface) 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1374cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt int j; 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13765460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); 13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface == NULL) 13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13807832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt#ifdef CONFIG_IEEE80211N 13817832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt#ifdef NEED_AP_MLME 13827832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt hostapd_stop_setup_timers(iface); 13837832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt eloop_cancel_timeout(ap_ht2040_timeout, iface, NULL); 13847832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt#endif /* NEED_AP_MLME */ 13857832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt#endif /* CONFIG_IEEE80211N */ 1386cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt eloop_cancel_timeout(channel_list_update_timeout, iface, NULL); 1387cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->wait_channel_update = 0; 1388cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 13895460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt for (j = iface->num_bss - 1; j >= 0; j--) 13905460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_bss_deinit(iface->bss[j]); 13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid hostapd_interface_free(struct hostapd_iface *iface) 13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t j; 13975460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); 13985460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 13995460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: free hapd %p", 14005460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, iface->bss[j]); 14018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(iface->bss[j]); 14025460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt } 14038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_cleanup_iface(iface); 14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1407cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt/** 1408cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_init - Allocate and initialize per-interface data 1409cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * @config_file: Path to the configuration file 1410cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * Returns: Pointer to the allocated interface data or %NULL on failure 1411cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * 1412cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * This function is used to allocate main data structures for per-interface 1413cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * data. The allocated data buffer will be freed by calling 1414cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_cleanup_iface(). 1415cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 1416cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstruct hostapd_iface * hostapd_init(struct hapd_interfaces *interfaces, 1417cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt const char *config_file) 1418cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 1419cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface *hapd_iface = NULL; 1420cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_config *conf = NULL; 1421cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_data *hapd; 1422cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i; 1423cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1424cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface = os_zalloc(sizeof(*hapd_iface)); 1425cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd_iface == NULL) 1426cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto fail; 1427cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1428cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->config_fname = os_strdup(config_file); 1429cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd_iface->config_fname == NULL) 1430cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto fail; 1431cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1432cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf = interfaces->config_read_cb(hapd_iface->config_fname); 1433cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (conf == NULL) 1434cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto fail; 1435cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->conf = conf; 1436cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1437cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->num_bss = conf->num_bss; 1438cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->bss = os_calloc(conf->num_bss, 1439cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt sizeof(struct hostapd_data *)); 1440cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd_iface->bss == NULL) 1441cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto fail; 1442cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1443cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (i = 0; i < conf->num_bss; i++) { 1444cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd = hapd_iface->bss[i] = 1445cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_alloc_bss_data(hapd_iface, conf, 1446cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf->bss[i]); 1447cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd == NULL) 1448cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto fail; 1449cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->msg_ctx = hapd; 1450cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1451cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1452cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return hapd_iface; 1453cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1454cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtfail: 1455cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to set up interface with %s", 1456cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt config_file); 1457cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (conf) 1458cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_config_free(conf); 1459cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd_iface) { 1460cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_free(hapd_iface->config_fname); 1461cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_free(hapd_iface->bss); 14625460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: free iface %p", 14635460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, hapd_iface); 1464cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_free(hapd_iface); 1465cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1466cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1467cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 1468cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1469cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1470cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic int ifname_in_use(struct hapd_interfaces *interfaces, const char *ifname) 1471cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 1472cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i, j; 1473cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1474cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (i = 0; i < interfaces->count; i++) { 1475cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface *iface = interfaces->iface[i]; 1476cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 1477cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_data *hapd = iface->bss[j]; 1478cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (os_strcmp(ifname, hapd->conf->iface) == 0) 1479cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 1; 1480cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1481cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1482cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1483cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 1484cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 1485cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1486cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1487cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt/** 1488cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_interface_init_bss - Read configuration file and init BSS data 1489cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * 1490cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * This function is used to parse configuration file for a BSS. This BSS is 1491cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * added to an existing interface sharing the same radio (if any) or a new 1492cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * interface is created if this is the first interface on a radio. This 1493cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * allocate memory for the BSS. No actual driver operations are started. 1494cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * 1495cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * This is similar to hostapd_interface_init(), but for a case where the 1496cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * configuration is used to add a single BSS instead of all BSSes for a radio. 1497cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 1498cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstruct hostapd_iface * 1499cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidthostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy, 1500cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt const char *config_fname, int debug) 1501cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 1502cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface *new_iface = NULL, *iface = NULL; 1503cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_data *hapd; 1504cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt int k; 1505cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i, bss_idx; 1506cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1507cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!phy || !*phy) 1508cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1509cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1510cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (i = 0; i < interfaces->count; i++) { 1511cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (os_strcmp(interfaces->iface[i]->phy, phy) == 0) { 1512cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface = interfaces->iface[i]; 1513cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt break; 1514cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1515cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1516cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1517cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "Configuration file: %s (phy %s)%s", 1518cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt config_fname, phy, iface ? "" : " --> new PHY"); 1519cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (iface) { 1520cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_config *conf; 1521cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_bss_config **tmp_conf; 1522cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_data **tmp_bss; 1523cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_bss_config *bss; 1524cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt const char *ifname; 1525cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1526cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* Add new BSS to existing iface */ 1527cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf = interfaces->config_read_cb(config_fname); 1528cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (conf == NULL) 1529cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1530cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (conf->num_bss > 1) { 1531cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "Multiple BSSes specified in BSS-config"); 1532cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_config_free(conf); 1533cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1534cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1535cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1536cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt ifname = conf->bss[0]->iface; 1537cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (ifname[0] != '\0' && ifname_in_use(interfaces, ifname)) { 1538cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, 1539cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "Interface name %s already in use", ifname); 1540cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_config_free(conf); 1541cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1542cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1543cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1544cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt tmp_conf = os_realloc_array( 1545cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->bss, iface->conf->num_bss + 1, 1546cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt sizeof(struct hostapd_bss_config *)); 1547cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt tmp_bss = os_realloc_array(iface->bss, iface->num_bss + 1, 1548cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt sizeof(struct hostapd_data *)); 1549cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (tmp_bss) 1550cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->bss = tmp_bss; 1551cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (tmp_conf) { 1552cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->bss = tmp_conf; 1553cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->last_bss = tmp_conf[0]; 1554cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1555cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (tmp_bss == NULL || tmp_conf == NULL) { 1556cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_config_free(conf); 1557cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1558cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1559cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt bss = iface->conf->bss[iface->conf->num_bss] = conf->bss[0]; 1560cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->num_bss++; 1561cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1562cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd = hostapd_alloc_bss_data(iface, iface->conf, bss); 1563cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd == NULL) { 1564cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->num_bss--; 1565cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_config_free(conf); 1566cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1567cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1568cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->last_bss = bss; 1569cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->bss[iface->num_bss] = hapd; 1570cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->msg_ctx = hapd; 1571cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1572cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt bss_idx = iface->num_bss++; 1573cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf->num_bss--; 1574cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf->bss[0] = NULL; 1575cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_config_free(conf); 1576cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } else { 1577cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* Add a new iface with the first BSS */ 1578cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt new_iface = iface = hostapd_init(interfaces, config_fname); 1579cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!iface) 1580cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1581cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_strlcpy(iface->phy, phy, sizeof(iface->phy)); 1582cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->interfaces = interfaces; 1583cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt bss_idx = 0; 1584cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1585cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1586cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (k = 0; k < debug; k++) { 1587cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (iface->bss[bss_idx]->conf->logger_stdout_level > 0) 1588cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->bss[bss_idx]->conf->logger_stdout_level--; 1589cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1590cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1591cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (iface->conf->bss[bss_idx]->iface[0] == '\0' && 1592cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt !hostapd_drv_none(iface->bss[bss_idx])) { 1593cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "Interface name not specified in %s", 1594cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt config_fname); 1595cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (new_iface) 1596cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_interface_deinit_free(new_iface); 1597cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1598cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1599cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1600cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return iface; 1601cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 1602cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 160361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 160461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid hostapd_interface_deinit_free(struct hostapd_iface *iface) 160561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 160661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const struct wpa_driver_ops *driver; 160761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt void *drv_priv; 16085460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 16095460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); 161061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (iface == NULL) 161161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 16125460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: num_bss=%u conf->num_bss=%u", 16135460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, (unsigned int) iface->num_bss, 16145460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt (unsigned int) iface->conf->num_bss); 161561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt driver = iface->bss[0]->driver; 161661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt drv_priv = iface->bss[0]->drv_priv; 161761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_interface_deinit(iface); 16185460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", 16195460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, driver, drv_priv); 1620717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (driver && driver->hapd_deinit && drv_priv) { 162161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt driver->hapd_deinit(drv_priv); 1622717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt iface->bss[0]->drv_priv = NULL; 1623717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt } 162461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_interface_free(iface); 162561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 162661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 162761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 162815907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidtstatic void hostapd_deinit_driver(const struct wpa_driver_ops *driver, 162915907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt void *drv_priv, 163015907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt struct hostapd_iface *hapd_iface) 163115907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt{ 163215907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt size_t j; 163315907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt 163415907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", 163515907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt __func__, driver, drv_priv); 163615907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt if (driver && driver->hapd_deinit && drv_priv) { 163715907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt driver->hapd_deinit(drv_priv); 163815907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt for (j = 0; j < hapd_iface->num_bss; j++) { 163915907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s:bss[%d]->drv_priv=%p", 164015907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt __func__, (int) j, 164115907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt hapd_iface->bss[j]->drv_priv); 164215907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt if (hapd_iface->bss[j]->drv_priv == drv_priv) 164315907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt hapd_iface->bss[j]->drv_priv = NULL; 164415907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt } 164515907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt } 164615907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt} 164715907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt 164815907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt 164961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint hostapd_enable_iface(struct hostapd_iface *hapd_iface) 165061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 1651717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt size_t j; 1652717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 165361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface->bss[0]->drv_priv != NULL) { 165461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "Interface %s already enabled", 1655cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->conf->bss[0]->iface); 165661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 165761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 165861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 165961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "Enable interface %s", 1660cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->conf->bss[0]->iface); 166161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1662717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt for (j = 0; j < hapd_iface->num_bss; j++) 1663717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_set_security_params(hapd_iface->conf->bss[j], 1); 1664344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt if (hostapd_config_check(hapd_iface->conf, 1) < 0) { 1665344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt wpa_printf(MSG_INFO, "Invalid configuration - cannot enable"); 1666344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt return -1; 1667344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt } 1668344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt 166961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface->interfaces == NULL || 167061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface->interfaces->driver_init == NULL || 1671cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->interfaces->driver_init(hapd_iface)) 1672cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 1673cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1674cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hostapd_setup_interface(hapd_iface)) { 167515907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt hostapd_deinit_driver(hapd_iface->bss[0]->driver, 167615907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt hapd_iface->bss[0]->drv_priv, 167715907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt hapd_iface); 167861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 167961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 1680cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 168161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 168261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 168361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 168461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 168561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint hostapd_reload_iface(struct hostapd_iface *hapd_iface) 168661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 168761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t j; 168861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 168961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "Reload interface %s", 1690cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->conf->bss[0]->iface); 1691cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (j = 0; j < hapd_iface->num_bss; j++) 1692717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_set_security_params(hapd_iface->conf->bss[j], 1); 1693344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt if (hostapd_config_check(hapd_iface->conf, 1) < 0) { 1694cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "Updated configuration is invalid"); 1695cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 169661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 1697cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_clear_old(hapd_iface); 1698cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (j = 0; j < hapd_iface->num_bss; j++) 1699cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_reload_bss(hapd_iface->bss[j]); 1700cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 170161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 170261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 170361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 170461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 170561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint hostapd_disable_iface(struct hostapd_iface *hapd_iface) 170661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 170761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t j; 170861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const struct wpa_driver_ops *driver; 170961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt void *drv_priv; 171061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 171161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface == NULL) 171261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 1713717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 1714717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (hapd_iface->bss[0]->drv_priv == NULL) { 1715717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt wpa_printf(MSG_INFO, "Interface %s already disabled", 1716717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hapd_iface->conf->bss[0]->iface); 1717717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt return -1; 1718717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt } 1719717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 1720cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_msg(hapd_iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_DISABLED); 172161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt driver = hapd_iface->bss[0]->driver; 172261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt drv_priv = hapd_iface->bss[0]->drv_priv; 172361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1724a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt hapd_iface->driver_ap_teardown = 1725a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt !!(hapd_iface->drv_flags & 1726a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT); 1727a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt 1728a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt /* same as hostapd_interface_deinit without deinitializing ctrl-iface */ 172961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (j = 0; j < hapd_iface->num_bss; j++) { 173061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_data *hapd = hapd_iface->bss[j]; 1731717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_bss_deinit_no_free(hapd); 173261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_free_hapd_data(hapd); 173361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 173461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 173515907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt hostapd_deinit_driver(driver, drv_priv, hapd_iface); 173661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 173761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* From hostapd_cleanup_iface: These were initialized in 173861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * hostapd_setup_interface and hostapd_setup_interface_complete 173961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 174061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_cleanup_iface_partial(hapd_iface); 174161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 17425605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_printf(MSG_DEBUG, "Interface %s disabled", 17435605286c30e1701491bd3af974ae423727750eddDmitry Shmidt hapd_iface->bss[0]->conf->iface); 1744cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_set_state(hapd_iface, HAPD_IFACE_DISABLED); 174561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 174661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 174761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 174861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 174961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic struct hostapd_iface * 175061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidthostapd_iface_alloc(struct hapd_interfaces *interfaces) 175161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 175261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_iface **iface, *hapd_iface; 175361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 175461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt iface = os_realloc_array(interfaces->iface, interfaces->count + 1, 175561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sizeof(struct hostapd_iface *)); 175661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (iface == NULL) 175761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 175861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->iface = iface; 175961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface = interfaces->iface[interfaces->count] = 176061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_zalloc(sizeof(*hapd_iface)); 176161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface == NULL) { 176261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Failed to allocate memory for " 176361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "the interface", __func__); 176461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 176561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 176661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->count++; 176761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface->interfaces = interfaces; 176861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 176961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return hapd_iface; 177061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 177161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 177261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 177361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic struct hostapd_config * 177461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidthostapd_config_alloc(struct hapd_interfaces *interfaces, const char *ifname, 177561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const char *ctrl_iface) 177661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 177761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_bss_config *bss; 177861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_config *conf; 177961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 178061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Allocates memory for bss and conf */ 178161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt conf = hostapd_config_defaults(); 178261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (conf == NULL) { 178361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Failed to allocate memory for " 178461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "configuration", __func__); 178561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 178661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 178761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 178861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt conf->driver = wpa_drivers[0]; 178961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (conf->driver == NULL) { 179061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "No driver wrappers registered!"); 179161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_config_free(conf); 179261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 179361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 179461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1795cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt bss = conf->last_bss = conf->bss[0]; 179661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 179761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_strlcpy(bss->iface, ifname, sizeof(bss->iface)); 179861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt bss->ctrl_interface = os_strdup(ctrl_iface); 179961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (bss->ctrl_interface == NULL) { 180061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_config_free(conf); 180161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 180261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 180361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 180461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Reading configuration file skipped, will be done in SET! 180561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * From reading the configuration till the end has to be done in 180661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * SET 180761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 180861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return conf; 180961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 181061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 181161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 181261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic struct hostapd_iface * hostapd_data_alloc( 181361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hapd_interfaces *interfaces, struct hostapd_config *conf) 181461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 181561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t i; 181661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_iface *hapd_iface = 181761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->iface[interfaces->count - 1]; 181861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_data *hapd; 181961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 182061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface->conf = conf; 182161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface->num_bss = conf->num_bss; 182261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 182361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface->bss = os_zalloc(conf->num_bss * 182461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sizeof(struct hostapd_data *)); 182561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface->bss == NULL) 182661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 182761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 182861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (i = 0; i < conf->num_bss; i++) { 182961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd = hapd_iface->bss[i] = 1830cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_alloc_bss_data(hapd_iface, conf, conf->bss[i]); 183161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd == NULL) 183261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 183361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd->msg_ctx = hapd; 183461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 183561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 183661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface->interfaces = interfaces; 183761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 183861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return hapd_iface; 183961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 184061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 184161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 184261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint hostapd_add_iface(struct hapd_interfaces *interfaces, char *buf) 184361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 184461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_config *conf = NULL; 1845cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface *hapd_iface = NULL, *new_iface = NULL; 1846cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_data *hapd; 184761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char *ptr; 1848cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i, j; 1849cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt const char *conf_file = NULL, *phy_name = NULL; 1850cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1851cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (os_strncmp(buf, "bss_config=", 11) == 0) { 1852cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt char *pos; 1853cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt phy_name = buf + 11; 1854cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt pos = os_strchr(phy_name, ':'); 1855cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!pos) 1856cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 1857cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt *pos++ = '\0'; 1858cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf_file = pos; 1859cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!os_strlen(conf_file)) 1860cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 1861cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1862cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface = hostapd_interface_init_bss(interfaces, phy_name, 1863cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf_file, 0); 1864cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!hapd_iface) 1865cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 1866cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (j = 0; j < interfaces->count; j++) { 1867cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (interfaces->iface[j] == hapd_iface) 1868cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt break; 1869cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1870cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (j == interfaces->count) { 1871cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface **tmp; 1872cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt tmp = os_realloc_array(interfaces->iface, 1873cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt interfaces->count + 1, 1874cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt sizeof(struct hostapd_iface *)); 1875cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!tmp) { 1876cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_interface_deinit_free(hapd_iface); 1877cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 1878cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1879cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt interfaces->iface = tmp; 1880cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt interfaces->iface[interfaces->count++] = hapd_iface; 1881cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt new_iface = hapd_iface; 1882cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1883cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1884cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (new_iface) { 1885cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (interfaces->driver_init(hapd_iface) || 1886cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_setup_interface(hapd_iface)) { 1887cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt interfaces->count--; 1888cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto fail; 1889cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1890cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } else { 1891cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* Assign new BSS with bss[0]'s driver info */ 1892cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd = hapd_iface->bss[hapd_iface->num_bss - 1]; 1893cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->driver = hapd_iface->bss[0]->driver; 1894cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->drv_priv = hapd_iface->bss[0]->drv_priv; 1895cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_memcpy(hapd->own_addr, hapd_iface->bss[0]->own_addr, 1896cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt ETH_ALEN); 1897cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1898cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (start_ctrl_iface_bss(hapd) < 0 || 18995460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt (hapd_iface->state == HAPD_IFACE_ENABLED && 19005460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_setup_bss(hapd, -1))) { 1901b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt hostapd_cleanup(hapd); 19027d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt hapd_iface->bss[hapd_iface->num_bss - 1] = NULL; 1903cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->conf->num_bss--; 1904cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->num_bss--; 19055460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: free hapd %p %s", 19065460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, hapd, hapd->conf->iface); 1907cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_free(hapd); 1908cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 1909cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1910cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1911cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 1912cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 191361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 191461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ptr = os_strchr(buf, ' '); 191561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (ptr == NULL) 191661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 191761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *ptr++ = '\0'; 191861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 19195605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (os_strncmp(ptr, "config=", 7) == 0) 19205605286c30e1701491bd3af974ae423727750eddDmitry Shmidt conf_file = ptr + 7; 19215605286c30e1701491bd3af974ae423727750eddDmitry Shmidt 192261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (i = 0; i < interfaces->count; i++) { 1923cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!os_strcmp(interfaces->iface[i]->conf->bss[0]->iface, 192461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf)) { 192561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_INFO, "Cannot add interface - it " 192661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "already exists"); 192761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 192861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 192961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 193061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 193161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface = hostapd_iface_alloc(interfaces); 193261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface == NULL) { 193361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Failed to allocate memory " 193461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "for interface", __func__); 193561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt goto fail; 193661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 193761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 19385605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (conf_file && interfaces->config_read_cb) { 19395605286c30e1701491bd3af974ae423727750eddDmitry Shmidt conf = interfaces->config_read_cb(conf_file); 19405605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (conf && conf->bss) 1941cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_strlcpy(conf->bss[0]->iface, buf, 1942cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt sizeof(conf->bss[0]->iface)); 19435605286c30e1701491bd3af974ae423727750eddDmitry Shmidt } else 19445605286c30e1701491bd3af974ae423727750eddDmitry Shmidt conf = hostapd_config_alloc(interfaces, buf, ptr); 19455605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (conf == NULL || conf->bss == NULL) { 194661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Failed to allocate memory " 194761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "for configuration", __func__); 194861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt goto fail; 194961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 195061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 195161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface = hostapd_data_alloc(interfaces, conf); 195261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface == NULL) { 195361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Failed to allocate memory " 195461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "for hostapd", __func__); 195561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt goto fail; 195661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 195761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1958cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (start_ctrl_iface(hapd_iface) < 0) 195961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt goto fail; 1960cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1961cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "Add interface '%s'", conf->bss[0]->iface); 196261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 196361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 196461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 196561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtfail: 196661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (conf) 196761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_config_free(conf); 196861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface) { 1969cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd_iface->bss) { 19705460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt for (i = 0; i < hapd_iface->num_bss; i++) { 19715460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd = hapd_iface->bss[i]; 19727d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt if (!hapd) 19737d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt continue; 19747d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt if (hapd_iface->interfaces && 19755460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd_iface->interfaces->ctrl_iface_deinit) 19765460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd_iface->interfaces-> 19775460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt ctrl_iface_deinit(hapd); 19785460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: free hapd %p (%s)", 19795460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, hapd_iface->bss[i], 19807d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt hapd->conf->iface); 19817d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt os_free(hapd); 19827d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt hapd_iface->bss[i] = NULL; 19835460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt } 1984cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_free(hapd_iface->bss); 1985cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 19865460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: free iface %p", 19875460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, hapd_iface); 198861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(hapd_iface); 198961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 199061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 199161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 199261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 199361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1994cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic int hostapd_remove_bss(struct hostapd_iface *iface, unsigned int idx) 1995cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 1996cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i; 1997cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 19985460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_INFO, "Remove BSS '%s'", iface->conf->bss[idx]->iface); 1999cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 20005460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt /* Remove hostapd_data only if it has already been initialized */ 20015460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt if (idx < iface->num_bss) { 20025460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt struct hostapd_data *hapd = iface->bss[idx]; 2003cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 20045460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_bss_deinit(hapd); 20055460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: free hapd %p (%s)", 20065460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, hapd, hapd->conf->iface); 20075460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_config_free_bss(hapd->conf); 20085460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt os_free(hapd); 20095460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 20105460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt iface->num_bss--; 20115460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 20125460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt for (i = idx; i < iface->num_bss; i++) 20135460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt iface->bss[i] = iface->bss[i + 1]; 20145460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt } else { 20155460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_config_free_bss(iface->conf->bss[idx]); 20165460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt iface->conf->bss[idx] = NULL; 20175460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt } 2018cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2019cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->num_bss--; 20205460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt for (i = idx; i < iface->conf->num_bss; i++) 2021cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->bss[i] = iface->conf->bss[i + 1]; 2022cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2023cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 2024cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 2025cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2026cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 202761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint hostapd_remove_iface(struct hapd_interfaces *interfaces, char *buf) 202861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 202961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_iface *hapd_iface; 2030cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i, j, k = 0; 203161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 203261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (i = 0; i < interfaces->count; i++) { 203361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface = interfaces->iface[i]; 203461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface == NULL) 203561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 20365460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt if (!os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) { 203761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_INFO, "Remove interface '%s'", buf); 2038a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt hapd_iface->driver_ap_teardown = 2039a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt !!(hapd_iface->drv_flags & 2040a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT); 2041a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt 204261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_interface_deinit_free(hapd_iface); 204361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt k = i; 204461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt while (k < (interfaces->count - 1)) { 204561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->iface[k] = 204661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->iface[k + 1]; 204761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt k++; 204861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 204961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->count--; 205061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 205161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 2052cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2053cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (j = 0; j < hapd_iface->conf->num_bss; j++) { 2054a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt if (!os_strcmp(hapd_iface->conf->bss[j]->iface, buf)) { 2055a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt hapd_iface->driver_ap_teardown = 2056a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt !(hapd_iface->drv_flags & 2057a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT); 2058cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return hostapd_remove_bss(hapd_iface, j); 2059a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt } 2060cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 206161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 206261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 206361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 206461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 206561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 20668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 20678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_new_assoc_sta - Notify that a new station associated with the AP 20688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hapd: Pointer to BSS data 20698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sta: Pointer to the associated STA data 20708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @reassoc: 1 to indicate this was a re-association; 0 = first association 20718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 20728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function will be called whenever a station associates with the AP. It 20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * can be called from ieee802_11.c for drivers that export MLME to hostapd and 20748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * from drv_callbacks.c based on driver events for drivers that take care of 20758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * management frames (IEEE 802.11 authentication and association) internally. 20768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 20778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta, 20788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int reassoc) 20798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->tkip_countermeasures) { 20818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_drv_sta_deauth(hapd, sta->addr, 20828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_REASON_MICHAEL_MIC_FAILURE); 20838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 20848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_prune_associations(hapd, sta->addr); 20878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* IEEE 802.11F (IAPP) */ 20898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ieee802_11f) 20908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iapp_new_station(hapd->iapp, sta); 20918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P 20938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->p2p_ie == NULL && !sta->no_p2p_set) { 20948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->no_p2p_set = 1; 20958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->num_sta_no_p2p++; 20968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->num_sta_no_p2p == 1) 20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_p2p_non_p2p_sta_connected(hapd); 20988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */ 21008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Start accounting here, if IEEE 802.1X and WPA are not used. 21028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * IEEE 802.1X/WPA code will start accounting after the station has 21038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * been authorized. */ 21042ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt if (!hapd->conf->ieee802_1x && !hapd->conf->wpa && !hapd->conf->osen) { 21052ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt ap_sta_set_authorized(hapd, sta, 1); 210604f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt os_get_reltime(&sta->connected_time); 21078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt accounting_sta_start(hapd, sta); 2108d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 21098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Start IEEE 802.1X authentication process for new stations */ 21118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_new_station(hapd, sta); 21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reassoc) { 21138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->auth_alg != WLAN_AUTH_FT && 21148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS))) 21158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH); 21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 21178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm); 211804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 211901904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_INACTIVITY_TIMER)) { 212001904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: reschedule ap_handle_timer timeout " 212101904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt "for " MACSTR " (%d seconds - ap_max_inactivity)", 212201904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt __func__, MAC2STR(sta->addr), 212301904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt hapd->conf->ap_max_inactivity); 212401904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt eloop_cancel_timeout(ap_handle_timer, hapd, sta); 212501904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt eloop_register_timeout(hapd->conf->ap_max_inactivity, 0, 212601904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt ap_handle_timer, hapd, sta); 212701904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt } 21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2129cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2130cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2131cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtconst char * hostapd_state_text(enum hostapd_iface_state s) 2132cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 2133cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt switch (s) { 2134cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_UNINITIALIZED: 2135cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "UNINITIALIZED"; 2136cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_DISABLED: 2137cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "DISABLED"; 2138cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_COUNTRY_UPDATE: 2139cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "COUNTRY_UPDATE"; 2140cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_ACS: 2141cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "ACS"; 2142cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_HT_SCAN: 2143cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "HT_SCAN"; 2144cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_DFS: 2145cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "DFS"; 2146cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_ENABLED: 2147cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "ENABLED"; 2148cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2149cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2150cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "UNKNOWN"; 2151cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 2152cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2153cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2154cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtvoid hostapd_set_state(struct hostapd_iface *iface, enum hostapd_iface_state s) 2155cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 2156cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "%s: interface state %s->%s", 2157cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->bss[0]->iface, hostapd_state_text(iface->state), 2158cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_state_text(s)); 2159cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->state = s; 2160cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 2161e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2162e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2163e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt#ifdef NEED_AP_MLME 2164e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2165e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtstatic void free_beacon_data(struct beacon_data *beacon) 2166e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 2167e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_free(beacon->head); 2168e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->head = NULL; 2169e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_free(beacon->tail); 2170e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->tail = NULL; 2171e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_free(beacon->probe_resp); 2172e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->probe_resp = NULL; 2173e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_free(beacon->beacon_ies); 2174e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->beacon_ies = NULL; 2175e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_free(beacon->proberesp_ies); 2176e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->proberesp_ies = NULL; 2177e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_free(beacon->assocresp_ies); 2178e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->assocresp_ies = NULL; 2179e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 2180e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2181e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2182d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidtstatic int hostapd_build_beacon_data(struct hostapd_data *hapd, 2183e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct beacon_data *beacon) 2184e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 2185e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct wpabuf *beacon_extra, *proberesp_extra, *assocresp_extra; 2186e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct wpa_driver_ap_params params; 2187e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt int ret; 2188e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 218901904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt os_memset(beacon, 0, sizeof(*beacon)); 2190e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = ieee802_11_build_ap_params(hapd, ¶ms); 2191e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret < 0) 2192e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 2193e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2194e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = hostapd_build_ap_extra_ies(hapd, &beacon_extra, 2195e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &proberesp_extra, 2196e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &assocresp_extra); 2197e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) 2198e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_ap_params; 2199e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2200e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = -1; 2201e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->head = os_malloc(params.head_len); 2202e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!beacon->head) 2203e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_ap_extra_ies; 2204e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2205e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memcpy(beacon->head, params.head, params.head_len); 2206e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->head_len = params.head_len; 2207e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2208e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->tail = os_malloc(params.tail_len); 2209e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!beacon->tail) 2210e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_beacon; 2211e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2212e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memcpy(beacon->tail, params.tail, params.tail_len); 2213e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->tail_len = params.tail_len; 2214e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2215e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (params.proberesp != NULL) { 2216e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->probe_resp = os_malloc(params.proberesp_len); 2217e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!beacon->probe_resp) 2218e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_beacon; 2219e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2220e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memcpy(beacon->probe_resp, params.proberesp, 2221e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt params.proberesp_len); 2222e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->probe_resp_len = params.proberesp_len; 2223e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2224e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2225e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* copy the extra ies */ 2226e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (beacon_extra) { 2227e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->beacon_ies = os_malloc(wpabuf_len(beacon_extra)); 2228e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!beacon->beacon_ies) 2229e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_beacon; 2230e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2231e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memcpy(beacon->beacon_ies, 2232e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon_extra->buf, wpabuf_len(beacon_extra)); 2233e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->beacon_ies_len = wpabuf_len(beacon_extra); 2234e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2235e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2236e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (proberesp_extra) { 2237e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->proberesp_ies = 2238e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_malloc(wpabuf_len(proberesp_extra)); 2239e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!beacon->proberesp_ies) 2240e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_beacon; 2241e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2242e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memcpy(beacon->proberesp_ies, proberesp_extra->buf, 2243e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt wpabuf_len(proberesp_extra)); 2244e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->proberesp_ies_len = wpabuf_len(proberesp_extra); 2245e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2246e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2247e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (assocresp_extra) { 2248e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->assocresp_ies = 2249e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_malloc(wpabuf_len(assocresp_extra)); 2250e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!beacon->assocresp_ies) 2251e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_beacon; 2252e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2253e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memcpy(beacon->assocresp_ies, assocresp_extra->buf, 2254e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt wpabuf_len(assocresp_extra)); 2255e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->assocresp_ies_len = wpabuf_len(assocresp_extra); 2256e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2257e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2258e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = 0; 2259e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtfree_beacon: 2260e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* if the function fails, the caller should not free beacon data */ 2261e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) 2262e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt free_beacon_data(beacon); 2263e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2264e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtfree_ap_extra_ies: 2265e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt hostapd_free_ap_extra_ies(hapd, beacon_extra, proberesp_extra, 2266e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt assocresp_extra); 2267e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtfree_ap_params: 2268e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ieee802_11_free_ap_params(¶ms); 2269e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 2270e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 2271e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2272e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2273e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt/* 2274e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt * TODO: This flow currently supports only changing frequency within the 2275e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt * same hw_mode. Any other changes to MAC parameters or provided settings (even 2276e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt * width) are not supported. 2277e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt */ 2278e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtstatic int hostapd_change_config_freq(struct hostapd_data *hapd, 2279e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct hostapd_config *conf, 2280e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct hostapd_freq_params *params, 2281e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct hostapd_freq_params *old_params) 2282e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 2283e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt int channel; 2284e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2285e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!params->channel) { 2286e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* check if the new channel is supported by hw */ 2287d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt params->channel = hostapd_hw_get_channel(hapd, params->freq); 2288e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2289e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2290d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt channel = params->channel; 2291d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt if (!channel) 2292d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt return -1; 2293d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 2294e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* if a pointer to old_params is provided we save previous state */ 2295e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (old_params) { 2296e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt old_params->channel = conf->channel; 2297e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt old_params->ht_enabled = conf->ieee80211n; 2298e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt old_params->sec_channel_offset = conf->secondary_channel; 2299e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2300e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2301e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt conf->channel = channel; 2302e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt conf->ieee80211n = params->ht_enabled; 2303e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt conf->secondary_channel = params->sec_channel_offset; 2304e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2305e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* TODO: maybe call here hostapd_config_check here? */ 2306e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2307e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return 0; 2308e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 2309e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2310e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2311d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidtstatic int hostapd_fill_csa_settings(struct hostapd_data *hapd, 2312e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct csa_settings *settings) 2313e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 2314d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt struct hostapd_iface *iface = hapd->iface; 2315e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct hostapd_freq_params old_freq; 2316e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt int ret; 2317e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2318e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memset(&old_freq, 0, sizeof(old_freq)); 2319d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt if (!iface || !iface->freq || hapd->csa_in_progress) 2320e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return -1; 2321e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2322e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = hostapd_change_config_freq(iface->bss[0], iface->conf, 2323e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &settings->freq_params, 2324e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &old_freq); 2325e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) 2326e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 2327e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2328d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt ret = hostapd_build_beacon_data(hapd, &settings->beacon_after); 2329e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2330e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* change back the configuration */ 2331e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt hostapd_change_config_freq(iface->bss[0], iface->conf, 2332e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &old_freq, NULL); 2333e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2334e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) 2335e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 2336e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2337e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* set channel switch parameters for csa ie */ 2338d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->cs_freq_params = settings->freq_params; 2339d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->cs_count = settings->cs_count; 2340d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->cs_block_tx = settings->block_tx; 2341e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2342d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt ret = hostapd_build_beacon_data(hapd, &settings->beacon_csa); 2343e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) { 2344e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt free_beacon_data(&settings->beacon_after); 2345e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 2346e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2347e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2348d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt settings->counter_offset_beacon = hapd->cs_c_off_beacon; 2349d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt settings->counter_offset_presp = hapd->cs_c_off_proberesp; 2350e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2351e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return 0; 2352e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 2353e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2354e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2355e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtvoid hostapd_cleanup_cs_params(struct hostapd_data *hapd) 2356e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 2357d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt os_memset(&hapd->cs_freq_params, 0, sizeof(hapd->cs_freq_params)); 2358d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->cs_count = 0; 2359d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->cs_block_tx = 0; 2360d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->cs_c_off_beacon = 0; 2361d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->cs_c_off_proberesp = 0; 2362d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->csa_in_progress = 0; 2363e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 2364e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2365e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2366e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtint hostapd_switch_channel(struct hostapd_data *hapd, 2367e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct csa_settings *settings) 2368e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 2369e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt int ret; 2370d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt ret = hostapd_fill_csa_settings(hapd, settings); 2371e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) 2372e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 2373e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2374e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = hostapd_drv_switch_channel(hapd, settings); 2375e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt free_beacon_data(&settings->beacon_csa); 2376e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt free_beacon_data(&settings->beacon_after); 2377e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2378e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) { 2379e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* if we failed, clean cs parameters */ 2380e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt hostapd_cleanup_cs_params(hapd); 2381e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 2382e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2383e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2384d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->csa_in_progress = 1; 2385e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return 0; 2386e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 2387e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2388d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 2389d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidtvoid 2390d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidthostapd_switch_channel_fallback(struct hostapd_iface *iface, 2391d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt const struct hostapd_freq_params *freq_params) 2392d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt{ 2393d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt int vht_seg0_idx = 0, vht_seg1_idx = 0, vht_bw = VHT_CHANWIDTH_USE_HT; 2394d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt unsigned int i; 2395d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 2396d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt wpa_printf(MSG_DEBUG, "Restarting all CSA-related BSSes"); 2397d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 2398d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt if (freq_params->center_freq1) 2399d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt vht_seg0_idx = 36 + (freq_params->center_freq1 - 5180) / 5; 2400d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt if (freq_params->center_freq2) 2401d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt vht_seg1_idx = 36 + (freq_params->center_freq2 - 5180) / 5; 2402d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 2403d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt switch (freq_params->bandwidth) { 2404d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt case 0: 2405d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt case 20: 2406d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt case 40: 2407d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt vht_bw = VHT_CHANWIDTH_USE_HT; 2408d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt break; 2409d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt case 80: 2410d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt if (freq_params->center_freq2) 2411d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt vht_bw = VHT_CHANWIDTH_80P80MHZ; 2412d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt else 2413d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt vht_bw = VHT_CHANWIDTH_80MHZ; 2414d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt break; 2415d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt case 160: 2416d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt vht_bw = VHT_CHANWIDTH_160MHZ; 2417d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt break; 2418d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt default: 2419d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt wpa_printf(MSG_WARNING, "Unknown CSA bandwidth: %d", 2420d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt freq_params->bandwidth); 2421d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt break; 2422d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt } 2423d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 2424d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt iface->freq = freq_params->freq; 2425d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt iface->conf->channel = freq_params->channel; 2426d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt iface->conf->secondary_channel = freq_params->sec_channel_offset; 2427d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt iface->conf->vht_oper_centr_freq_seg0_idx = vht_seg0_idx; 2428d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt iface->conf->vht_oper_centr_freq_seg1_idx = vht_seg1_idx; 2429d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt iface->conf->vht_oper_chwidth = vht_bw; 2430d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt iface->conf->ieee80211n = freq_params->ht_enabled; 2431d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt iface->conf->ieee80211ac = freq_params->vht_enabled; 2432d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 2433d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt /* 2434d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt * cs_params must not be cleared earlier because the freq_params 2435d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt * argument may actually point to one of these. 2436d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt */ 2437d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt for (i = 0; i < iface->num_bss; i++) 2438d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hostapd_cleanup_cs_params(iface->bss[i]); 2439d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 2440d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hostapd_disable_iface(iface); 2441d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hostapd_enable_iface(iface); 2442d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt} 2443d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 2444e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt#endif /* NEED_AP_MLME */ 2445