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" 15d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#include "common/hw_features_common.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "radius/radius_client.h" 1704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "radius/radius_das.h" 1850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt#include "eap_server/tncs.h" 192f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt#include "eapol_auth/eapol_auth_sm.h" 202f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt#include "eapol_auth/eapol_auth_sm_i.h" 21d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#include "fst/fst.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "hostapd.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "authsrv.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "sta_info.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "accounting.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_list.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "beacon.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "iapp.h" 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ieee802_1x.h" 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ieee802_11_auth.h" 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "vlan_init.h" 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_auth.h" 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps_hostapd.h" 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "hw_features.h" 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_auth_glue.h" 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_drv_ops.h" 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_config.h" 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_hostapd.h" 3904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "gas_serv.h" 40051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#include "dfs.h" 417832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt#include "ieee802_11.h" 426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#include "bss_load.h" 436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#include "x_snoop.h" 446c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#include "dhcp_snoop.h" 456c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#include "ndisc_snoop.h" 46849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt#include "neighbor_db.h" 47849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt#include "rrm.h" 48ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt#include "fils_hlp.h" 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5104949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason); 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd); 53c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidtstatic int hostapd_broadcast_wep_clear(struct hostapd_data *hapd); 54cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic int setup_interface2(struct hostapd_iface *iface); 55cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic void channel_list_update_timeout(void *eloop_ctx, void *timeout_ctx); 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint hostapd_for_each_interface(struct hapd_interfaces *interfaces, 5904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int (*cb)(struct hostapd_iface *iface, 6004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt void *ctx), void *ctx) 6104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 6204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt size_t i; 6304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int ret; 6404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 6504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (i = 0; i < interfaces->count; i++) { 6604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ret = cb(interfaces->iface[i], ctx); 6704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ret) 6804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return ret; 6904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 7004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 7104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 7204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 7304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 7404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_reload_bss(struct hostapd_data *hapd) 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 77cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_ssid *ssid; 78cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 79293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt if (!hapd->started) 80293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt return; 81293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_client_reconfig(hapd->radius, hapd->conf->radius); 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 86cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt ssid = &hapd->conf->ssid; 87cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!ssid->wpa_psk_set && ssid->wpa_psk && !ssid->wpa_psk->next && 88cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt ssid->wpa_passphrase_set && ssid->wpa_passphrase) { 89cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* 90cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * Force PSK to be derived again since SSID or passphrase may 91cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * have changed. 92cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 937f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt hostapd_config_clear_wpa_psk(&hapd->conf->ssid.wpa_psk); 94cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_setup_wpa_psk(hapd->conf)) { 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to re-configure WPA PSK " 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "after reloading configuration"); 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ieee802_1x || hapd->conf->wpa) 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 1); 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 0); 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 105f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if ((hapd->conf->wpa || hapd->conf->osen) && hapd->wpa_auth == NULL) { 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_setup_wpa(hapd); 1071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (hapd->wpa_auth) 1081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_init_keys(hapd->wpa_auth); 1091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else if (hapd->conf->wpa) { 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *wpa_ie; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t wpa_ie_len; 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_reconfig_wpa(hapd); 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &wpa_ie_len); 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_set_generic_elem(hapd, wpa_ie, wpa_ie_len)) 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to configure WPA IE for " 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "the kernel driver."); 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (hapd->wpa_auth) { 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_deinit(hapd->wpa_auth); 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->wpa_auth = NULL; 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_privacy(hapd, 0); 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_setup_encryption(hapd->conf->iface, hapd); 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_generic_elem(hapd, (u8 *) "", 0); 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_11_set_beacon(hapd); 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_update_wps(hapd); 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ssid.ssid_set && 12961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_set_ssid(hapd, hapd->conf->ssid.ssid, 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->ssid.ssid_len)) { 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver"); 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* try to continue */ 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Reconfigured interface %s", hapd->conf->iface); 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 138444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidtstatic void hostapd_clear_old(struct hostapd_iface *iface) 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t j; 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Deauthenticate all stations since the new configuration may not 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * allow them to use the BSS anymore. 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 14704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_flush_old_stations(iface->bss[j], 14804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt WLAN_REASON_PREV_AUTH_NOT_VALID); 149c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt hostapd_broadcast_wep_clear(iface->bss[j]); 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: update dynamic data based on changed configuration 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * items (e.g., open/close sockets, etc.) */ 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_client_flush(iface->bss[j]->radius, 0); 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 157444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt} 158444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt 159444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt 160444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidtint hostapd_reload_config(struct hostapd_iface *iface) 161444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt{ 162444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt struct hostapd_data *hapd = iface->bss[0]; 163444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt struct hostapd_config *newconf, *oldconf; 164444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt size_t j; 165444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt 166444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt if (iface->config_fname == NULL) { 167444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt /* Only in-memory config in use - assume it has been updated */ 168444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt hostapd_clear_old(iface); 169444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) 170444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt hostapd_reload_bss(iface->bss[j]); 171444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt return 0; 172444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt } 173444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt 174444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt if (iface->interfaces == NULL || 175444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt iface->interfaces->config_read_cb == NULL) 176444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt return -1; 177444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt newconf = iface->interfaces->config_read_cb(iface->config_fname); 178444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt if (newconf == NULL) 179444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt return -1; 180444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt 181444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt hostapd_clear_old(iface); 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt oldconf = hapd->iconf; 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->conf = newconf; 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd = iface->bss[j]; 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iconf = newconf; 189d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt hapd->iconf->channel = oldconf->channel; 190dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt hapd->iconf->acs = oldconf->acs; 191df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt hapd->iconf->secondary_channel = oldconf->secondary_channel; 192d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt hapd->iconf->ieee80211n = oldconf->ieee80211n; 193d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt hapd->iconf->ieee80211ac = oldconf->ieee80211ac; 194d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt hapd->iconf->ht_capab = oldconf->ht_capab; 195d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt hapd->iconf->vht_capab = oldconf->vht_capab; 196d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt hapd->iconf->vht_oper_chwidth = oldconf->vht_oper_chwidth; 197d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt hapd->iconf->vht_oper_centr_freq_seg0_idx = 198d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt oldconf->vht_oper_centr_freq_seg0_idx; 199d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt hapd->iconf->vht_oper_centr_freq_seg1_idx = 200d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt oldconf->vht_oper_centr_freq_seg1_idx; 201cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->conf = newconf->bss[j]; 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_reload_bss(hapd); 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_config_free(oldconf); 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_broadcast_key_clear_iface(struct hostapd_data *hapd, 213d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt const char *ifname) 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 217293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt if (!ifname || !hapd->drv_priv) 218d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt return; 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < NUM_WEP_KEYS; i++) { 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE, NULL, i, 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, NULL, 0, NULL, 0)) { 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to clear default " 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "encryption keys (ifname=%s keyidx=%d)", 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ifname, i); 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ieee80211w) { 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = NUM_WEP_KEYS; i < NUM_WEP_KEYS + 2; i++) { 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE, 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, i, 0, NULL, 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, NULL, 0)) { 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to clear " 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "default mgmt encryption keys " 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(ifname=%s keyidx=%d)", ifname, i); 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_broadcast_wep_clear(struct hostapd_data *hapd) 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_broadcast_key_clear_iface(hapd, hapd->conf->iface); 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_broadcast_wep_set(struct hostapd_data *hapd) 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int errors = 0, idx; 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_ssid *ssid = &hapd->conf->ssid; 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idx = ssid->wep.idx; 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->wep.default_len && 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_drv_set_key(hapd->conf->iface, 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd, WPA_ALG_WEP, broadcast_ether_addr, idx, 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1, NULL, 0, ssid->wep.key[idx], 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->wep.len[idx])) { 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "Could not set WEP encryption."); 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt errors++; 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return errors; 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void hostapd_free_hapd_data(struct hostapd_data *hapd) 27004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 2716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_free(hapd->probereq_cb); 2726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hapd->probereq_cb = NULL; 273d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt hapd->num_probereq_cb = 0; 2746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 2756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_P2P 2766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpabuf_free(hapd->p2p_beacon_ie); 2776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hapd->p2p_beacon_ie = NULL; 2786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpabuf_free(hapd->p2p_probe_resp_ie); 2796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hapd->p2p_probe_resp_ie = NULL; 2806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_P2P */ 2816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 282fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt if (!hapd->started) { 283fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Interface %s wasn't started", 284fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt __func__, hapd->conf->iface); 285fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt return; 286fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt } 287fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt hapd->started = 0; 288fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt 2895460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface); 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iapp_deinit(hapd->iapp); 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iapp = NULL; 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt accounting_deinit(hapd); 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_deinit_wpa(hapd); 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt vlan_deinit(hapd); 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_acl_deinit(hapd); 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_client_deinit(hapd->radius); 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->radius = NULL; 29904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt radius_das_deinit(hapd->radius_das); 30004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hapd->radius_das = NULL; 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_deinit_wps(hapd); 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt authsrv_deinit(hapd); 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 307717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (hapd->interface_added) { 308717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hapd->interface_added = 0; 309717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (hostapd_if_remove(hapd, WPA_IF_AP_BSS, hapd->conf->iface)) { 310717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt wpa_printf(MSG_WARNING, 311717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt "Failed to remove BSS interface %s", 312717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hapd->conf->iface); 313717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hapd->interface_added = 1; 314717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt } else { 315717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt /* 316717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt * Since this was a dynamically added interface, the 317717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt * driver wrapper may have removed its internal instance 318717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt * and hapd->drv_priv is not valid anymore. 319717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt */ 320717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hapd->drv_priv = NULL; 321717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt } 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_free(hapd->time_adv); 32504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 32604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_INTERWORKING 32704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt gas_serv_deinit(hapd); 32804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_INTERWORKING */ 329d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 3306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt bss_load_update_deinit(hapd); 3316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ndisc_snoop_deinit(hapd); 3326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt dhcp_snoop_deinit(hapd); 3336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt x_snoop_deinit(hapd); 3346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 335d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SQLITE 336c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt bin_clear_free(hapd->tmp_eap_user.identity, 337c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt hapd->tmp_eap_user.identity_len); 338c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt bin_clear_free(hapd->tmp_eap_user.password, 339c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt hapd->tmp_eap_user.password_len); 340d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SQLITE */ 3416c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 3426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_MESH 3436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpabuf_free(hapd->mesh_pending_auth); 3446c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hapd->mesh_pending_auth = NULL; 3456c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_MESH */ 346849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 347849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt hostapd_clean_rrm(hapd); 348ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt fils_hlp_deinit(hapd); 34904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 35004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 35104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 35204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/** 35304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * hostapd_cleanup - Per-BSS cleanup (deinitialization) 35404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @hapd: Pointer to BSS data 35504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * 35604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * This function is used to free all per-BSS data structures and resources. 3575460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt * Most of the modules that are initialized in hostapd_setup_bss() are 3585460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt * deinitialized here. 35904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 36004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void hostapd_cleanup(struct hostapd_data *hapd) 36104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 3625460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(hapd=%p (%s))", __func__, hapd, 3635460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd->conf->iface); 36461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd->iface->interfaces && 365293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt hapd->iface->interfaces->ctrl_iface_deinit) { 366293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt wpa_msg(hapd->msg_ctx, MSG_INFO, WPA_EVENT_TERMINATING); 36761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd->iface->interfaces->ctrl_iface_deinit(hapd); 368293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt } 36904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_free_hapd_data(hapd); 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 373d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic void sta_track_deinit(struct hostapd_iface *iface) 374d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 375d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct hostapd_sta_info *info; 376d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 377d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!iface->num_sta_seen) 378d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return; 379d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 380d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt while ((info = dl_list_first(&iface->sta_seen, struct hostapd_sta_info, 381d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt list))) { 382d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt dl_list_del(&info->list); 383d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt iface->num_sta_seen--; 384aca489e0b2daec9e67dd611b7a44f47bd1f41e27Dmitry Shmidt sta_track_del(info); 385d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 386d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 387d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 388d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 38904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void hostapd_cleanup_iface_partial(struct hostapd_iface *iface) 39004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 3915460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); 3927f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt#ifdef CONFIG_IEEE80211N 3937f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt#ifdef NEED_AP_MLME 3947f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt hostapd_stop_setup_timers(iface); 3957f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt#endif /* NEED_AP_MLME */ 3967f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt#endif /* CONFIG_IEEE80211N */ 39704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_free_hw_features(iface->hw_features, iface->num_hw_features); 39804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt iface->hw_features = NULL; 39904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(iface->current_rates); 40004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt iface->current_rates = NULL; 40104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(iface->basic_rates); 40204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt iface->basic_rates = NULL; 40304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ap_list_deinit(iface); 404d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt sta_track_deinit(iface); 40504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 40604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 40704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_cleanup_iface - Complete per-interface cleanup 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @iface: Pointer to interface data 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called after per-BSS data structures are deinitialized 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * with hostapd_cleanup(). 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_cleanup_iface(struct hostapd_iface *iface) 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4175460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); 418cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt eloop_cancel_timeout(channel_list_update_timeout, iface, NULL); 419cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 42004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_cleanup_iface_partial(iface); 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_config_free(iface->conf); 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->conf = NULL; 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(iface->config_fname); 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(iface->bss); 4265460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: free iface=%p", __func__, iface); 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(iface); 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43104949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void hostapd_clear_wep(struct hostapd_data *hapd) 43204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 433a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt if (hapd->drv_priv && !hapd->iface->driver_ap_teardown) { 43404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_set_privacy(hapd, 0); 43504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_broadcast_wep_clear(hapd); 43604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 43704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 43804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 43904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd) 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_broadcast_wep_set(hapd); 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ssid.wep.default_len) { 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_privacy(hapd, 1); 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 45175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 45275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * When IEEE 802.1X is not enabled, the driver may need to know how to 45375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * set authentication algorithms for static WEP. 45475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 45575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen hostapd_drv_set_authmode(hapd, hapd->conf->auth_algs); 45675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 4; i++) { 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ssid.wep.key[i] && 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_drv_set_key(iface, hapd, WPA_ALG_WEP, NULL, i, 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i == hapd->conf->ssid.wep.idx, NULL, 0, 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->ssid.wep.key[i], 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->ssid.wep.len[i])) { 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "Could not set WEP " 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "encryption."); 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ssid.wep.key[i] && 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i == hapd->conf->ssid.wep.idx) 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_privacy(hapd, 1); 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 47604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason) 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 addr[ETH_ALEN]; 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_drv_none(hapd) || hapd->drv_priv == NULL) 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 484a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt if (!hapd->iface->driver_ap_teardown) { 485a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt wpa_dbg(hapd->msg_ctx, MSG_DEBUG, 486a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt "Flushing old station entries"); 487a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt 488a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt if (hostapd_flush(hapd)) { 489a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt wpa_msg(hapd->msg_ctx, MSG_WARNING, 490a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt "Could not connect to kernel driver"); 491a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt ret = -1; 492a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt } 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "Deauthenticate all stations"); 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(addr, 0xff, ETH_ALEN); 49604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_drv_sta_deauth(hapd, addr, reason); 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_free_stas(hapd); 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 503717574375e969e8272c6d1a26137286eac158abbDmitry Shmidtstatic void hostapd_bss_deinit_no_free(struct hostapd_data *hapd) 504717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt{ 505717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_free_stas(hapd); 506717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING); 507717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_clear_wep(hapd); 508717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt} 509717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 510717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_validate_bssid_configuration - Validate BSSID configuration 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @iface: Pointer to interface data 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to validate that the configured BSSIDs are valid. 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_validate_bssid_configuration(struct hostapd_iface *iface) 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 mask[ETH_ALEN] = { 0 }; 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = iface->bss[0]; 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int i = iface->conf->num_bss, bits = 0, j; 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int auto_addr = 0; 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_drv_none(hapd)) 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52831a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt if (iface->conf->use_driver_iface_addr) 52931a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt return 0; 53031a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Generate BSSID mask that is large enough to cover the BSSIDs. */ 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Determine the bits necessary to cover the number of BSSIDs. */ 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i--; i; i >>= 1) 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bits++; 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Determine the bits necessary to any configured BSSIDs, 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if they are higher than the number of BSSIDs. */ 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < iface->conf->num_bss; j++) { 5409c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt if (is_zero_ether_addr(iface->conf->bss[j]->bssid)) { 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (j) 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auto_addr++; 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < ETH_ALEN; i++) { 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mask[i] |= 548cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->bss[j]->bssid[i] ^ 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->own_addr[i]; 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!auto_addr) 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto skip_mask_ext; 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < ETH_ALEN && mask[i] == 0; i++) 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ; 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt j = 0; 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i < ETH_ALEN) { 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt j = (5 - i) * 8; 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (mask[i] != 0) { 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mask[i] >>= 1; 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt j++; 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bits < j) 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bits = j; 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bits > 40) { 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Too many bits in the BSSID mask (%u)", 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bits); 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(mask, 0xff, ETH_ALEN); 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt j = bits / 8; 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 5; i > 5 - j; i--) 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mask[i] = 0; 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt j = bits % 8; 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (j--) 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mask[i] <<= 1; 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtskip_mask_ext: 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "BSS count %lu, BSSID mask " MACSTR " (%d bits)", 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) iface->conf->num_bss, MAC2STR(mask), bits); 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!auto_addr) 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < ETH_ALEN; i++) { 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((hapd->own_addr[i] & mask[i]) != hapd->own_addr[i]) { 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Invalid BSSID mask " MACSTR 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " for start address " MACSTR ".", 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mask), MAC2STR(hapd->own_addr)); 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Start address must be the " 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "first address in the block (i.e., addr " 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "AND mask == addr)."); 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int mac_in_conf(struct hostapd_config *conf, const void *a) 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < conf->num_bss; i++) { 613cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hostapd_mac_comp(conf->bss[i]->bssid, a) == 0) { 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 62204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifndef CONFIG_NO_RADIUS 62304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 62404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int hostapd_das_nas_mismatch(struct hostapd_data *hapd, 62504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct radius_das_attrs *attr) 62604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 62713ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt if (attr->nas_identifier && 62813ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt (!hapd->conf->nas_identifier || 62913ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt os_strlen(hapd->conf->nas_identifier) != 63013ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt attr->nas_identifier_len || 63113ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt os_memcmp(hapd->conf->nas_identifier, attr->nas_identifier, 63213ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt attr->nas_identifier_len) != 0)) { 63313ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-Identifier mismatch"); 63413ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt return 1; 63513ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt } 63613ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt 63713ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt if (attr->nas_ip_addr && 63813ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt (hapd->conf->own_ip_addr.af != AF_INET || 63913ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt os_memcmp(&hapd->conf->own_ip_addr.u.v4, attr->nas_ip_addr, 4) != 64013ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt 0)) { 64113ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-IP-Address mismatch"); 64213ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt return 1; 64313ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt } 64413ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt 64513ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt#ifdef CONFIG_IPV6 64613ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt if (attr->nas_ipv6_addr && 64713ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt (hapd->conf->own_ip_addr.af != AF_INET6 || 64813ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt os_memcmp(&hapd->conf->own_ip_addr.u.v6, attr->nas_ipv6_addr, 16) 64913ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt != 0)) { 65013ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-IPv6-Address mismatch"); 65113ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt return 1; 65213ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt } 65313ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt#endif /* CONFIG_IPV6 */ 65413ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt 65504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 65604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 65704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 65804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 65904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic struct sta_info * hostapd_das_find_sta(struct hostapd_data *hapd, 6602f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt struct radius_das_attrs *attr, 6612f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt int *multi) 66204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 6632f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt struct sta_info *selected, *sta; 66404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt char buf[128]; 6652f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt int num_attr = 0; 6662f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt int count; 66704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 6682f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt *multi = 0; 6692f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 6702f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt for (sta = hapd->sta_list; sta; sta = sta->next) 6712f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt sta->radius_das_match = 1; 6722f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 6732f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (attr->sta_addr) { 6742f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt num_attr++; 67504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sta = ap_get_sta(hapd, attr->sta_addr); 6762f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (!sta) { 6772f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, 6782f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "RADIUS DAS: No Calling-Station-Id match"); 6792f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return NULL; 6802f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 68104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 6822f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt selected = sta; 68304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (sta = hapd->sta_list; sta; sta = sta->next) { 6842f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (sta != selected) 6852f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt sta->radius_das_match = 0; 6862f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 6872f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, "RADIUS DAS: Calling-Station-Id match"); 6882f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 6892f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 6902f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (attr->acct_session_id) { 6912f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt num_attr++; 692b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (attr->acct_session_id_len != 16) { 6932f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, 6942f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "RADIUS DAS: Acct-Session-Id cannot match"); 6952f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return NULL; 6962f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 6972f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt count = 0; 6982f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 6992f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt for (sta = hapd->sta_list; sta; sta = sta->next) { 7002f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (!sta->radius_das_match) 7012f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt continue; 70257c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt os_snprintf(buf, sizeof(buf), "%016llX", 70357c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt (unsigned long long) sta->acct_session_id); 704b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (os_memcmp(attr->acct_session_id, buf, 16) != 0) 7052f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt sta->radius_das_match = 0; 7062f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt else 7072f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt count++; 7082f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 7092f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 7102f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (count == 0) { 7112f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, 7122f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "RADIUS DAS: No matches remaining after Acct-Session-Id check"); 7132f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return NULL; 71404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 7152f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, "RADIUS DAS: Acct-Session-Id match"); 71604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 71704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 7182f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (attr->acct_multi_session_id) { 7192f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt num_attr++; 720b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (attr->acct_multi_session_id_len != 16) { 7212f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, 7222f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "RADIUS DAS: Acct-Multi-Session-Id cannot match"); 7232f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return NULL; 7242f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 7252f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt count = 0; 7262f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 7272f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt for (sta = hapd->sta_list; sta; sta = sta->next) { 7282f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (!sta->radius_das_match) 7292f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt continue; 7302f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (!sta->eapol_sm || 731b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt !sta->eapol_sm->acct_multi_session_id) { 7322f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt sta->radius_das_match = 0; 7332f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt continue; 7342f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 73557c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt os_snprintf(buf, sizeof(buf), "%016llX", 73657c2d39d85825f38c5fdac9b73bb0088406ffc85Dmitry Shmidt (unsigned long long) 737b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt sta->eapol_sm->acct_multi_session_id); 738b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (os_memcmp(attr->acct_multi_session_id, buf, 16) != 7392f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 0) 7402f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt sta->radius_das_match = 0; 7412f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt else 7422f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt count++; 7432f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 7442f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 7452f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (count == 0) { 7462f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, 7472f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "RADIUS DAS: No matches remaining after Acct-Multi-Session-Id check"); 7482f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return NULL; 7492f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 7502f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, 7512f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "RADIUS DAS: Acct-Multi-Session-Id match"); 7522f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 7532f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 7542f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (attr->cui) { 7552f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt num_attr++; 7562f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt count = 0; 7572f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 75804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (sta = hapd->sta_list; sta; sta = sta->next) { 75904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpabuf *cui; 7602f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 7612f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (!sta->radius_das_match) 7622f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt continue; 76304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cui = ieee802_1x_get_radius_cui(sta->eapol_sm); 7642f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (!cui || wpabuf_len(cui) != attr->cui_len || 76504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcmp(wpabuf_head(cui), attr->cui, 7662f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt attr->cui_len) != 0) 7672f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt sta->radius_das_match = 0; 7682f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt else 7692f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt count++; 77004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 7712f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 7722f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (count == 0) { 7732f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, 7742f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "RADIUS DAS: No matches remaining after Chargeable-User-Identity check"); 7752f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return NULL; 7762f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 7772f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, 7782f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "RADIUS DAS: Chargeable-User-Identity match"); 77904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 78004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 7812f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (attr->user_name) { 7822f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt num_attr++; 7832f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt count = 0; 7842f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 78504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (sta = hapd->sta_list; sta; sta = sta->next) { 78604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 *identity; 78704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt size_t identity_len; 7882f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 7892f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (!sta->radius_das_match) 7902f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt continue; 79104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt identity = ieee802_1x_get_identity(sta->eapol_sm, 79204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt &identity_len); 7932f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (!identity || 7942f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt identity_len != attr->user_name_len || 79504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcmp(identity, attr->user_name, identity_len) 7962f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt != 0) 7972f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt sta->radius_das_match = 0; 7982f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt else 7992f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt count++; 8002f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 8012f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 8022f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (count == 0) { 8032f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, 8042f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "RADIUS DAS: No matches remaining after User-Name check"); 8052f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return NULL; 8062f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 8072f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, 8082f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "RADIUS DAS: User-Name match"); 8092f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 8102f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 8112f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (num_attr == 0) { 8122f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt /* 8132f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt * In theory, we could match all current associations, but it 8142f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt * seems safer to just reject requests that do not include any 8152f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt * session identification attributes. 8162f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt */ 8172f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, 8182f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "RADIUS DAS: No session identification attributes included"); 8192f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return NULL; 8202f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 8212f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 8222f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt selected = NULL; 8232f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt for (sta = hapd->sta_list; sta; sta = sta->next) { 8242f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (sta->radius_das_match) { 8252f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (selected) { 8262f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt *multi = 1; 8272f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return NULL; 8282f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 8292f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt selected = sta; 83004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 83104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 83204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 8332f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return selected; 8342f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt} 8352f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 8362f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 8372f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidtstatic int hostapd_das_disconnect_pmksa(struct hostapd_data *hapd, 8382f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt struct radius_das_attrs *attr) 8392f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt{ 8402f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (!hapd->wpa_auth) 8412f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return -1; 8422f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return wpa_auth_radius_das_disconnect_pmksa(hapd->wpa_auth, attr); 84304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 84404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 84504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 84604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic enum radius_das_res 84704949598a23f501be6eec21697465fd46a28840aDmitry Shmidthostapd_das_disconnect(void *ctx, struct radius_das_attrs *attr) 84804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 84904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct hostapd_data *hapd = ctx; 85004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct sta_info *sta; 8512f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt int multi; 85204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 85304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (hostapd_das_nas_mismatch(hapd, attr)) 85404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return RADIUS_DAS_NAS_MISMATCH; 85504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 8562f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt sta = hostapd_das_find_sta(hapd, attr, &multi); 8572f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (sta == NULL) { 8582f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (multi) { 8592f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, 8602f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "RADIUS DAS: Multiple sessions match - not supported"); 8612f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return RADIUS_DAS_MULTI_SESSION_MATCH; 8622f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 8632f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (hostapd_das_disconnect_pmksa(hapd, attr) == 0) { 8642f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, 8652f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "RADIUS DAS: PMKSA cache entry matched"); 8662f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return RADIUS_DAS_SUCCESS; 8672f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 8682f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, "RADIUS DAS: No matching session found"); 86904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return RADIUS_DAS_SESSION_NOT_FOUND; 8702f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 87104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 8722f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, "RADIUS DAS: Found a matching session " MACSTR 8732f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt " - disconnecting", MAC2STR(sta->addr)); 87413ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr); 87513ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt 87604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_drv_sta_deauth(hapd, sta->addr, 87704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt WLAN_REASON_PREV_AUTH_NOT_VALID); 87804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ap_sta_deauthenticate(hapd, sta, WLAN_REASON_PREV_AUTH_NOT_VALID); 87904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 88004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return RADIUS_DAS_SUCCESS; 88104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 88204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 88304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_setup_bss - Per-BSS setup (initialization) 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hapd: Pointer to BSS data 889cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * @first: Whether this BSS is the first BSS of an interface; -1 = not first, 890cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * but interface may exist 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to initialize all per-BSS data structures and 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * resources. This gets called in a loop for each BSS when an interface is 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * initialized. Most of the modules that are initialized here will be 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * deinitialized in hostapd_cleanup(). 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_setup_bss(struct hostapd_data *hapd, int first) 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_bss_config *conf = hapd->conf; 9009d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt u8 ssid[SSID_MAX_LEN + 1]; 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ssid_len, set_ssid; 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char force_ifname[IFNAMSIZ]; 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 if_addr[ETH_ALEN]; 9046c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int flush_old_stations = 1; 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9065460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(hapd=%p (%s), first=%d)", 907661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt __func__, hapd, conf->iface, first); 9085460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 90950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt#ifdef EAP_SERVER_TNC 910661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (conf->tnc && tncs_global_init() < 0) { 91150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to initialize TNCS"); 91250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt return -1; 91350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt } 91450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt#endif /* EAP_SERVER_TNC */ 91550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 9165460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt if (hapd->started) { 9175460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Interface %s was already started", 918661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt __func__, conf->iface); 9195460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt return -1; 9205460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt } 9215460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd->started = 1; 9225460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 923cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!first || first == -1) { 92431a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt u8 *addr = hapd->own_addr; 92531a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt 92631a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt if (!is_zero_ether_addr(conf->bssid)) { 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Allocate the configured BSSID. */ 928661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt os_memcpy(hapd->own_addr, conf->bssid, ETH_ALEN); 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_mac_comp(hapd->own_addr, 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface->bss[0]->own_addr) == 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "BSS '%s' may not have " 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "BSSID set to the MAC address of " 935661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt "the radio", conf->iface); 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 93831a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt } else if (hapd->iconf->use_driver_iface_addr) { 93931a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt addr = NULL; 94031a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt } else { 94131a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt /* Allocate the next available BSSID. */ 94231a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt do { 94331a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt inc_byte_array(hapd->own_addr, ETH_ALEN); 94431a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt } while (mac_in_conf(hapd->iconf, hapd->own_addr)); 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9475460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd->interface_added = 1; 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_if_add(hapd->iface->bss[0], WPA_IF_AP_BSS, 94931a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt conf->iface, addr, hapd, 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &hapd->drv_priv, force_ifname, if_addr, 951661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt conf->bridge[0] ? conf->bridge : NULL, 952661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt first == -1)) { 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to add BSS (BSSID=" 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR ")", MAC2STR(hapd->own_addr)); 9553cf6f79011d16f23e60cbf2846aab0fd440511daDmitry Shmidt hapd->interface_added = 0; 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 95831a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt 95931a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt if (!addr) 96031a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt os_memcpy(hapd->own_addr, if_addr, ETH_ALEN); 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->wmm_enabled < 0) 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->wmm_enabled = hapd->iconf->ieee80211n; 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9669839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#ifdef CONFIG_IEEE80211R_AP 9679c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt if (is_zero_ether_addr(conf->r1_key_holder)) 9689c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt os_memcpy(conf->r1_key_holder, hapd->own_addr, ETH_ALEN); 9699839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt#endif /* CONFIG_IEEE80211R_AP */ 9709c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt 9716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_MESH 9726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (hapd->iface->mconf == NULL) 9736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt flush_old_stations = 0; 9746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_MESH */ 9756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 9766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (flush_old_stations) 9776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hostapd_flush_old_stations(hapd, 9786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt WLAN_REASON_PREV_AUTH_NOT_VALID); 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_privacy(hapd, 0); 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_broadcast_wep_clear(hapd); 982661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (hostapd_setup_encryption(conf->iface, hapd)) 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Fetch the SSID from the system and use it or, 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * if one was specified in the config file, verify they 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * match. 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid_len = hostapd_get_ssid(hapd, ssid, sizeof(ssid)); 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid_len < 0) { 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not read SSID from system"); 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->ssid.ssid_set) { 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If SSID is specified in the config file and it differs 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * from what is being used then force installation of the 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * new SSID. 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt set_ssid = (conf->ssid.ssid_len != (size_t) ssid_len || 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(conf->ssid.ssid, ssid, ssid_len) != 0); 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * No SSID in the config file; just use the one we got 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * from the system. 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt set_ssid = 0; 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->ssid.ssid_len = ssid_len; 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conf->ssid.ssid, ssid, conf->ssid.ssid_len); 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!hostapd_drv_none(hapd)) { 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Using interface %s with hwaddr " MACSTR 101561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt " and ssid \"%s\"", 1016661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt conf->iface, MAC2STR(hapd->own_addr), 1017661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt wpa_ssid_txt(conf->ssid.ssid, conf->ssid.ssid_len)); 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_setup_wpa_psk(conf)) { 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "WPA-PSK setup failed."); 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Set SSID for the kernel driver (to be used in beacon and probe 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * response frames) */ 102761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (set_ssid && hostapd_set_ssid(hapd, conf->ssid.ssid, 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->ssid.ssid_len)) { 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver"); 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1033818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (wpa_debug_level <= MSG_MSGDUMP) 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->radius->msg_dumps = 1; 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->radius = radius_client_init(hapd, conf->radius); 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->radius == NULL) { 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "RADIUS client initialization failed."); 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 104104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 1042661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (conf->radius_das_port) { 104304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct radius_das_conf das_conf; 104404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memset(&das_conf, 0, sizeof(das_conf)); 1045661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt das_conf.port = conf->radius_das_port; 1046661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt das_conf.shared_secret = conf->radius_das_shared_secret; 104704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt das_conf.shared_secret_len = 1048661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt conf->radius_das_shared_secret_len; 1049661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt das_conf.client_addr = &conf->radius_das_client_addr; 1050661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt das_conf.time_window = conf->radius_das_time_window; 105104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt das_conf.require_event_timestamp = 1052661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt conf->radius_das_require_event_timestamp; 10537f2c753f60025528366b5f19b8b490a47bf5080bDmitry Shmidt das_conf.require_message_authenticator = 10547f2c753f60025528366b5f19b8b490a47bf5080bDmitry Shmidt conf->radius_das_require_message_authenticator; 105504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt das_conf.ctx = hapd; 105604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt das_conf.disconnect = hostapd_das_disconnect; 105704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hapd->radius_das = radius_das_init(&das_conf); 105804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (hapd->radius_das == NULL) { 105904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_ERROR, "RADIUS DAS initialization " 106004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "failed."); 106104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 106204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 106304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_acl_init(hapd)) { 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ACL initialization failed."); 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_init_wps(hapd, conf)) 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (authsrv_init(hapd) < 0) 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ieee802_1x_init(hapd)) { 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "IEEE 802.1X initialization failed."); 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1081661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if ((conf->wpa || conf->osen) && hostapd_setup_wpa(hapd)) 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (accounting_init(hapd)) { 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Accounting initialization failed."); 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1089661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (conf->ieee802_11f && 1090661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt (hapd->iapp = iapp_init(hapd, conf->iapp_iface)) == NULL) { 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "IEEE 802.11F (IAPP) initialization " 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed."); 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 109604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_INTERWORKING 109704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (gas_serv_init(hapd)) { 109804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_ERROR, "GAS server initialization failed"); 109904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 110004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 110104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 1102cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (conf->qos_map_set_len && 1103cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_drv_set_qos_map(hapd, conf->qos_map_set, 1104cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf->qos_map_set_len)) { 1105cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to initialize QoS Map"); 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1108cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#endif /* CONFIG_INTERWORKING */ 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (conf->bss_load_update_period && bss_load_update_init(hapd)) { 11116c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_ERROR, "BSS Load initialization failed"); 11126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 11136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 11146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 11156c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (conf->proxy_arp) { 11166c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (x_snoop_init(hapd)) { 11176c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_ERROR, 11186c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "Generic snooping infrastructure initialization failed"); 11196c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 11206c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 11216c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 11226c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (dhcp_snoop_init(hapd)) { 11236c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_ERROR, 11246c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "DHCP snooping initialization failed"); 11256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 11266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 11276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 11286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (ndisc_snoop_init(hapd)) { 11296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_ERROR, 11306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "Neighbor Discovery snooping initialization failed"); 11316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 11326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 11336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 11346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!hostapd_drv_none(hapd) && vlan_init(hapd)) { 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "VLAN initialization failed."); 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1140661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (!conf->start_disabled && ieee802_11_set_beacon(hapd) < 0) 1141fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return -1; 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (hapd->wpa_auth && wpa_init_keys(hapd->wpa_auth) < 0) 11441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 11451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->driver && hapd->driver->set_operstate) 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->driver->set_operstate(hapd->drv_priv, 1); 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_tx_queue_params(struct hostapd_iface *iface) 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = iface->bss[0]; 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_tx_queue_params *p; 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_MESH 11606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (iface->mconf == NULL) 11616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 11626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_MESH */ 11636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < NUM_TX_QUEUES; i++) { 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = &iface->conf->tx_queue[i]; 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_set_tx_queue_params(hapd, i, p->aifs, p->cwmin, 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p->cwmax, p->burst)) { 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to set TX queue " 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "parameters for queue %d.", i); 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Continue anyway */ 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11778bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidtstatic int hostapd_set_acl_list(struct hostapd_data *hapd, 11788bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt struct mac_acl_entry *mac_acl, 11798bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt int n_entries, u8 accept_acl) 11808bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt{ 11818bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt struct hostapd_acl_params *acl_params; 11828bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt int i, err; 11838bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 11848bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt acl_params = os_zalloc(sizeof(*acl_params) + 11858bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt (n_entries * sizeof(acl_params->mac_acl[0]))); 11868bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt if (!acl_params) 11878bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt return -ENOMEM; 11888bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 11898bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt for (i = 0; i < n_entries; i++) 11908bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt os_memcpy(acl_params->mac_acl[i].addr, mac_acl[i].addr, 11918bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt ETH_ALEN); 11928bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 11938bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt acl_params->acl_policy = accept_acl; 11948bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt acl_params->num_mac_acl = n_entries; 11958bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 11968bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt err = hostapd_drv_set_acl(hapd, acl_params); 11978bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 11988bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt os_free(acl_params); 11998bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 12008bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt return err; 12018bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt} 12028bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 12038bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 12048bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidtstatic void hostapd_set_acl(struct hostapd_data *hapd) 12058bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt{ 12068bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt struct hostapd_config *conf = hapd->iconf; 12078bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt int err; 12088bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt u8 accept_acl; 12098bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 12108bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt if (hapd->iface->drv_max_acl_mac_addrs == 0) 12118bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt return; 12128bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 1213cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (conf->bss[0]->macaddr_acl == DENY_UNLESS_ACCEPTED) { 121443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt accept_acl = 1; 121543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt err = hostapd_set_acl_list(hapd, conf->bss[0]->accept_mac, 121643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt conf->bss[0]->num_accept_mac, 121743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt accept_acl); 121843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (err) { 121943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to set accept acl"); 122043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt return; 12218bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } 1222cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } else if (conf->bss[0]->macaddr_acl == ACCEPT_UNLESS_DENIED) { 122343cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt accept_acl = 0; 122443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt err = hostapd_set_acl_list(hapd, conf->bss[0]->deny_mac, 122543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt conf->bss[0]->num_deny_mac, 122643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt accept_acl); 122743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (err) { 122843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to set deny acl"); 122943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt return; 12308bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } 12318bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } 12328bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt} 12338bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 12348bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 1235cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic int start_ctrl_iface_bss(struct hostapd_data *hapd) 1236cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 1237cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!hapd->iface->interfaces || 1238cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt !hapd->iface->interfaces->ctrl_iface_init) 1239cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 1240cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1241cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd->iface->interfaces->ctrl_iface_init(hapd)) { 1242cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, 1243cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "Failed to setup control interface for %s", 1244cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->conf->iface); 1245cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 1246cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1247cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1248cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 1249cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 1250cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1251cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1252cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic int start_ctrl_iface(struct hostapd_iface *iface) 1253cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 1254cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i; 1255cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1256cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!iface->interfaces || !iface->interfaces->ctrl_iface_init) 1257cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 1258cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1259cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (i = 0; i < iface->num_bss; i++) { 1260cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_data *hapd = iface->bss[i]; 1261cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (iface->interfaces->ctrl_iface_init(hapd)) { 1262cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, 1263cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "Failed to setup control interface for %s", 1264cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->conf->iface); 1265cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 1266cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1267cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1268cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1269cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 1270cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 1271cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1272cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1273cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic void channel_list_update_timeout(void *eloop_ctx, void *timeout_ctx) 1274cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 1275cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface *iface = eloop_ctx; 1276cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1277cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!iface->wait_channel_update) { 1278cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "Channel list update timeout, but interface was not waiting for it"); 1279cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return; 1280cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1281cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1282cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* 1283cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * It is possible that the existing channel list is acceptable, so try 1284cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * to proceed. 1285cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 1286cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_DEBUG, "Channel list update timeout - try to continue anyway"); 1287cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt setup_interface2(iface); 1288cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 1289cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1290cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1291e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtvoid hostapd_channel_list_updated(struct hostapd_iface *iface, int initiator) 1292cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 1293e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!iface->wait_channel_update || initiator != REGDOM_SET_BY_USER) 1294cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return; 1295cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1296cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_DEBUG, "Channel list updated - continue setup"); 1297cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt eloop_cancel_timeout(channel_list_update_timeout, iface, NULL); 1298cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt setup_interface2(iface); 1299cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 1300cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1301cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int setup_interface(struct hostapd_iface *iface) 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = iface->bss[0]; 13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 1306cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1307a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt /* 1308a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt * It is possible that setup_interface() is called after the interface 1309a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt * was disabled etc., in which case driver_ap_teardown is possibly set 1310a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt * to 1. Clear it here so any other key/station deletion, which is not 1311a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt * part of a teardown flow, would also call the relevant driver 1312a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt * callbacks. 1313a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt */ 1314a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt iface->driver_ap_teardown = 0; 1315a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt 1316cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!iface->phy[0]) { 1317cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt const char *phy = hostapd_drv_get_radio_name(hapd); 1318cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (phy) { 1319cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_DEBUG, "phy: %s", phy); 1320cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_strlcpy(iface->phy, phy, sizeof(iface->phy)); 1321cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1322cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Make sure that all BSSes get configured with a pointer to the same 13268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * driver interface. 13278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 1; i < iface->num_bss; i++) { 13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->bss[i]->driver = hapd->driver; 13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->bss[i]->drv_priv = hapd->drv_priv; 13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_validate_bssid_configuration(iface)) 13348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1336cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* 1337cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * Initialize control interfaces early to allow external monitoring of 1338cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * channel setup operations that may take considerable amount of time 1339cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * especially for DFS cases. 1340cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 1341cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (start_ctrl_iface(iface)) 1342cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 1343cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iconf->country[0] && hapd->iconf->country[1]) { 1345cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt char country[4], previous_country[4]; 1346cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1347cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_set_state(iface, HAPD_IFACE_COUNTRY_UPDATE); 1348cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hostapd_get_country(hapd, previous_country) < 0) 1349cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt previous_country[0] = '\0'; 1350cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(country, hapd->iconf->country, 3); 13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt country[3] = '\0'; 13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_set_country(hapd, country) < 0) { 13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to set country code"); 13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1357cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1358cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_DEBUG, "Previous country code %s, new country code %s", 1359cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt previous_country, country); 1360cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1361cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (os_strncmp(previous_country, country, 2) != 0) { 1362cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_DEBUG, "Continue interface setup after channel list update"); 1363cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->wait_channel_update = 1; 13649767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt eloop_register_timeout(5, 0, 1365cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt channel_list_update_timeout, 1366cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface, NULL); 1367cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 1368cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1371cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return setup_interface2(iface); 1372cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 1373cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1374cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1375cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic int setup_interface2(struct hostapd_iface *iface) 1376cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 1377cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->wait_channel_update = 0; 1378cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_get_hw_features(iface)) { 13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Not all drivers support this yet, so continue without hw 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * feature data. */ 13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = hostapd_select_hw_mode(iface); 13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) { 13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not select hw_mode and " 13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel. (%d)", ret); 1387b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1389391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (ret == 1) { 1390391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_DEBUG, "Interface initialization will be completed in a callback (ACS)"); 1391391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return 0; 1392391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = hostapd_check_ht_capab(iface); 13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) 1395b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret == 1) { 13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Interface initialization will " 13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "be completed in a callback"); 13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1401051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1402051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (iface->conf->ieee80211h) 1403051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_printf(MSG_DEBUG, "DFS support is enabled"); 14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return hostapd_setup_interface_complete(iface, 0); 1406b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt 1407b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidtfail: 1408b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt hostapd_set_state(iface, HAPD_IFACE_DISABLED); 1409b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_DISABLED); 1410b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (iface->interfaces && iface->interfaces->terminate_on_error) 1411b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt eloop_terminate(); 1412b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt return -1; 14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1416d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifdef CONFIG_FST 1417d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1418d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic const u8 * fst_hostapd_get_bssid_cb(void *ctx) 1419d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 1420d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct hostapd_data *hapd = ctx; 1421d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1422d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return hapd->own_addr; 1423d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 1424d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1425d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1426d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic void fst_hostapd_get_channel_info_cb(void *ctx, 1427d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt enum hostapd_hw_mode *hw_mode, 1428d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt u8 *channel) 1429d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 1430d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct hostapd_data *hapd = ctx; 1431d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1432d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt *hw_mode = ieee80211_freq_to_chan(hapd->iface->freq, channel); 1433d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 1434d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1435d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1436d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic void fst_hostapd_set_ies_cb(void *ctx, const struct wpabuf *fst_ies) 1437d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 1438d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct hostapd_data *hapd = ctx; 1439d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1440d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (hapd->iface->fst_ies != fst_ies) { 1441d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt hapd->iface->fst_ies = fst_ies; 1442d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (ieee802_11_set_beacon(hapd)) 1443d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_WARNING, "FST: Cannot set beacon"); 1444d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 1445d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 1446d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1447d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1448d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int fst_hostapd_send_action_cb(void *ctx, const u8 *da, 1449d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct wpabuf *buf) 1450d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 1451d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct hostapd_data *hapd = ctx; 1452d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1453d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return hostapd_drv_send_action(hapd, hapd->iface->freq, 0, da, 1454d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpabuf_head(buf), wpabuf_len(buf)); 1455d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 1456d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1457d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1458d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic const struct wpabuf * fst_hostapd_get_mb_ie_cb(void *ctx, const u8 *addr) 1459d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 1460d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct hostapd_data *hapd = ctx; 1461d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct sta_info *sta = ap_get_sta(hapd, addr); 1462d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1463d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return sta ? sta->mb_ies : NULL; 1464d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 1465d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1466d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1467d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic void fst_hostapd_update_mb_ie_cb(void *ctx, const u8 *addr, 1468d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const u8 *buf, size_t size) 1469d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 1470d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct hostapd_data *hapd = ctx; 1471d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct sta_info *sta = ap_get_sta(hapd, addr); 1472d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1473d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (sta) { 1474d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct mb_ies_info info; 1475d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1476d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!mb_ies_info_by_ies(&info, buf, size)) { 1477d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpabuf_free(sta->mb_ies); 1478d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt sta->mb_ies = mb_ies_by_info(&info); 1479d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 1480d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 1481d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 1482d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1483d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1484d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic const u8 * fst_hostapd_get_sta(struct fst_get_peer_ctx **get_ctx, 1485d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt Boolean mb_only) 1486d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 1487d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct sta_info *s = (struct sta_info *) *get_ctx; 1488d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1489d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (mb_only) { 1490d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt for (; s && !s->mb_ies; s = s->next) 1491d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ; 1492d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 1493d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1494d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (s) { 1495d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt *get_ctx = (struct fst_get_peer_ctx *) s->next; 1496d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1497d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return s->addr; 1498d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 1499d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1500d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt *get_ctx = NULL; 1501d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return NULL; 1502d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 1503d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1504d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1505d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic const u8 * fst_hostapd_get_peer_first(void *ctx, 1506d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_get_peer_ctx **get_ctx, 1507d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt Boolean mb_only) 1508d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 1509d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct hostapd_data *hapd = ctx; 1510d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1511d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt *get_ctx = (struct fst_get_peer_ctx *) hapd->sta_list; 1512d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1513d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return fst_hostapd_get_sta(get_ctx, mb_only); 1514d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 1515d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1516d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1517d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic const u8 * fst_hostapd_get_peer_next(void *ctx, 1518d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_get_peer_ctx **get_ctx, 1519d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt Boolean mb_only) 1520d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 1521d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return fst_hostapd_get_sta(get_ctx, mb_only); 1522d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 1523d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1524d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1525d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtvoid fst_hostapd_fill_iface_obj(struct hostapd_data *hapd, 1526d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_wpa_obj *iface_obj) 1527d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 1528d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt iface_obj->ctx = hapd; 1529d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt iface_obj->get_bssid = fst_hostapd_get_bssid_cb; 1530d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt iface_obj->get_channel_info = fst_hostapd_get_channel_info_cb; 1531d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt iface_obj->set_ies = fst_hostapd_set_ies_cb; 1532d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt iface_obj->send_action = fst_hostapd_send_action_cb; 1533d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt iface_obj->get_mb_ie = fst_hostapd_get_mb_ie_cb; 1534d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt iface_obj->update_mb_ie = fst_hostapd_update_mb_ie_cb; 1535d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt iface_obj->get_peer_first = fst_hostapd_get_peer_first; 1536d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt iface_obj->get_peer_next = fst_hostapd_get_peer_next; 1537d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 1538d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1539d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* CONFIG_FST */ 1540d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1541d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1542849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt#ifdef NEED_AP_MLME 1543849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidtstatic enum nr_chan_width hostapd_get_nr_chan_width(struct hostapd_data *hapd, 1544849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt int ht, int vht) 1545849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt{ 1546849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (!ht && !vht) 1547849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt return NR_CHAN_WIDTH_20; 1548849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (!hapd->iconf->secondary_channel) 1549849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt return NR_CHAN_WIDTH_20; 1550849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (!vht || hapd->iconf->vht_oper_chwidth == VHT_CHANWIDTH_USE_HT) 1551849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt return NR_CHAN_WIDTH_40; 1552849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (hapd->iconf->vht_oper_chwidth == VHT_CHANWIDTH_80MHZ) 1553849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt return NR_CHAN_WIDTH_80; 1554849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (hapd->iconf->vht_oper_chwidth == VHT_CHANWIDTH_160MHZ) 1555849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt return NR_CHAN_WIDTH_160; 1556849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (hapd->iconf->vht_oper_chwidth == VHT_CHANWIDTH_80P80MHZ) 1557849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt return NR_CHAN_WIDTH_80P80; 1558849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt return NR_CHAN_WIDTH_20; 1559849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt} 1560849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt#endif /* NEED_AP_MLME */ 1561849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 1562849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 1563849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidtstatic void hostapd_set_own_neighbor_report(struct hostapd_data *hapd) 1564849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt{ 1565849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt#ifdef NEED_AP_MLME 1566849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt u16 capab = hostapd_own_capab_info(hapd); 1567849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt int ht = hapd->iconf->ieee80211n && !hapd->conf->disable_11n; 1568849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt int vht = hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac; 1569849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt struct wpa_ssid_value ssid; 1570849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt u8 channel, op_class; 15719839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt u8 center_freq1_idx = 0, center_freq2_idx = 0; 1572849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt enum nr_chan_width width; 1573849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt u32 bssid_info; 1574849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt struct wpabuf *nr; 1575849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 1576849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (!(hapd->conf->radio_measurements[0] & 1577849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt WLAN_RRM_CAPS_NEIGHBOR_REPORT)) 1578849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt return; 1579849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 1580849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt bssid_info = 3; /* AP is reachable */ 1581849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt bssid_info |= NEI_REP_BSSID_INFO_SECURITY; /* "same as the AP" */ 1582849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt bssid_info |= NEI_REP_BSSID_INFO_KEY_SCOPE; /* "same as the AP" */ 1583849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 1584849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT) 1585849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt bssid_info |= NEI_REP_BSSID_INFO_SPECTRUM_MGMT; 1586849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 1587849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt bssid_info |= NEI_REP_BSSID_INFO_RM; /* RRM is supported */ 1588849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 1589849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (hapd->conf->wmm_enabled) { 1590849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt bssid_info |= NEI_REP_BSSID_INFO_QOS; 1591849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 1592849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (hapd->conf->wmm_uapsd && 1593849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_UAPSD)) 1594849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt bssid_info |= NEI_REP_BSSID_INFO_APSD; 1595849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt } 1596849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 1597849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (ht) { 1598849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt bssid_info |= NEI_REP_BSSID_INFO_HT | 1599849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt NEI_REP_BSSID_INFO_DELAYED_BA; 1600849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 1601849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt /* VHT bit added in IEEE P802.11-REVmc/D4.3 */ 1602849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (vht) 1603849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt bssid_info |= NEI_REP_BSSID_INFO_VHT; 1604849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt } 1605849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 1606849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt /* TODO: Set NEI_REP_BSSID_INFO_MOBILITY_DOMAIN if MDE is set */ 1607849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 1608293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt if (ieee80211_freq_to_channel_ext(hapd->iface->freq, 1609293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt hapd->iconf->secondary_channel, 1610293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt hapd->iconf->vht_oper_chwidth, 1611293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt &op_class, &channel) == 1612293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt NUM_HOSTAPD_MODES) 1613293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt return; 1614849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt width = hostapd_get_nr_chan_width(hapd, ht, vht); 1615849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (vht) { 16169839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt center_freq1_idx = hapd->iconf->vht_oper_centr_freq_seg0_idx; 1617849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (width == NR_CHAN_WIDTH_80P80) 16189839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt center_freq2_idx = 16199839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt hapd->iconf->vht_oper_centr_freq_seg1_idx; 1620849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt } else if (ht) { 16219839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt ieee80211_freq_to_chan(hapd->iface->freq + 16229839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt 10 * hapd->iconf->secondary_channel, 16239839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt ¢er_freq1_idx); 1624849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt } 1625849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 1626849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt ssid.ssid_len = hapd->conf->ssid.ssid_len; 1627849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt os_memcpy(ssid.ssid, hapd->conf->ssid.ssid, ssid.ssid_len); 1628849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 1629849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt /* 1630849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt * Neighbor Report element size = BSSID + BSSID info + op_class + chan + 1631849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt * phy type + wide bandwidth channel subelement. 1632849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt */ 1633849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt nr = wpabuf_alloc(ETH_ALEN + 4 + 1 + 1 + 1 + 5); 1634849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (!nr) 1635849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt return; 1636849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 1637849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt wpabuf_put_data(nr, hapd->own_addr, ETH_ALEN); 1638849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt wpabuf_put_le32(nr, bssid_info); 1639849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt wpabuf_put_u8(nr, op_class); 1640849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt wpabuf_put_u8(nr, channel); 1641849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt wpabuf_put_u8(nr, ieee80211_get_phy_type(hapd->iface->freq, ht, vht)); 1642849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 1643849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt /* 1644849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt * Wide Bandwidth Channel subelement may be needed to allow the 1645849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt * receiving STA to send packets to the AP. See IEEE P802.11-REVmc/D5.0 1646849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt * Figure 9-301. 1647849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt */ 1648849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt wpabuf_put_u8(nr, WNM_NEIGHBOR_WIDE_BW_CHAN); 1649849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt wpabuf_put_u8(nr, 3); 1650849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt wpabuf_put_u8(nr, width); 16519839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt wpabuf_put_u8(nr, center_freq1_idx); 16529839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt wpabuf_put_u8(nr, center_freq2_idx); 1653849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 1654849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt hostapd_neighbor_set(hapd, hapd->own_addr, &ssid, nr, hapd->iconf->lci, 16559839ecd75c832023d4d13fd2917a8c28261ff668Dmitry Shmidt hapd->iconf->civic, hapd->iconf->stationary_ap); 1656849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 1657849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt wpabuf_free(nr); 1658849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt#endif /* NEED_AP_MLME */ 1659849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt} 1660849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 1661849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 1662d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int hostapd_setup_interface_complete_sync(struct hostapd_iface *iface, 1663d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int err) 16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = iface->bss[0]; 16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t j; 16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *prev_addr; 16686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int delay_apply_cfg = 0; 1669203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt int res_dfs_offload = 0; 16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1671b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (err) 1672b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Completing interface initialization"); 1675cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (iface->conf->channel) { 1676051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#ifdef NEED_AP_MLME 1677051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt int res; 1678051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#endif /* NEED_AP_MLME */ 1679051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1680cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->freq = hostapd_hw_get_freq(hapd, iface->conf->channel); 16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Mode: %s Channel: %d " 16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Frequency: %d MHz", 1683cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_hw_mode_txt(iface->conf->hw_mode), 1684cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->channel, iface->freq); 16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1686051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#ifdef NEED_AP_MLME 1687661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt /* Handle DFS only if it is not offloaded to the driver */ 1688661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (!(iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)) { 1689661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt /* Check DFS */ 1690661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt res = hostapd_handle_dfs(iface); 1691661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (res <= 0) { 1692661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (res < 0) 1693661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt goto fail; 1694661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return res; 1695661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt } 1696203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt } else { 1697203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt /* If DFS is offloaded to the driver */ 1698203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt res_dfs_offload = hostapd_handle_dfs_offload(iface); 1699203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt if (res_dfs_offload <= 0) { 1700203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt if (res_dfs_offload < 0) 1701203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt goto fail; 1702203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt } else { 1703203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt wpa_printf(MSG_DEBUG, 1704203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt "Proceed with AP/channel setup"); 1705203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt /* 1706203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt * If this is a DFS channel, move to completing 1707203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt * AP setup. 1708203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt */ 1709203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt if (res_dfs_offload == 1) 1710203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt goto dfs_offload; 1711203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt /* Otherwise fall through. */ 1712203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt } 1713b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt } 1714051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#endif /* NEED_AP_MLME */ 1715051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 17166c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_MESH 17176c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (iface->mconf != NULL) { 17186c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 17196c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "%s: Mesh configuration will be applied while joining the mesh network", 17206c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt iface->bss[0]->conf->iface); 17216c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt delay_apply_cfg = 1; 17226c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 17236c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_MESH */ 17246c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 17256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!delay_apply_cfg && 17266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hostapd_set_freq(hapd, hapd->iconf->hw_mode, iface->freq, 17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iconf->channel, 17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iconf->ieee80211n, 1729a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hapd->iconf->ieee80211ac, 1730a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hapd->iconf->secondary_channel, 1731a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hapd->iconf->vht_oper_chwidth, 1732a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hapd->iconf->vht_oper_centr_freq_seg0_idx, 1733a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hapd->iconf->vht_oper_centr_freq_seg1_idx)) { 17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not set channel for " 17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "kernel driver"); 1736b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface->current_mode) { 17411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (hostapd_prepare_rates(iface, iface->current_mode)) { 17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to prepare rates " 17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "table."); 17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, 17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_WARNING, 17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to prepare rates table."); 1747b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iconf->rts_threshold > -1 && 17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_rts(hapd, hapd->iconf->rts_threshold)) { 17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not set RTS threshold for " 17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "kernel driver"); 1755b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iconf->fragm_threshold > -1 && 17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_frag(hapd, hapd->iconf->fragm_threshold)) { 17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not set fragmentation threshold " 17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for kernel driver"); 1762b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev_addr = hapd->own_addr; 17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd = iface->bss[j]; 17698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (j) 17708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN); 1771717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (hostapd_setup_bss(hapd, j == 0)) { 1772717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt do { 1773717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hapd = iface->bss[j]; 1774717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_bss_deinit_no_free(hapd); 1775717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_free_hapd_data(hapd); 1776717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt } while (j-- > 0); 1777b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 1778717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt } 17799c17526f86859e2b6aebac0ed4f2561601816103Dmitry Shmidt if (is_zero_ether_addr(hapd->conf->bssid)) 17808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev_addr = hapd->own_addr; 17818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1782cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd = iface->bss[0]; 17838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_tx_queue_params(iface); 17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_list_init(iface); 17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17888bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt hostapd_set_acl(hapd); 17898bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_driver_commit(hapd) < 0) { 17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Failed to commit driver " 17928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "configuration", __func__); 1793b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 179687fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen /* 179787fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen * WPS UPnP module can be initialized only when the "upnp_iface" is up. 179887fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen * If "interface" and "upnp_iface" are the same (e.g., non-bridge 179987fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen * mode), the interface is up only after driver_commit, so initialize 180087fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen * WPS after driver_commit. 180187fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen */ 180287fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen for (j = 0; j < iface->num_bss; j++) { 180387fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen if (hostapd_init_wps_complete(iface->bss[j])) 1804b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 180587fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen } 180687fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen 1807203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt if ((iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) && 1808203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt !res_dfs_offload) { 1809203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt /* 1810203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt * If freq is DFS, and DFS is offloaded to the driver, then wait 1811203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt * for CAC to complete. 1812203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt */ 1813203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: Wait for CAC to complete", __func__); 1814203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt return res_dfs_offload; 1815203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt } 1816203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt 1817203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt#ifdef NEED_AP_MLME 1818203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidtdfs_offload: 1819203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt#endif /* NEED_AP_MLME */ 1820d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1821d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifdef CONFIG_FST 1822d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (hapd->iconf->fst_cfg.group_id[0]) { 1823d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct fst_wpa_obj iface_obj; 1824d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1825d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_hostapd_fill_iface_obj(hapd, &iface_obj); 1826d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt iface->fst = fst_attach(hapd->conf->iface, hapd->own_addr, 1827d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt &iface_obj, &hapd->iconf->fst_cfg); 1828d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!iface->fst) { 1829d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not attach to FST %s", 1830d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt hapd->iconf->fst_cfg.group_id); 1831d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt goto fail; 1832d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 1833d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 1834d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* CONFIG_FST */ 1835d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1836cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_set_state(iface, HAPD_IFACE_ENABLED); 1837cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_ENABLED); 18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->setup_complete_cb) 18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->setup_complete_cb(hapd->setup_complete_cb_ctx); 18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: Setup of interface done.", 18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->bss[0]->conf->iface); 1843b96dad47218788efffa3db0fe7f1b54a7d19e366Dmitry Shmidt if (iface->interfaces && iface->interfaces->terminate_on_error > 0) 1844b96dad47218788efffa3db0fe7f1b54a7d19e366Dmitry Shmidt iface->interfaces->terminate_on_error--; 18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1846849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt for (j = 0; j < iface->num_bss; j++) 1847849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt hostapd_set_own_neighbor_report(iface->bss[j]); 1848849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1850b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt 1851b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidtfail: 1852b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt wpa_printf(MSG_ERROR, "Interface initialization failed"); 1853b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt hostapd_set_state(iface, HAPD_IFACE_DISABLED); 1854b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED); 1855d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifdef CONFIG_FST 1856d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (iface->fst) { 1857d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_detach(iface->fst); 1858d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt iface->fst = NULL; 1859d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 1860d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* CONFIG_FST */ 1861b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (iface->interfaces && iface->interfaces->terminate_on_error) 1862b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt eloop_terminate(); 1863b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt return -1; 18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1868d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * hostapd_setup_interface_complete - Complete interface setup 1869d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * 1870d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * This function is called when previous steps in the interface setup has been 1871d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * completed. This can also start operations, e.g., DFS, that will require 1872d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * additional processing before interface is ready to be enabled. Such 1873d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * operations will call this function from eloop callbacks when finished. 1874d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt */ 1875d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtint hostapd_setup_interface_complete(struct hostapd_iface *iface, int err) 1876d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 1877d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct hapd_interfaces *interfaces = iface->interfaces; 1878d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct hostapd_data *hapd = iface->bss[0]; 1879d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned int i; 1880d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int not_ready_in_sync_ifaces = 0; 1881d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1882d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!iface->need_to_start_in_sync) 1883d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return hostapd_setup_interface_complete_sync(iface, err); 1884d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1885d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (err) { 1886d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_ERROR, "Interface initialization failed"); 1887d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt hostapd_set_state(iface, HAPD_IFACE_DISABLED); 1888d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt iface->need_to_start_in_sync = 0; 1889d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED); 1890d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (interfaces && interfaces->terminate_on_error) 1891d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt eloop_terminate(); 1892d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 1893d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 1894d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1895d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (iface->ready_to_start_in_sync) { 1896d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* Already in ready and waiting. should never happpen */ 1897d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return 0; 1898d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 1899d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1900d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt for (i = 0; i < interfaces->count; i++) { 1901d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (interfaces->iface[i]->need_to_start_in_sync && 1902d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt !interfaces->iface[i]->ready_to_start_in_sync) 1903d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt not_ready_in_sync_ifaces++; 1904d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 1905d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1906d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* 1907d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * Check if this is the last interface, if yes then start all the other 1908d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * waiting interfaces. If not, add this interface to the waiting list. 1909d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt */ 1910d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (not_ready_in_sync_ifaces > 1 && iface->state == HAPD_IFACE_DFS) { 1911d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* 1912d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * If this interface went through CAC, do not synchronize, just 1913d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * start immediately. 1914d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt */ 1915d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt iface->need_to_start_in_sync = 0; 1916d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_INFO, 1917d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "%s: Finished CAC - bypass sync and start interface", 1918d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt iface->bss[0]->conf->iface); 1919d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return hostapd_setup_interface_complete_sync(iface, err); 1920d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 1921d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1922d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (not_ready_in_sync_ifaces > 1) { 1923d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* need to wait as there are other interfaces still coming up */ 1924d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt iface->ready_to_start_in_sync = 1; 1925d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_INFO, 1926d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "%s: Interface waiting to sync with other interfaces", 1927d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt iface->bss[0]->conf->iface); 1928d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return 0; 1929d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 1930d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1931d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_INFO, 1932d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "%s: Last interface to sync - starting all interfaces", 1933d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt iface->bss[0]->conf->iface); 1934d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt iface->need_to_start_in_sync = 0; 1935d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt hostapd_setup_interface_complete_sync(iface, err); 1936d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt for (i = 0; i < interfaces->count; i++) { 1937d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (interfaces->iface[i]->need_to_start_in_sync && 1938d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt interfaces->iface[i]->ready_to_start_in_sync) { 1939d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt hostapd_setup_interface_complete_sync( 1940d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt interfaces->iface[i], 0); 1941d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* Only once the interfaces are sync started */ 1942d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt interfaces->iface[i]->need_to_start_in_sync = 0; 1943d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 1944d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 1945d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1946d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return 0; 1947d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 1948d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1949d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1950d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt/** 19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_setup_interface - Setup of an interface 19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @iface: Pointer to interface data. 19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 19548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 19558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Initializes the driver interface, validates the configuration, 19568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * and sets driver parameters based on the configuration. 19578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Flushes old stations, sets the channel, encryption, 19588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * beacons, and WDS links based on the configuration. 1959cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * 1960cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * If interface setup requires more time, e.g., to perform HT co-ex scans, ACS, 1961cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * or DFS operations, this function returns 0 before such operations have been 1962cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * completed. The pending operations are registered into eloop and will be 1963cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * completed from eloop callbacks. Those callbacks end up calling 1964cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_setup_interface_complete() once setup has been completed. 19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_setup_interface(struct hostapd_iface *iface) 19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = setup_interface(iface); 19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) { 19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Unable to setup interface.", 19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->bss[0]->conf->iface); 19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_alloc_bss_data - Allocate and initialize per-BSS data 19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hapd_iface: Pointer to interface data 19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conf: Pointer to per-interface configuration 19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @bss: Pointer to per-BSS configuration for this BSS 19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to allocated BSS data 19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to allocate per-BSS data structure. This data will be 19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * freed after hostapd_cleanup() is called for it during interface 19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * deinitialization. 19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct hostapd_data * 19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidthostapd_alloc_bss_data(struct hostapd_iface *hapd_iface, 19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_config *conf, 19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_bss_config *bss) 19968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd; 19988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd = os_zalloc(sizeof(*hapd)); 20008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd == NULL) 20018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 20028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->new_assoc_sta_cb = hostapd_new_assoc_sta; 20048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iconf = conf; 20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf = bss; 20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface = hapd_iface; 2007ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt if (conf) 2008ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt hapd->driver = conf->driver; 200904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hapd->ctrl_sock = -1; 201031a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt dl_list_init(&hapd->ctrl_dst); 20117d17530e229db79208e99741071df97ea4faeec6Dmitry Shmidt dl_list_init(&hapd->nr_db); 2012ebd93af924f6e54fb4982b3312ff875a4896b62bDmitry Shmidt hapd->dhcp_sock = -1; 20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return hapd; 20158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20185460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidtstatic void hostapd_bss_deinit(struct hostapd_data *hapd) 20195460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt{ 2020d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt if (!hapd) 2021d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt return; 20225460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: deinit bss %s", __func__, 20235460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd->conf->iface); 2024717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_bss_deinit_no_free(hapd); 2025f73259cc00af557e36add405799b7f2326587c13Dmitry Shmidt wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED); 20265460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_cleanup(hapd); 20275460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt} 20285460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 20295460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 20308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid hostapd_interface_deinit(struct hostapd_iface *iface) 20318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2032cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt int j; 20338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20345460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); 20358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface == NULL) 20368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 20378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2038f73259cc00af557e36add405799b7f2326587c13Dmitry Shmidt hostapd_set_state(iface, HAPD_IFACE_DISABLED); 2039f73259cc00af557e36add405799b7f2326587c13Dmitry Shmidt 20407832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt#ifdef CONFIG_IEEE80211N 20417832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt#ifdef NEED_AP_MLME 20427832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt hostapd_stop_setup_timers(iface); 20437832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt eloop_cancel_timeout(ap_ht2040_timeout, iface, NULL); 20447832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt#endif /* NEED_AP_MLME */ 20457832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt#endif /* CONFIG_IEEE80211N */ 2046cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt eloop_cancel_timeout(channel_list_update_timeout, iface, NULL); 2047cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->wait_channel_update = 0; 2048cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2049d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifdef CONFIG_FST 2050d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (iface->fst) { 2051d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_detach(iface->fst); 2052d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt iface->fst = NULL; 2053d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 2054d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* CONFIG_FST */ 2055d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 2056d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt for (j = iface->num_bss - 1; j >= 0; j--) { 2057d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt if (!iface->bss) 2058d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt break; 20595460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_bss_deinit(iface->bss[j]); 2060d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt } 20618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid hostapd_interface_free(struct hostapd_iface *iface) 20658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t j; 20675460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); 20685460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 2069d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt if (!iface->bss) 2070d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt break; 20715460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: free hapd %p", 20725460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, iface->bss[j]); 20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(iface->bss[j]); 20745460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt } 20758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_cleanup_iface(iface); 20768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2079aca489e0b2daec9e67dd611b7a44f47bd1f41e27Dmitry Shmidtstruct hostapd_iface * hostapd_alloc_iface(void) 2080aca489e0b2daec9e67dd611b7a44f47bd1f41e27Dmitry Shmidt{ 2081aca489e0b2daec9e67dd611b7a44f47bd1f41e27Dmitry Shmidt struct hostapd_iface *hapd_iface; 2082aca489e0b2daec9e67dd611b7a44f47bd1f41e27Dmitry Shmidt 2083aca489e0b2daec9e67dd611b7a44f47bd1f41e27Dmitry Shmidt hapd_iface = os_zalloc(sizeof(*hapd_iface)); 2084aca489e0b2daec9e67dd611b7a44f47bd1f41e27Dmitry Shmidt if (!hapd_iface) 2085aca489e0b2daec9e67dd611b7a44f47bd1f41e27Dmitry Shmidt return NULL; 2086aca489e0b2daec9e67dd611b7a44f47bd1f41e27Dmitry Shmidt 2087aca489e0b2daec9e67dd611b7a44f47bd1f41e27Dmitry Shmidt dl_list_init(&hapd_iface->sta_seen); 2088aca489e0b2daec9e67dd611b7a44f47bd1f41e27Dmitry Shmidt 2089aca489e0b2daec9e67dd611b7a44f47bd1f41e27Dmitry Shmidt return hapd_iface; 2090aca489e0b2daec9e67dd611b7a44f47bd1f41e27Dmitry Shmidt} 2091aca489e0b2daec9e67dd611b7a44f47bd1f41e27Dmitry Shmidt 2092aca489e0b2daec9e67dd611b7a44f47bd1f41e27Dmitry Shmidt 2093cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt/** 2094cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_init - Allocate and initialize per-interface data 2095cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * @config_file: Path to the configuration file 2096cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * Returns: Pointer to the allocated interface data or %NULL on failure 2097cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * 2098cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * This function is used to allocate main data structures for per-interface 2099cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * data. The allocated data buffer will be freed by calling 2100cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_cleanup_iface(). 2101cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 2102cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstruct hostapd_iface * hostapd_init(struct hapd_interfaces *interfaces, 2103cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt const char *config_file) 2104cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 2105cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface *hapd_iface = NULL; 2106cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_config *conf = NULL; 2107cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_data *hapd; 2108cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i; 2109cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2110aca489e0b2daec9e67dd611b7a44f47bd1f41e27Dmitry Shmidt hapd_iface = hostapd_alloc_iface(); 2111cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd_iface == NULL) 2112cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto fail; 2113cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2114cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->config_fname = os_strdup(config_file); 2115cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd_iface->config_fname == NULL) 2116cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto fail; 2117cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2118cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf = interfaces->config_read_cb(hapd_iface->config_fname); 2119cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (conf == NULL) 2120cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto fail; 2121cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->conf = conf; 2122cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2123cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->num_bss = conf->num_bss; 2124cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->bss = os_calloc(conf->num_bss, 2125cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt sizeof(struct hostapd_data *)); 2126cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd_iface->bss == NULL) 2127cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto fail; 2128cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2129cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (i = 0; i < conf->num_bss; i++) { 2130cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd = hapd_iface->bss[i] = 2131cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_alloc_bss_data(hapd_iface, conf, 2132cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf->bss[i]); 2133cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd == NULL) 2134cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto fail; 2135cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->msg_ctx = hapd; 2136cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2137cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2138cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return hapd_iface; 2139cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2140cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtfail: 2141cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to set up interface with %s", 2142cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt config_file); 2143cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (conf) 2144cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_config_free(conf); 2145cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd_iface) { 2146cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_free(hapd_iface->config_fname); 2147cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_free(hapd_iface->bss); 21485460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: free iface %p", 21495460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, hapd_iface); 2150cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_free(hapd_iface); 2151cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2152cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 2153cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 2154cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2155cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2156cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic int ifname_in_use(struct hapd_interfaces *interfaces, const char *ifname) 2157cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 2158cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i, j; 2159cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2160cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (i = 0; i < interfaces->count; i++) { 2161cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface *iface = interfaces->iface[i]; 2162cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 2163cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_data *hapd = iface->bss[j]; 2164cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (os_strcmp(ifname, hapd->conf->iface) == 0) 2165cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 1; 2166cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2167cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2168cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2169cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 2170cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 2171cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2172cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2173cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt/** 2174cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_interface_init_bss - Read configuration file and init BSS data 2175cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * 2176cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * This function is used to parse configuration file for a BSS. This BSS is 2177cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * added to an existing interface sharing the same radio (if any) or a new 2178cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * interface is created if this is the first interface on a radio. This 2179cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * allocate memory for the BSS. No actual driver operations are started. 2180cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * 2181cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * This is similar to hostapd_interface_init(), but for a case where the 2182cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * configuration is used to add a single BSS instead of all BSSes for a radio. 2183cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 2184cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstruct hostapd_iface * 2185cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidthostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy, 2186cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt const char *config_fname, int debug) 2187cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 2188cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface *new_iface = NULL, *iface = NULL; 2189cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_data *hapd; 2190cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt int k; 2191cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i, bss_idx; 2192cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2193cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!phy || !*phy) 2194cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 2195cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2196cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (i = 0; i < interfaces->count; i++) { 2197cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (os_strcmp(interfaces->iface[i]->phy, phy) == 0) { 2198cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface = interfaces->iface[i]; 2199cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt break; 2200cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2201cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2202cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2203cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "Configuration file: %s (phy %s)%s", 2204cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt config_fname, phy, iface ? "" : " --> new PHY"); 2205cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (iface) { 2206cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_config *conf; 2207cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_bss_config **tmp_conf; 2208cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_data **tmp_bss; 2209cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_bss_config *bss; 2210cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt const char *ifname; 2211cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2212cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* Add new BSS to existing iface */ 2213cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf = interfaces->config_read_cb(config_fname); 2214cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (conf == NULL) 2215cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 2216cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (conf->num_bss > 1) { 2217cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "Multiple BSSes specified in BSS-config"); 2218cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_config_free(conf); 2219cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 2220cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2221cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2222cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt ifname = conf->bss[0]->iface; 2223cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (ifname[0] != '\0' && ifname_in_use(interfaces, ifname)) { 2224cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, 2225cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "Interface name %s already in use", ifname); 2226cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_config_free(conf); 2227cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 2228cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2229cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2230cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt tmp_conf = os_realloc_array( 2231cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->bss, iface->conf->num_bss + 1, 2232cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt sizeof(struct hostapd_bss_config *)); 2233cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt tmp_bss = os_realloc_array(iface->bss, iface->num_bss + 1, 2234cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt sizeof(struct hostapd_data *)); 2235cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (tmp_bss) 2236cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->bss = tmp_bss; 2237cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (tmp_conf) { 2238cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->bss = tmp_conf; 2239cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->last_bss = tmp_conf[0]; 2240cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2241cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (tmp_bss == NULL || tmp_conf == NULL) { 2242cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_config_free(conf); 2243cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 2244cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2245cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt bss = iface->conf->bss[iface->conf->num_bss] = conf->bss[0]; 2246cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->num_bss++; 2247cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2248cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd = hostapd_alloc_bss_data(iface, iface->conf, bss); 2249cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd == NULL) { 2250cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->num_bss--; 2251cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_config_free(conf); 2252cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 2253cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2254cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->last_bss = bss; 2255cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->bss[iface->num_bss] = hapd; 2256cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->msg_ctx = hapd; 2257cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2258cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt bss_idx = iface->num_bss++; 2259cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf->num_bss--; 2260cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf->bss[0] = NULL; 2261cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_config_free(conf); 2262cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } else { 2263cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* Add a new iface with the first BSS */ 2264cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt new_iface = iface = hostapd_init(interfaces, config_fname); 2265cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!iface) 2266cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 2267cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_strlcpy(iface->phy, phy, sizeof(iface->phy)); 2268cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->interfaces = interfaces; 2269cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt bss_idx = 0; 2270cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2271cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2272cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (k = 0; k < debug; k++) { 2273cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (iface->bss[bss_idx]->conf->logger_stdout_level > 0) 2274cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->bss[bss_idx]->conf->logger_stdout_level--; 2275cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2276cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2277cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (iface->conf->bss[bss_idx]->iface[0] == '\0' && 2278cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt !hostapd_drv_none(iface->bss[bss_idx])) { 2279cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "Interface name not specified in %s", 2280cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt config_fname); 2281cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (new_iface) 2282cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_interface_deinit_free(new_iface); 2283cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 2284cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2285cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2286cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return iface; 2287cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 2288cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 228961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 229061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid hostapd_interface_deinit_free(struct hostapd_iface *iface) 229161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 229261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const struct wpa_driver_ops *driver; 229361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt void *drv_priv; 22945460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 22955460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); 229661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (iface == NULL) 229761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 22985460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: num_bss=%u conf->num_bss=%u", 22995460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, (unsigned int) iface->num_bss, 23005460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt (unsigned int) iface->conf->num_bss); 230161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt driver = iface->bss[0]->driver; 230261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt drv_priv = iface->bss[0]->drv_priv; 230361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_interface_deinit(iface); 23045460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", 23055460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, driver, drv_priv); 2306717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (driver && driver->hapd_deinit && drv_priv) { 230761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt driver->hapd_deinit(drv_priv); 2308717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt iface->bss[0]->drv_priv = NULL; 2309717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt } 231061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_interface_free(iface); 231161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 231261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 231361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 231415907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidtstatic void hostapd_deinit_driver(const struct wpa_driver_ops *driver, 231515907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt void *drv_priv, 231615907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt struct hostapd_iface *hapd_iface) 231715907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt{ 231815907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt size_t j; 231915907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt 232015907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", 232115907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt __func__, driver, drv_priv); 232215907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt if (driver && driver->hapd_deinit && drv_priv) { 232315907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt driver->hapd_deinit(drv_priv); 232415907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt for (j = 0; j < hapd_iface->num_bss; j++) { 232515907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s:bss[%d]->drv_priv=%p", 232615907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt __func__, (int) j, 232715907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt hapd_iface->bss[j]->drv_priv); 232815907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt if (hapd_iface->bss[j]->drv_priv == drv_priv) 232915907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt hapd_iface->bss[j]->drv_priv = NULL; 233015907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt } 233115907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt } 233215907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt} 233315907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt 233415907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt 233561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint hostapd_enable_iface(struct hostapd_iface *hapd_iface) 233661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 2337717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt size_t j; 2338717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 233961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface->bss[0]->drv_priv != NULL) { 234061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "Interface %s already enabled", 2341cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->conf->bss[0]->iface); 234261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 234361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 234461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 234561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "Enable interface %s", 2346cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->conf->bss[0]->iface); 234761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2348717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt for (j = 0; j < hapd_iface->num_bss; j++) 2349717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_set_security_params(hapd_iface->conf->bss[j], 1); 2350344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt if (hostapd_config_check(hapd_iface->conf, 1) < 0) { 2351344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt wpa_printf(MSG_INFO, "Invalid configuration - cannot enable"); 2352344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt return -1; 2353344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt } 2354344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt 235561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface->interfaces == NULL || 235661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface->interfaces->driver_init == NULL || 2357cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->interfaces->driver_init(hapd_iface)) 2358cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 2359cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2360cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hostapd_setup_interface(hapd_iface)) { 236115907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt hostapd_deinit_driver(hapd_iface->bss[0]->driver, 236215907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt hapd_iface->bss[0]->drv_priv, 236315907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt hapd_iface); 236461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 236561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 2366cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 236761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 236861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 236961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 237061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 237161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint hostapd_reload_iface(struct hostapd_iface *hapd_iface) 237261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 237361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t j; 237461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 237561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "Reload interface %s", 2376cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->conf->bss[0]->iface); 2377cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (j = 0; j < hapd_iface->num_bss; j++) 2378717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_set_security_params(hapd_iface->conf->bss[j], 1); 2379344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt if (hostapd_config_check(hapd_iface->conf, 1) < 0) { 2380cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "Updated configuration is invalid"); 2381cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 238261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 2383cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_clear_old(hapd_iface); 2384cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (j = 0; j < hapd_iface->num_bss; j++) 2385cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_reload_bss(hapd_iface->bss[j]); 2386cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 238761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 238861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 238961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 239061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 239161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint hostapd_disable_iface(struct hostapd_iface *hapd_iface) 239261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 239361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t j; 239461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const struct wpa_driver_ops *driver; 239561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt void *drv_priv; 239661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 239761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface == NULL) 239861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 2399717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 2400717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (hapd_iface->bss[0]->drv_priv == NULL) { 2401717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt wpa_printf(MSG_INFO, "Interface %s already disabled", 2402717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hapd_iface->conf->bss[0]->iface); 2403717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt return -1; 2404717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt } 2405717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 2406cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_msg(hapd_iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_DISABLED); 240761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt driver = hapd_iface->bss[0]->driver; 240861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt drv_priv = hapd_iface->bss[0]->drv_priv; 240961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2410a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt hapd_iface->driver_ap_teardown = 2411a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt !!(hapd_iface->drv_flags & 2412a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT); 2413a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt 2414a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt /* same as hostapd_interface_deinit without deinitializing ctrl-iface */ 241561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (j = 0; j < hapd_iface->num_bss; j++) { 241661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_data *hapd = hapd_iface->bss[j]; 2417717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_bss_deinit_no_free(hapd); 241861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_free_hapd_data(hapd); 241961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 242061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 242115907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt hostapd_deinit_driver(driver, drv_priv, hapd_iface); 242261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 242361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* From hostapd_cleanup_iface: These were initialized in 242461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * hostapd_setup_interface and hostapd_setup_interface_complete 242561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 242661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_cleanup_iface_partial(hapd_iface); 242761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 24285605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_printf(MSG_DEBUG, "Interface %s disabled", 24295605286c30e1701491bd3af974ae423727750eddDmitry Shmidt hapd_iface->bss[0]->conf->iface); 2430cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_set_state(hapd_iface, HAPD_IFACE_DISABLED); 243161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 243261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 243361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 243461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 243561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic struct hostapd_iface * 243661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidthostapd_iface_alloc(struct hapd_interfaces *interfaces) 243761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 243861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_iface **iface, *hapd_iface; 243961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 244061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt iface = os_realloc_array(interfaces->iface, interfaces->count + 1, 244161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sizeof(struct hostapd_iface *)); 244261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (iface == NULL) 244361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 244461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->iface = iface; 244561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface = interfaces->iface[interfaces->count] = 2446aca489e0b2daec9e67dd611b7a44f47bd1f41e27Dmitry Shmidt hostapd_alloc_iface(); 244761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface == NULL) { 244861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Failed to allocate memory for " 244961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "the interface", __func__); 245061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 245161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 245261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->count++; 245361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface->interfaces = interfaces; 245461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 245561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return hapd_iface; 245661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 245761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 245861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 245961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic struct hostapd_config * 246061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidthostapd_config_alloc(struct hapd_interfaces *interfaces, const char *ifname, 2461d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const char *ctrl_iface, const char *driver) 246261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 246361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_bss_config *bss; 246461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_config *conf; 246561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 246661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Allocates memory for bss and conf */ 246761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt conf = hostapd_config_defaults(); 246861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (conf == NULL) { 246961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Failed to allocate memory for " 247061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "configuration", __func__); 247161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 247261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 247361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2474d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (driver) { 2475d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int j; 2476d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 2477d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt for (j = 0; wpa_drivers[j]; j++) { 2478d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (os_strcmp(driver, wpa_drivers[j]->name) == 0) { 2479d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conf->driver = wpa_drivers[j]; 2480d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt goto skip; 2481d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 2482d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 2483d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 2484d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_ERROR, 2485d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "Invalid/unknown driver '%s' - registering the default driver", 2486d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt driver); 2487d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 2488d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 248961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt conf->driver = wpa_drivers[0]; 249061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (conf->driver == NULL) { 249161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "No driver wrappers registered!"); 249261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_config_free(conf); 249361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 249461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 249561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2496d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtskip: 2497cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt bss = conf->last_bss = conf->bss[0]; 249861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 249961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_strlcpy(bss->iface, ifname, sizeof(bss->iface)); 250061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt bss->ctrl_interface = os_strdup(ctrl_iface); 250161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (bss->ctrl_interface == NULL) { 250261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_config_free(conf); 250361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 250461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 250561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 250661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Reading configuration file skipped, will be done in SET! 250761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * From reading the configuration till the end has to be done in 250861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * SET 250961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 251061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return conf; 251161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 251261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 251361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2514ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidtstatic int hostapd_data_alloc(struct hostapd_iface *hapd_iface, 2515ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt struct hostapd_config *conf) 251661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 251761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t i; 251861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_data *hapd; 251961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 25206c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hapd_iface->bss = os_calloc(conf->num_bss, 252161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sizeof(struct hostapd_data *)); 252261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface->bss == NULL) 2523ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return -1; 252461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 252561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (i = 0; i < conf->num_bss; i++) { 252661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd = hapd_iface->bss[i] = 2527cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_alloc_bss_data(hapd_iface, conf, conf->bss[i]); 2528ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (hapd == NULL) { 2529ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt while (i > 0) { 2530ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt i--; 2531ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt os_free(hapd_iface->bss[i]); 2532ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt hapd_iface->bss[i] = NULL; 2533ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 2534ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt os_free(hapd_iface->bss); 2535ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt hapd_iface->bss = NULL; 2536ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return -1; 2537ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 253861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd->msg_ctx = hapd; 253961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 254061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2541ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt hapd_iface->conf = conf; 2542ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt hapd_iface->num_bss = conf->num_bss; 254361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2544ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return 0; 254561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 254661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 254761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 254861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint hostapd_add_iface(struct hapd_interfaces *interfaces, char *buf) 254961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 255061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_config *conf = NULL; 2551cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface *hapd_iface = NULL, *new_iface = NULL; 2552cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_data *hapd; 255361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char *ptr; 2554cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i, j; 2555cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt const char *conf_file = NULL, *phy_name = NULL; 2556cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2557cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (os_strncmp(buf, "bss_config=", 11) == 0) { 2558cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt char *pos; 2559cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt phy_name = buf + 11; 2560cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt pos = os_strchr(phy_name, ':'); 2561cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!pos) 2562cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 2563cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt *pos++ = '\0'; 2564cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf_file = pos; 2565cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!os_strlen(conf_file)) 2566cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 2567cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2568cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface = hostapd_interface_init_bss(interfaces, phy_name, 2569cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf_file, 0); 2570cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!hapd_iface) 2571cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 2572cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (j = 0; j < interfaces->count; j++) { 2573cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (interfaces->iface[j] == hapd_iface) 2574cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt break; 2575cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2576cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (j == interfaces->count) { 2577cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface **tmp; 2578cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt tmp = os_realloc_array(interfaces->iface, 2579cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt interfaces->count + 1, 2580cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt sizeof(struct hostapd_iface *)); 2581cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!tmp) { 2582cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_interface_deinit_free(hapd_iface); 2583cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 2584cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2585cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt interfaces->iface = tmp; 2586cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt interfaces->iface[interfaces->count++] = hapd_iface; 2587cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt new_iface = hapd_iface; 2588cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2589cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2590cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (new_iface) { 2591ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (interfaces->driver_init(hapd_iface)) 2592cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto fail; 25936c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 25946c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (hostapd_setup_interface(hapd_iface)) { 25956c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hostapd_deinit_driver( 25966c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hapd_iface->bss[0]->driver, 25976c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hapd_iface->bss[0]->drv_priv, 25986c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hapd_iface); 25996c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt goto fail; 26006c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 2601cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } else { 2602cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* Assign new BSS with bss[0]'s driver info */ 2603cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd = hapd_iface->bss[hapd_iface->num_bss - 1]; 2604cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->driver = hapd_iface->bss[0]->driver; 2605cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->drv_priv = hapd_iface->bss[0]->drv_priv; 2606cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_memcpy(hapd->own_addr, hapd_iface->bss[0]->own_addr, 2607cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt ETH_ALEN); 2608cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2609cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (start_ctrl_iface_bss(hapd) < 0 || 26105460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt (hapd_iface->state == HAPD_IFACE_ENABLED && 26115460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_setup_bss(hapd, -1))) { 2612b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt hostapd_cleanup(hapd); 26137d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt hapd_iface->bss[hapd_iface->num_bss - 1] = NULL; 2614cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->conf->num_bss--; 2615cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->num_bss--; 26165460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: free hapd %p %s", 26175460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, hapd, hapd->conf->iface); 2618ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt hostapd_config_free_bss(hapd->conf); 2619ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt hapd->conf = NULL; 2620cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_free(hapd); 2621cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 2622cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2623cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2624cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 2625cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 262661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 262761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ptr = os_strchr(buf, ' '); 262861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (ptr == NULL) 262961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 263061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *ptr++ = '\0'; 263161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 26325605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (os_strncmp(ptr, "config=", 7) == 0) 26335605286c30e1701491bd3af974ae423727750eddDmitry Shmidt conf_file = ptr + 7; 26345605286c30e1701491bd3af974ae423727750eddDmitry Shmidt 263561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (i = 0; i < interfaces->count; i++) { 2636cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!os_strcmp(interfaces->iface[i]->conf->bss[0]->iface, 263761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf)) { 263861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_INFO, "Cannot add interface - it " 263961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "already exists"); 264061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 264161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 264261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 264361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 264461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface = hostapd_iface_alloc(interfaces); 264561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface == NULL) { 264661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Failed to allocate memory " 264761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "for interface", __func__); 264861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt goto fail; 264961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 2650ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt new_iface = hapd_iface; 265161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 26525605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (conf_file && interfaces->config_read_cb) { 26535605286c30e1701491bd3af974ae423727750eddDmitry Shmidt conf = interfaces->config_read_cb(conf_file); 26545605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (conf && conf->bss) 2655cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_strlcpy(conf->bss[0]->iface, buf, 2656cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt sizeof(conf->bss[0]->iface)); 2657d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } else { 2658d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt char *driver = os_strchr(ptr, ' '); 2659d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 2660d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (driver) 2661d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt *driver++ = '\0'; 2662d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conf = hostapd_config_alloc(interfaces, buf, ptr, driver); 2663d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 2664d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 26655605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (conf == NULL || conf->bss == NULL) { 266661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Failed to allocate memory " 266761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "for configuration", __func__); 266861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt goto fail; 266961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 267061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2671ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (hostapd_data_alloc(hapd_iface, conf) < 0) { 267261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Failed to allocate memory " 267361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "for hostapd", __func__); 267461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt goto fail; 267561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 2676ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conf = NULL; 267761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2678cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (start_ctrl_iface(hapd_iface) < 0) 267961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt goto fail; 2680cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2681ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_INFO, "Add interface '%s'", 2682ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt hapd_iface->conf->bss[0]->iface); 268361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 268461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 268561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 268661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtfail: 268761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (conf) 268861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_config_free(conf); 268961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface) { 2690cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd_iface->bss) { 26915460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt for (i = 0; i < hapd_iface->num_bss; i++) { 26925460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd = hapd_iface->bss[i]; 26937d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt if (!hapd) 26947d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt continue; 26957d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt if (hapd_iface->interfaces && 26965460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd_iface->interfaces->ctrl_iface_deinit) 26975460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd_iface->interfaces-> 26985460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt ctrl_iface_deinit(hapd); 26995460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: free hapd %p (%s)", 27005460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, hapd_iface->bss[i], 27017d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt hapd->conf->iface); 27026c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hostapd_cleanup(hapd); 27037d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt os_free(hapd); 27047d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt hapd_iface->bss[i] = NULL; 27055460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt } 2706cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_free(hapd_iface->bss); 27076c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hapd_iface->bss = NULL; 2708cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2709ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (new_iface) { 2710ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt interfaces->count--; 2711ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt interfaces->iface[interfaces->count] = NULL; 2712ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 27136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hostapd_cleanup_iface(hapd_iface); 271461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 271561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 271661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 271761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 271861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2719cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic int hostapd_remove_bss(struct hostapd_iface *iface, unsigned int idx) 2720cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 2721cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i; 2722cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 27235460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_INFO, "Remove BSS '%s'", iface->conf->bss[idx]->iface); 2724cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 27255460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt /* Remove hostapd_data only if it has already been initialized */ 27265460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt if (idx < iface->num_bss) { 27275460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt struct hostapd_data *hapd = iface->bss[idx]; 2728cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 27295460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_bss_deinit(hapd); 27305460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: free hapd %p (%s)", 27315460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, hapd, hapd->conf->iface); 27325460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_config_free_bss(hapd->conf); 2733ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt hapd->conf = NULL; 27345460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt os_free(hapd); 27355460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 27365460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt iface->num_bss--; 27375460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 27385460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt for (i = idx; i < iface->num_bss; i++) 27395460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt iface->bss[i] = iface->bss[i + 1]; 27405460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt } else { 27415460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_config_free_bss(iface->conf->bss[idx]); 27425460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt iface->conf->bss[idx] = NULL; 27435460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt } 2744cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2745cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->num_bss--; 27465460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt for (i = idx; i < iface->conf->num_bss; i++) 2747cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->bss[i] = iface->conf->bss[i + 1]; 2748cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2749cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 2750cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 2751cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2752cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 275361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint hostapd_remove_iface(struct hapd_interfaces *interfaces, char *buf) 275461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 275561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_iface *hapd_iface; 2756cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i, j, k = 0; 275761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 275861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (i = 0; i < interfaces->count; i++) { 275961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface = interfaces->iface[i]; 276061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface == NULL) 276161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 27625460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt if (!os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) { 276361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_INFO, "Remove interface '%s'", buf); 2764a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt hapd_iface->driver_ap_teardown = 2765a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt !!(hapd_iface->drv_flags & 2766a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT); 2767a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt 276861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_interface_deinit_free(hapd_iface); 276961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt k = i; 277061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt while (k < (interfaces->count - 1)) { 277161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->iface[k] = 277261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->iface[k + 1]; 277361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt k++; 277461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 277561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->count--; 277661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 277761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 2778cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2779cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (j = 0; j < hapd_iface->conf->num_bss; j++) { 2780a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt if (!os_strcmp(hapd_iface->conf->bss[j]->iface, buf)) { 2781a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt hapd_iface->driver_ap_teardown = 2782a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt !(hapd_iface->drv_flags & 2783a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT); 2784cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return hostapd_remove_bss(hapd_iface, j); 2785a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt } 2786cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 278761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 278861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 278961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 279061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 279161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 27928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 27938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_new_assoc_sta - Notify that a new station associated with the AP 27948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hapd: Pointer to BSS data 27958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sta: Pointer to the associated STA data 27968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @reassoc: 1 to indicate this was a re-association; 0 = first association 27978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 27988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function will be called whenever a station associates with the AP. It 27998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * can be called from ieee802_11.c for drivers that export MLME to hostapd and 28008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * from drv_callbacks.c based on driver events for drivers that take care of 28018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * management frames (IEEE 802.11 authentication and association) internally. 28028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 28038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta, 28048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int reassoc) 28058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->tkip_countermeasures) { 28078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_drv_sta_deauth(hapd, sta->addr, 28088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_REASON_MICHAEL_MIC_FAILURE); 28098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 28108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_prune_associations(hapd, sta->addr); 28131d6bf427f4769edb60865a3999d01eeb8f8fcb19Dmitry Shmidt ap_sta_clear_disconnect_timeouts(hapd, sta); 28148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* IEEE 802.11F (IAPP) */ 28168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ieee802_11f) 28178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iapp_new_station(hapd->iapp, sta); 28188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P 28208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->p2p_ie == NULL && !sta->no_p2p_set) { 28218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->no_p2p_set = 1; 28228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->num_sta_no_p2p++; 28238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->num_sta_no_p2p == 1) 28248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_p2p_non_p2p_sta_connected(hapd); 28258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */ 28278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Start accounting here, if IEEE 802.1X and WPA are not used. 28298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * IEEE 802.1X/WPA code will start accounting after the station has 28308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * been authorized. */ 28312ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt if (!hapd->conf->ieee802_1x && !hapd->conf->wpa && !hapd->conf->osen) { 28322ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt ap_sta_set_authorized(hapd, sta, 1); 283304f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt os_get_reltime(&sta->connected_time); 28348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt accounting_sta_start(hapd, sta); 2835d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 28368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Start IEEE 802.1X authentication process for new stations */ 28388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_new_station(hapd, sta); 28398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reassoc) { 28408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->auth_alg != WLAN_AUTH_FT && 28418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS))) 28428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH); 28438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 28448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm); 284504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 2846abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt if (hapd->iface->drv_flags & WPA_DRIVER_FLAGS_WIRED) { 2847abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt if (eloop_cancel_timeout(ap_handle_timer, hapd, sta) > 0) { 2848abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt wpa_printf(MSG_DEBUG, 2849abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt "%s: %s: canceled wired ap_handle_timer timeout for " 2850abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt MACSTR, 2851abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt hapd->conf->iface, __func__, 2852abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt MAC2STR(sta->addr)); 2853abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt } 2854abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt } else if (!(hapd->iface->drv_flags & 2855abb90a3fc1917e628167827cb14e742000605332Dmitry Shmidt WPA_DRIVER_FLAGS_INACTIVITY_TIMER)) { 28561d6bf427f4769edb60865a3999d01eeb8f8fcb19Dmitry Shmidt wpa_printf(MSG_DEBUG, 28571d6bf427f4769edb60865a3999d01eeb8f8fcb19Dmitry Shmidt "%s: %s: reschedule ap_handle_timer timeout for " 28581d6bf427f4769edb60865a3999d01eeb8f8fcb19Dmitry Shmidt MACSTR " (%d seconds - ap_max_inactivity)", 28591d6bf427f4769edb60865a3999d01eeb8f8fcb19Dmitry Shmidt hapd->conf->iface, __func__, MAC2STR(sta->addr), 286001904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt hapd->conf->ap_max_inactivity); 286101904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt eloop_cancel_timeout(ap_handle_timer, hapd, sta); 286201904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt eloop_register_timeout(hapd->conf->ap_max_inactivity, 0, 286301904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt ap_handle_timer, hapd, sta); 286401904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt } 28658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2866cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2867cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2868cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtconst char * hostapd_state_text(enum hostapd_iface_state s) 2869cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 2870cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt switch (s) { 2871cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_UNINITIALIZED: 2872cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "UNINITIALIZED"; 2873cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_DISABLED: 2874cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "DISABLED"; 2875cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_COUNTRY_UPDATE: 2876cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "COUNTRY_UPDATE"; 2877cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_ACS: 2878cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "ACS"; 2879cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_HT_SCAN: 2880cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "HT_SCAN"; 2881cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_DFS: 2882cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "DFS"; 2883cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_ENABLED: 2884cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "ENABLED"; 2885cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2886cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2887cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "UNKNOWN"; 2888cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 2889cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2890cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2891cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtvoid hostapd_set_state(struct hostapd_iface *iface, enum hostapd_iface_state s) 2892cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 2893cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "%s: interface state %s->%s", 2894d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt iface->conf ? iface->conf->bss[0]->iface : "N/A", 2895d5ab1b53af720d05586ccc0addabe93459f1f388Dmitry Shmidt hostapd_state_text(iface->state), hostapd_state_text(s)); 2896cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->state = s; 2897cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 2898e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2899e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2900d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtint hostapd_csa_in_progress(struct hostapd_iface *iface) 2901d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 2902d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned int i; 2903d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 2904d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt for (i = 0; i < iface->num_bss; i++) 2905d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (iface->bss[i]->csa_in_progress) 2906d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return 1; 2907d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return 0; 2908d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 2909d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 2910d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 2911e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt#ifdef NEED_AP_MLME 2912e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2913e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtstatic void free_beacon_data(struct beacon_data *beacon) 2914e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 2915e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_free(beacon->head); 2916e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->head = NULL; 2917e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_free(beacon->tail); 2918e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->tail = NULL; 2919e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_free(beacon->probe_resp); 2920e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->probe_resp = NULL; 2921e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_free(beacon->beacon_ies); 2922e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->beacon_ies = NULL; 2923e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_free(beacon->proberesp_ies); 2924e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->proberesp_ies = NULL; 2925e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_free(beacon->assocresp_ies); 2926e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->assocresp_ies = NULL; 2927e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 2928e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2929e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2930d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidtstatic int hostapd_build_beacon_data(struct hostapd_data *hapd, 2931e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct beacon_data *beacon) 2932e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 2933e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct wpabuf *beacon_extra, *proberesp_extra, *assocresp_extra; 2934e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct wpa_driver_ap_params params; 2935e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt int ret; 2936e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 293701904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt os_memset(beacon, 0, sizeof(*beacon)); 2938e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = ieee802_11_build_ap_params(hapd, ¶ms); 2939e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret < 0) 2940e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 2941e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2942e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = hostapd_build_ap_extra_ies(hapd, &beacon_extra, 2943e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &proberesp_extra, 2944e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &assocresp_extra); 2945e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) 2946e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_ap_params; 2947e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2948e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = -1; 2949e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->head = os_malloc(params.head_len); 2950e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!beacon->head) 2951e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_ap_extra_ies; 2952e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2953e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memcpy(beacon->head, params.head, params.head_len); 2954e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->head_len = params.head_len; 2955e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2956e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->tail = os_malloc(params.tail_len); 2957e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!beacon->tail) 2958e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_beacon; 2959e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2960e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memcpy(beacon->tail, params.tail, params.tail_len); 2961e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->tail_len = params.tail_len; 2962e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2963e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (params.proberesp != NULL) { 2964e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->probe_resp = os_malloc(params.proberesp_len); 2965e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!beacon->probe_resp) 2966e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_beacon; 2967e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2968e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memcpy(beacon->probe_resp, params.proberesp, 2969e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt params.proberesp_len); 2970e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->probe_resp_len = params.proberesp_len; 2971e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2972e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2973e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* copy the extra ies */ 2974e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (beacon_extra) { 2975e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->beacon_ies = os_malloc(wpabuf_len(beacon_extra)); 2976e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!beacon->beacon_ies) 2977e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_beacon; 2978e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2979e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memcpy(beacon->beacon_ies, 2980e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon_extra->buf, wpabuf_len(beacon_extra)); 2981e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->beacon_ies_len = wpabuf_len(beacon_extra); 2982e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2983e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2984e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (proberesp_extra) { 2985e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->proberesp_ies = 2986e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_malloc(wpabuf_len(proberesp_extra)); 2987e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!beacon->proberesp_ies) 2988e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_beacon; 2989e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2990e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memcpy(beacon->proberesp_ies, proberesp_extra->buf, 2991e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt wpabuf_len(proberesp_extra)); 2992e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->proberesp_ies_len = wpabuf_len(proberesp_extra); 2993e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2994e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2995e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (assocresp_extra) { 2996e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->assocresp_ies = 2997e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_malloc(wpabuf_len(assocresp_extra)); 2998e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!beacon->assocresp_ies) 2999e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_beacon; 3000e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3001e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memcpy(beacon->assocresp_ies, assocresp_extra->buf, 3002e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt wpabuf_len(assocresp_extra)); 3003e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->assocresp_ies_len = wpabuf_len(assocresp_extra); 3004e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 3005e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3006e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = 0; 3007e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtfree_beacon: 3008e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* if the function fails, the caller should not free beacon data */ 3009e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) 3010e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt free_beacon_data(beacon); 3011e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3012e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtfree_ap_extra_ies: 3013e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt hostapd_free_ap_extra_ies(hapd, beacon_extra, proberesp_extra, 3014e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt assocresp_extra); 3015e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtfree_ap_params: 3016e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ieee802_11_free_ap_params(¶ms); 3017e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 3018e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 3019e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3020e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3021e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt/* 3022d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * TODO: This flow currently supports only changing channel and width within 3023d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * the same hw_mode. Any other changes to MAC parameters or provided settings 3024d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt * are not supported. 3025e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt */ 3026e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtstatic int hostapd_change_config_freq(struct hostapd_data *hapd, 3027e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct hostapd_config *conf, 3028e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct hostapd_freq_params *params, 3029e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct hostapd_freq_params *old_params) 3030e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 3031e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt int channel; 3032e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3033e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!params->channel) { 3034e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* check if the new channel is supported by hw */ 3035d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt params->channel = hostapd_hw_get_channel(hapd, params->freq); 3036e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 3037e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3038d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt channel = params->channel; 3039d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt if (!channel) 3040d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt return -1; 3041d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 3042e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* if a pointer to old_params is provided we save previous state */ 3043d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (old_params && 3044d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt hostapd_set_freq_params(old_params, conf->hw_mode, 3045d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt hostapd_hw_get_freq(hapd, conf->channel), 3046d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conf->channel, conf->ieee80211n, 3047d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conf->ieee80211ac, 3048d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conf->secondary_channel, 3049d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conf->vht_oper_chwidth, 3050d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conf->vht_oper_centr_freq_seg0_idx, 3051d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conf->vht_oper_centr_freq_seg1_idx, 3052d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conf->vht_capab)) 3053d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 3054d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3055d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt switch (params->bandwidth) { 3056d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 0: 3057d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 20: 3058d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 40: 3059d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conf->vht_oper_chwidth = VHT_CHANWIDTH_USE_HT; 3060d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 3061d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 80: 3062d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (params->center_freq2) 3063d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conf->vht_oper_chwidth = VHT_CHANWIDTH_80P80MHZ; 3064d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt else 3065d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conf->vht_oper_chwidth = VHT_CHANWIDTH_80MHZ; 3066d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 3067d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 160: 3068d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt conf->vht_oper_chwidth = VHT_CHANWIDTH_160MHZ; 3069d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 3070d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt default: 3071d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 3072e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 3073e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3074e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt conf->channel = channel; 3075e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt conf->ieee80211n = params->ht_enabled; 3076e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt conf->secondary_channel = params->sec_channel_offset; 3077d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ieee80211_freq_to_chan(params->center_freq1, 3078d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt &conf->vht_oper_centr_freq_seg0_idx); 3079d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ieee80211_freq_to_chan(params->center_freq2, 3080d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt &conf->vht_oper_centr_freq_seg1_idx); 3081e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3082e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* TODO: maybe call here hostapd_config_check here? */ 3083e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3084e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return 0; 3085e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 3086e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3087e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3088d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidtstatic int hostapd_fill_csa_settings(struct hostapd_data *hapd, 3089e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct csa_settings *settings) 3090e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 3091d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt struct hostapd_iface *iface = hapd->iface; 3092e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct hostapd_freq_params old_freq; 3093e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt int ret; 3094d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt u8 chan, vht_bandwidth; 3095e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3096e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memset(&old_freq, 0, sizeof(old_freq)); 3097d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt if (!iface || !iface->freq || hapd->csa_in_progress) 3098e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return -1; 3099e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3100d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt switch (settings->freq_params.bandwidth) { 3101d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 80: 3102d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (settings->freq_params.center_freq2) 3103d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt vht_bandwidth = VHT_CHANWIDTH_80P80MHZ; 3104d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt else 3105d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt vht_bandwidth = VHT_CHANWIDTH_80MHZ; 3106d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 3107d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 160: 3108d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt vht_bandwidth = VHT_CHANWIDTH_160MHZ; 3109d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 3110d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt default: 3111d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt vht_bandwidth = VHT_CHANWIDTH_USE_HT; 3112d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 3113d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 3114d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3115d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (ieee80211_freq_to_channel_ext( 3116d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt settings->freq_params.freq, 3117d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt settings->freq_params.sec_channel_offset, 3118d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt vht_bandwidth, 3119d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt &hapd->iface->cs_oper_class, 3120d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt &chan) == NUM_HOSTAPD_MODES) { 3121d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_DEBUG, 3122d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "invalid frequency for channel switch (freq=%d, sec_channel_offset=%d, vht_enabled=%d)", 3123d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt settings->freq_params.freq, 3124d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt settings->freq_params.sec_channel_offset, 3125d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt settings->freq_params.vht_enabled); 3126d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 3127d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 3128d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3129d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt settings->freq_params.channel = chan; 3130d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3131e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = hostapd_change_config_freq(iface->bss[0], iface->conf, 3132e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &settings->freq_params, 3133e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &old_freq); 3134e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) 3135e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 3136e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3137d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt ret = hostapd_build_beacon_data(hapd, &settings->beacon_after); 3138e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3139e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* change back the configuration */ 3140e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt hostapd_change_config_freq(iface->bss[0], iface->conf, 3141e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &old_freq, NULL); 3142e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3143e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) 3144e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 3145e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3146e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* set channel switch parameters for csa ie */ 3147d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->cs_freq_params = settings->freq_params; 3148d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->cs_count = settings->cs_count; 3149d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->cs_block_tx = settings->block_tx; 3150e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3151d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt ret = hostapd_build_beacon_data(hapd, &settings->beacon_csa); 3152e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) { 3153e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt free_beacon_data(&settings->beacon_after); 3154e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 3155e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 3156e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3157d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt settings->counter_offset_beacon[0] = hapd->cs_c_off_beacon; 3158d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt settings->counter_offset_presp[0] = hapd->cs_c_off_proberesp; 3159d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt settings->counter_offset_beacon[1] = hapd->cs_c_off_ecsa_beacon; 3160d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt settings->counter_offset_presp[1] = hapd->cs_c_off_ecsa_proberesp; 3161e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3162e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return 0; 3163e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 3164e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3165e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3166e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtvoid hostapd_cleanup_cs_params(struct hostapd_data *hapd) 3167e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 3168d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt os_memset(&hapd->cs_freq_params, 0, sizeof(hapd->cs_freq_params)); 3169d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->cs_count = 0; 3170d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->cs_block_tx = 0; 3171d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->cs_c_off_beacon = 0; 3172d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->cs_c_off_proberesp = 0; 3173d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->csa_in_progress = 0; 3174d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt hapd->cs_c_off_ecsa_beacon = 0; 3175d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt hapd->cs_c_off_ecsa_proberesp = 0; 3176e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 3177e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3178e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3179e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtint hostapd_switch_channel(struct hostapd_data *hapd, 3180e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct csa_settings *settings) 3181e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 3182e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt int ret; 31836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 31846c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA)) { 31856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_INFO, "CSA is not supported"); 31866c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 31876c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 31886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 3189d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt ret = hostapd_fill_csa_settings(hapd, settings); 3190e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) 3191e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 3192e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3193e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = hostapd_drv_switch_channel(hapd, settings); 3194e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt free_beacon_data(&settings->beacon_csa); 3195e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt free_beacon_data(&settings->beacon_after); 3196e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3197e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) { 3198e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* if we failed, clean cs parameters */ 3199e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt hostapd_cleanup_cs_params(hapd); 3200e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 3201e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 3202e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3203d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->csa_in_progress = 1; 3204e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return 0; 3205e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 3206e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 3207d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 3208d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidtvoid 3209d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidthostapd_switch_channel_fallback(struct hostapd_iface *iface, 3210d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt const struct hostapd_freq_params *freq_params) 3211d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt{ 3212d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt int vht_seg0_idx = 0, vht_seg1_idx = 0, vht_bw = VHT_CHANWIDTH_USE_HT; 3213d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt unsigned int i; 3214d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 3215d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt wpa_printf(MSG_DEBUG, "Restarting all CSA-related BSSes"); 3216d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 3217d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt if (freq_params->center_freq1) 3218d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt vht_seg0_idx = 36 + (freq_params->center_freq1 - 5180) / 5; 3219d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt if (freq_params->center_freq2) 3220d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt vht_seg1_idx = 36 + (freq_params->center_freq2 - 5180) / 5; 3221d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 3222d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt switch (freq_params->bandwidth) { 3223d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt case 0: 3224d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt case 20: 3225d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt case 40: 3226d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt vht_bw = VHT_CHANWIDTH_USE_HT; 3227d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt break; 3228d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt case 80: 3229d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt if (freq_params->center_freq2) 3230d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt vht_bw = VHT_CHANWIDTH_80P80MHZ; 3231d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt else 3232d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt vht_bw = VHT_CHANWIDTH_80MHZ; 3233d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt break; 3234d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt case 160: 3235d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt vht_bw = VHT_CHANWIDTH_160MHZ; 3236d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt break; 3237d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt default: 3238d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt wpa_printf(MSG_WARNING, "Unknown CSA bandwidth: %d", 3239d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt freq_params->bandwidth); 3240d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt break; 3241d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt } 3242d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 3243d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt iface->freq = freq_params->freq; 3244d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt iface->conf->channel = freq_params->channel; 3245d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt iface->conf->secondary_channel = freq_params->sec_channel_offset; 3246d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt iface->conf->vht_oper_centr_freq_seg0_idx = vht_seg0_idx; 3247d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt iface->conf->vht_oper_centr_freq_seg1_idx = vht_seg1_idx; 3248d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt iface->conf->vht_oper_chwidth = vht_bw; 3249d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt iface->conf->ieee80211n = freq_params->ht_enabled; 3250d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt iface->conf->ieee80211ac = freq_params->vht_enabled; 3251d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 3252d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt /* 3253d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt * cs_params must not be cleared earlier because the freq_params 3254d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt * argument may actually point to one of these. 3255d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt */ 3256d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt for (i = 0; i < iface->num_bss; i++) 3257d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hostapd_cleanup_cs_params(iface->bss[i]); 3258d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 3259d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hostapd_disable_iface(iface); 3260d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hostapd_enable_iface(iface); 3261d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt} 3262d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 3263e4663044d3a689fb5458247e9bc0f8b58cf72fcaDmitry Shmidt#endif /* NEED_AP_MLME */ 3264e4663044d3a689fb5458247e9bc0f8b58cf72fcaDmitry Shmidt 3265d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3266d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstruct hostapd_data * hostapd_get_iface(struct hapd_interfaces *interfaces, 3267d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const char *ifname) 3268d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 3269d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt size_t i, j; 3270d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3271d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt for (i = 0; i < interfaces->count; i++) { 3272d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct hostapd_iface *iface = interfaces->iface[i]; 3273d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3274d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 3275d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct hostapd_data *hapd = iface->bss[j]; 3276d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3277d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (os_strcmp(ifname, hapd->conf->iface) == 0) 3278d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return hapd; 3279d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 3280d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 3281d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3282d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return NULL; 3283d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 3284d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3285d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3286d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtvoid hostapd_periodic_iface(struct hostapd_iface *iface) 3287d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 3288d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt size_t i; 3289d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3290d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ap_list_timer(iface); 3291d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3292d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt for (i = 0; i < iface->num_bss; i++) { 3293d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct hostapd_data *hapd = iface->bss[i]; 3294d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3295d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!hapd->started) 3296d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt continue; 3297d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 3298d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 3299d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt hostapd_acl_expire(hapd); 3300d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 3301d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 3302d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 3303