18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd / Initialization and configuration 3344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt * Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/eloop.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h" 14cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#include "common/wpa_ctrl.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "radius/radius_client.h" 1604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "radius/radius_das.h" 1750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt#include "eap_server/tncs.h" 182f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt#include "eapol_auth/eapol_auth_sm.h" 192f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt#include "eapol_auth/eapol_auth_sm_i.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "hostapd.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "authsrv.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "sta_info.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "accounting.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_list.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "beacon.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "iapp.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ieee802_1x.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ieee802_11_auth.h" 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "vlan_init.h" 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_auth.h" 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps_hostapd.h" 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "hw_features.h" 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_auth_glue.h" 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_drv_ops.h" 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_config.h" 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_hostapd.h" 3704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "gas_serv.h" 38051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#include "dfs.h" 397832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt#include "ieee802_11.h" 406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#include "bss_load.h" 416c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#include "x_snoop.h" 426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#include "dhcp_snoop.h" 436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#include "ndisc_snoop.h" 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason); 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd); 48c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidtstatic int hostapd_broadcast_wep_clear(struct hostapd_data *hapd); 49cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic int setup_interface2(struct hostapd_iface *iface); 50cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic void channel_list_update_timeout(void *eloop_ctx, void *timeout_ctx); 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5304949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint hostapd_for_each_interface(struct hapd_interfaces *interfaces, 5404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int (*cb)(struct hostapd_iface *iface, 5504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt void *ctx), void *ctx) 5604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 5704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt size_t i; 5804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int ret; 5904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 6004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (i = 0; i < interfaces->count; i++) { 6104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ret = cb(interfaces->iface[i], ctx); 6204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ret) 6304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return ret; 6404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 6504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 6604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 6704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 6804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 6904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_reload_bss(struct hostapd_data *hapd) 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 72cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_ssid *ssid; 73cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_client_reconfig(hapd->radius, hapd->conf->radius); 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 78cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt ssid = &hapd->conf->ssid; 79cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!ssid->wpa_psk_set && ssid->wpa_psk && !ssid->wpa_psk->next && 80cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt ssid->wpa_passphrase_set && ssid->wpa_passphrase) { 81cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* 82cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * Force PSK to be derived again since SSID or passphrase may 83cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * have changed. 84cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 857f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt hostapd_config_clear_wpa_psk(&hapd->conf->ssid.wpa_psk); 86cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_setup_wpa_psk(hapd->conf)) { 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to re-configure WPA PSK " 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "after reloading configuration"); 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ieee802_1x || hapd->conf->wpa) 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 1); 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 0); 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 97f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if ((hapd->conf->wpa || hapd->conf->osen) && hapd->wpa_auth == NULL) { 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_setup_wpa(hapd); 991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (hapd->wpa_auth) 1001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_init_keys(hapd->wpa_auth); 1011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else if (hapd->conf->wpa) { 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *wpa_ie; 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t wpa_ie_len; 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_reconfig_wpa(hapd); 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &wpa_ie_len); 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_set_generic_elem(hapd, wpa_ie, wpa_ie_len)) 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to configure WPA IE for " 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "the kernel driver."); 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (hapd->wpa_auth) { 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_deinit(hapd->wpa_auth); 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->wpa_auth = NULL; 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_privacy(hapd, 0); 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_setup_encryption(hapd->conf->iface, hapd); 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_generic_elem(hapd, (u8 *) "", 0); 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_11_set_beacon(hapd); 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_update_wps(hapd); 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ssid.ssid_set && 12161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_set_ssid(hapd, hapd->conf->ssid.ssid, 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->ssid.ssid_len)) { 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver"); 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* try to continue */ 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Reconfigured interface %s", hapd->conf->iface); 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 130444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidtstatic void hostapd_clear_old(struct hostapd_iface *iface) 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t j; 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Deauthenticate all stations since the new configuration may not 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * allow them to use the BSS anymore. 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 13904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_flush_old_stations(iface->bss[j], 14004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt WLAN_REASON_PREV_AUTH_NOT_VALID); 141c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt hostapd_broadcast_wep_clear(iface->bss[j]); 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: update dynamic data based on changed configuration 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * items (e.g., open/close sockets, etc.) */ 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_client_flush(iface->bss[j]->radius, 0); 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 149444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt} 150444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt 151444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt 152444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidtint hostapd_reload_config(struct hostapd_iface *iface) 153444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt{ 154444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt struct hostapd_data *hapd = iface->bss[0]; 155444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt struct hostapd_config *newconf, *oldconf; 156444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt size_t j; 157444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt 158444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt if (iface->config_fname == NULL) { 159444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt /* Only in-memory config in use - assume it has been updated */ 160444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt hostapd_clear_old(iface); 161444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) 162444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt hostapd_reload_bss(iface->bss[j]); 163444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt return 0; 164444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt } 165444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt 166444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt if (iface->interfaces == NULL || 167444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt iface->interfaces->config_read_cb == NULL) 168444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt return -1; 169444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt newconf = iface->interfaces->config_read_cb(iface->config_fname); 170444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt if (newconf == NULL) 171444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt return -1; 172444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt 173444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt hostapd_clear_old(iface); 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt oldconf = hapd->iconf; 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->conf = newconf; 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd = iface->bss[j]; 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iconf = newconf; 181d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt hapd->iconf->channel = oldconf->channel; 182dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt hapd->iconf->acs = oldconf->acs; 183df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt hapd->iconf->secondary_channel = oldconf->secondary_channel; 184d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt hapd->iconf->ieee80211n = oldconf->ieee80211n; 185d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt hapd->iconf->ieee80211ac = oldconf->ieee80211ac; 186d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt hapd->iconf->ht_capab = oldconf->ht_capab; 187d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt hapd->iconf->vht_capab = oldconf->vht_capab; 188d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt hapd->iconf->vht_oper_chwidth = oldconf->vht_oper_chwidth; 189d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt hapd->iconf->vht_oper_centr_freq_seg0_idx = 190d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt oldconf->vht_oper_centr_freq_seg0_idx; 191d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt hapd->iconf->vht_oper_centr_freq_seg1_idx = 192d11f019d62a42a8fc4c4d1f2ec17cf35b0763153Dmitry Shmidt oldconf->vht_oper_centr_freq_seg1_idx; 193cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->conf = newconf->bss[j]; 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_reload_bss(hapd); 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_config_free(oldconf); 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_broadcast_key_clear_iface(struct hostapd_data *hapd, 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *ifname) 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < NUM_WEP_KEYS; i++) { 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE, NULL, i, 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, NULL, 0, NULL, 0)) { 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to clear default " 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "encryption keys (ifname=%s keyidx=%d)", 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ifname, i); 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ieee80211w) { 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = NUM_WEP_KEYS; i < NUM_WEP_KEYS + 2; i++) { 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE, 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, i, 0, NULL, 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, NULL, 0)) { 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to clear " 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "default mgmt encryption keys " 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(ifname=%s keyidx=%d)", ifname, i); 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_broadcast_wep_clear(struct hostapd_data *hapd) 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_broadcast_key_clear_iface(hapd, hapd->conf->iface); 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_broadcast_wep_set(struct hostapd_data *hapd) 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int errors = 0, idx; 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_ssid *ssid = &hapd->conf->ssid; 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idx = ssid->wep.idx; 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->wep.default_len && 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_drv_set_key(hapd->conf->iface, 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd, WPA_ALG_WEP, broadcast_ether_addr, idx, 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1, NULL, 0, ssid->wep.key[idx], 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->wep.len[idx])) { 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "Could not set WEP encryption."); 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt errors++; 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return errors; 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void hostapd_free_hapd_data(struct hostapd_data *hapd) 26004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 2616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_free(hapd->probereq_cb); 2626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hapd->probereq_cb = NULL; 2636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 2646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_P2P 2656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpabuf_free(hapd->p2p_beacon_ie); 2666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hapd->p2p_beacon_ie = NULL; 2676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpabuf_free(hapd->p2p_probe_resp_ie); 2686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hapd->p2p_probe_resp_ie = NULL; 2696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_P2P */ 2706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 271fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt if (!hapd->started) { 272fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Interface %s wasn't started", 273fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt __func__, hapd->conf->iface); 274fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt return; 275fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt } 276fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt hapd->started = 0; 277fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt 2785460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface); 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iapp_deinit(hapd->iapp); 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iapp = NULL; 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt accounting_deinit(hapd); 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_deinit_wpa(hapd); 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt vlan_deinit(hapd); 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_acl_deinit(hapd); 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_client_deinit(hapd->radius); 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->radius = NULL; 28804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt radius_das_deinit(hapd->radius_das); 28904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hapd->radius_das = NULL; 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_deinit_wps(hapd); 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt authsrv_deinit(hapd); 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 296717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (hapd->interface_added) { 297717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hapd->interface_added = 0; 298717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (hostapd_if_remove(hapd, WPA_IF_AP_BSS, hapd->conf->iface)) { 299717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt wpa_printf(MSG_WARNING, 300717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt "Failed to remove BSS interface %s", 301717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hapd->conf->iface); 302717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hapd->interface_added = 1; 303717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt } else { 304717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt /* 305717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt * Since this was a dynamically added interface, the 306717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt * driver wrapper may have removed its internal instance 307717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt * and hapd->drv_priv is not valid anymore. 308717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt */ 309717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hapd->drv_priv = NULL; 310717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt } 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_free(hapd->time_adv); 31404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 31504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_INTERWORKING 31604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt gas_serv_deinit(hapd); 31704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_INTERWORKING */ 318d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 3196c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt bss_load_update_deinit(hapd); 3206c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ndisc_snoop_deinit(hapd); 3216c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt dhcp_snoop_deinit(hapd); 3226c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt x_snoop_deinit(hapd); 3236c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 324d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SQLITE 325c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt bin_clear_free(hapd->tmp_eap_user.identity, 326c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt hapd->tmp_eap_user.identity_len); 327c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt bin_clear_free(hapd->tmp_eap_user.password, 328c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt hapd->tmp_eap_user.password_len); 329d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SQLITE */ 3306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 3316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_MESH 3326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpabuf_free(hapd->mesh_pending_auth); 3336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hapd->mesh_pending_auth = NULL; 3346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_MESH */ 33504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 33604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 33704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 33804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/** 33904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * hostapd_cleanup - Per-BSS cleanup (deinitialization) 34004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @hapd: Pointer to BSS data 34104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * 34204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * This function is used to free all per-BSS data structures and resources. 3435460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt * Most of the modules that are initialized in hostapd_setup_bss() are 3445460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt * deinitialized here. 34504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 34604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void hostapd_cleanup(struct hostapd_data *hapd) 34704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 3485460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(hapd=%p (%s))", __func__, hapd, 3495460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd->conf->iface); 35061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd->iface->interfaces && 35161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd->iface->interfaces->ctrl_iface_deinit) 35261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd->iface->interfaces->ctrl_iface_deinit(hapd); 35304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_free_hapd_data(hapd); 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void hostapd_cleanup_iface_partial(struct hostapd_iface *iface) 35804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 3595460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); 3607f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt#ifdef CONFIG_IEEE80211N 3617f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt#ifdef NEED_AP_MLME 3627f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt hostapd_stop_setup_timers(iface); 3637f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt#endif /* NEED_AP_MLME */ 3647f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt#endif /* CONFIG_IEEE80211N */ 36504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_free_hw_features(iface->hw_features, iface->num_hw_features); 36604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt iface->hw_features = NULL; 36704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(iface->current_rates); 36804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt iface->current_rates = NULL; 36904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(iface->basic_rates); 37004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt iface->basic_rates = NULL; 37104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ap_list_deinit(iface); 37204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 37304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 37404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_cleanup_iface - Complete per-interface cleanup 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @iface: Pointer to interface data 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called after per-BSS data structures are deinitialized 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * with hostapd_cleanup(). 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_cleanup_iface(struct hostapd_iface *iface) 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3845460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); 385cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt eloop_cancel_timeout(channel_list_update_timeout, iface, NULL); 386cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 38704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_cleanup_iface_partial(iface); 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_config_free(iface->conf); 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->conf = NULL; 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(iface->config_fname); 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(iface->bss); 3935460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: free iface=%p", __func__, iface); 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(iface); 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void hostapd_clear_wep(struct hostapd_data *hapd) 39904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 400a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt if (hapd->drv_priv && !hapd->iface->driver_ap_teardown) { 40104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_set_privacy(hapd, 0); 40204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_broadcast_wep_clear(hapd); 40304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 40404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 40504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 40604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd) 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_broadcast_wep_set(hapd); 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ssid.wep.default_len) { 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_privacy(hapd, 1); 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 41975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * When IEEE 802.1X is not enabled, the driver may need to know how to 42075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * set authentication algorithms for static WEP. 42175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 42275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen hostapd_drv_set_authmode(hapd, hapd->conf->auth_algs); 42375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 4; i++) { 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ssid.wep.key[i] && 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_drv_set_key(iface, hapd, WPA_ALG_WEP, NULL, i, 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i == hapd->conf->ssid.wep.idx, NULL, 0, 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->ssid.wep.key[i], 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->ssid.wep.len[i])) { 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "Could not set WEP " 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "encryption."); 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ssid.wep.key[i] && 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i == hapd->conf->ssid.wep.idx) 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_privacy(hapd, 1); 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 44304949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason) 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 addr[ETH_ALEN]; 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_drv_none(hapd) || hapd->drv_priv == NULL) 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 451a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt if (!hapd->iface->driver_ap_teardown) { 452a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt wpa_dbg(hapd->msg_ctx, MSG_DEBUG, 453a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt "Flushing old station entries"); 454a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt 455a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt if (hostapd_flush(hapd)) { 456a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt wpa_msg(hapd->msg_ctx, MSG_WARNING, 457a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt "Could not connect to kernel driver"); 458a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt ret = -1; 459a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt } 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "Deauthenticate all stations"); 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(addr, 0xff, ETH_ALEN); 46304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_drv_sta_deauth(hapd, addr, reason); 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_free_stas(hapd); 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 470717574375e969e8272c6d1a26137286eac158abbDmitry Shmidtstatic void hostapd_bss_deinit_no_free(struct hostapd_data *hapd) 471717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt{ 472717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_free_stas(hapd); 473717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING); 474717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_clear_wep(hapd); 475717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt} 476717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 477717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_validate_bssid_configuration - Validate BSSID configuration 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @iface: Pointer to interface data 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to validate that the configured BSSIDs are valid. 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_validate_bssid_configuration(struct hostapd_iface *iface) 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 mask[ETH_ALEN] = { 0 }; 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = iface->bss[0]; 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int i = iface->conf->num_bss, bits = 0, j; 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int auto_addr = 0; 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_drv_none(hapd)) 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Generate BSSID mask that is large enough to cover the BSSIDs. */ 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Determine the bits necessary to cover the number of BSSIDs. */ 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i--; i; i >>= 1) 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bits++; 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Determine the bits necessary to any configured BSSIDs, 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if they are higher than the number of BSSIDs. */ 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < iface->conf->num_bss; j++) { 504cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hostapd_mac_comp_empty(iface->conf->bss[j]->bssid) == 0) { 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (j) 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auto_addr++; 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < ETH_ALEN; i++) { 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mask[i] |= 512cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->bss[j]->bssid[i] ^ 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->own_addr[i]; 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!auto_addr) 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto skip_mask_ext; 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < ETH_ALEN && mask[i] == 0; i++) 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ; 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt j = 0; 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i < ETH_ALEN) { 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt j = (5 - i) * 8; 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (mask[i] != 0) { 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mask[i] >>= 1; 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt j++; 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bits < j) 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bits = j; 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bits > 40) { 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Too many bits in the BSSID mask (%u)", 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bits); 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(mask, 0xff, ETH_ALEN); 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt j = bits / 8; 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 5; i > 5 - j; i--) 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mask[i] = 0; 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt j = bits % 8; 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (j--) 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mask[i] <<= 1; 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtskip_mask_ext: 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "BSS count %lu, BSSID mask " MACSTR " (%d bits)", 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) iface->conf->num_bss, MAC2STR(mask), bits); 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!auto_addr) 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < ETH_ALEN; i++) { 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((hapd->own_addr[i] & mask[i]) != hapd->own_addr[i]) { 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Invalid BSSID mask " MACSTR 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " for start address " MACSTR ".", 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mask), MAC2STR(hapd->own_addr)); 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Start address must be the " 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "first address in the block (i.e., addr " 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "AND mask == addr)."); 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int mac_in_conf(struct hostapd_config *conf, const void *a) 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < conf->num_bss; i++) { 577cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hostapd_mac_comp(conf->bss[i]->bssid, a) == 0) { 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 58604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifndef CONFIG_NO_RADIUS 58704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 58804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int hostapd_das_nas_mismatch(struct hostapd_data *hapd, 58904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct radius_das_attrs *attr) 59004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 59113ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt if (attr->nas_identifier && 59213ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt (!hapd->conf->nas_identifier || 59313ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt os_strlen(hapd->conf->nas_identifier) != 59413ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt attr->nas_identifier_len || 59513ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt os_memcmp(hapd->conf->nas_identifier, attr->nas_identifier, 59613ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt attr->nas_identifier_len) != 0)) { 59713ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-Identifier mismatch"); 59813ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt return 1; 59913ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt } 60013ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt 60113ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt if (attr->nas_ip_addr && 60213ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt (hapd->conf->own_ip_addr.af != AF_INET || 60313ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt os_memcmp(&hapd->conf->own_ip_addr.u.v4, attr->nas_ip_addr, 4) != 60413ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt 0)) { 60513ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-IP-Address mismatch"); 60613ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt return 1; 60713ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt } 60813ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt 60913ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt#ifdef CONFIG_IPV6 61013ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt if (attr->nas_ipv6_addr && 61113ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt (hapd->conf->own_ip_addr.af != AF_INET6 || 61213ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt os_memcmp(&hapd->conf->own_ip_addr.u.v6, attr->nas_ipv6_addr, 16) 61313ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt != 0)) { 61413ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt wpa_printf(MSG_DEBUG, "RADIUS DAS: NAS-IPv6-Address mismatch"); 61513ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt return 1; 61613ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt } 61713ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt#endif /* CONFIG_IPV6 */ 61813ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt 61904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 62004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 62104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 62204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 62304949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic struct sta_info * hostapd_das_find_sta(struct hostapd_data *hapd, 6242f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt struct radius_das_attrs *attr, 6252f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt int *multi) 62604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 6272f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt struct sta_info *selected, *sta; 62804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt char buf[128]; 6292f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt int num_attr = 0; 6302f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt int count; 63104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 6322f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt *multi = 0; 6332f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 6342f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt for (sta = hapd->sta_list; sta; sta = sta->next) 6352f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt sta->radius_das_match = 1; 6362f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 6372f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (attr->sta_addr) { 6382f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt num_attr++; 63904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sta = ap_get_sta(hapd, attr->sta_addr); 6402f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (!sta) { 6412f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, 6422f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "RADIUS DAS: No Calling-Station-Id match"); 6432f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return NULL; 6442f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 64504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 6462f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt selected = sta; 64704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (sta = hapd->sta_list; sta; sta = sta->next) { 6482f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (sta != selected) 6492f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt sta->radius_das_match = 0; 6502f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 6512f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, "RADIUS DAS: Calling-Station-Id match"); 6522f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 6532f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 6542f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (attr->acct_session_id) { 6552f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt num_attr++; 6562f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (attr->acct_session_id_len != 17) { 6572f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, 6582f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "RADIUS DAS: Acct-Session-Id cannot match"); 6592f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return NULL; 6602f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 6612f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt count = 0; 6622f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 6632f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt for (sta = hapd->sta_list; sta; sta = sta->next) { 6642f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (!sta->radius_das_match) 6652f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt continue; 66604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_snprintf(buf, sizeof(buf), "%08X-%08X", 66704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sta->acct_session_id_hi, 66804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sta->acct_session_id_lo); 6692f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (os_memcmp(attr->acct_session_id, buf, 17) != 0) 6702f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt sta->radius_das_match = 0; 6712f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt else 6722f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt count++; 6732f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 6742f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 6752f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (count == 0) { 6762f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, 6772f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "RADIUS DAS: No matches remaining after Acct-Session-Id check"); 6782f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return NULL; 67904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 6802f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, "RADIUS DAS: Acct-Session-Id match"); 68104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 68204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 6832f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (attr->acct_multi_session_id) { 6842f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt num_attr++; 6852f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (attr->acct_multi_session_id_len != 17) { 6862f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, 6872f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "RADIUS DAS: Acct-Multi-Session-Id cannot match"); 6882f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return NULL; 6892f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 6902f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt count = 0; 6912f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 6922f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt for (sta = hapd->sta_list; sta; sta = sta->next) { 6932f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (!sta->radius_das_match) 6942f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt continue; 6952f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (!sta->eapol_sm || 6962f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt !sta->eapol_sm->acct_multi_session_id_hi) { 6972f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt sta->radius_das_match = 0; 6982f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt continue; 6992f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 7002f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt os_snprintf(buf, sizeof(buf), "%08X+%08X", 7012f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt sta->eapol_sm->acct_multi_session_id_hi, 7022f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt sta->eapol_sm->acct_multi_session_id_lo); 7032f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (os_memcmp(attr->acct_multi_session_id, buf, 17) != 7042f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 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-Multi-Session-Id check"); 7132f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return NULL; 7142f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 7152f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, 7162f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "RADIUS DAS: Acct-Multi-Session-Id match"); 7172f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 7182f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 7192f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (attr->cui) { 7202f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt num_attr++; 7212f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt count = 0; 7222f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 72304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (sta = hapd->sta_list; sta; sta = sta->next) { 72404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpabuf *cui; 7252f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 7262f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (!sta->radius_das_match) 7272f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt continue; 72804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cui = ieee802_1x_get_radius_cui(sta->eapol_sm); 7292f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (!cui || wpabuf_len(cui) != attr->cui_len || 73004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcmp(wpabuf_head(cui), attr->cui, 7312f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt attr->cui_len) != 0) 7322f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt sta->radius_das_match = 0; 7332f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt else 7342f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt count++; 73504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 7362f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 7372f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (count == 0) { 7382f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, 7392f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "RADIUS DAS: No matches remaining after Chargeable-User-Identity check"); 7402f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return NULL; 7412f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 7422f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, 7432f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "RADIUS DAS: Chargeable-User-Identity match"); 74404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 74504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 7462f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (attr->user_name) { 7472f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt num_attr++; 7482f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt count = 0; 7492f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 75004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (sta = hapd->sta_list; sta; sta = sta->next) { 75104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 *identity; 75204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt size_t identity_len; 7532f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 7542f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (!sta->radius_das_match) 7552f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt continue; 75604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt identity = ieee802_1x_get_identity(sta->eapol_sm, 75704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt &identity_len); 7582f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (!identity || 7592f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt identity_len != attr->user_name_len || 76004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcmp(identity, attr->user_name, identity_len) 7612f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt != 0) 7622f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt sta->radius_das_match = 0; 7632f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt else 7642f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt count++; 7652f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 7662f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 7672f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (count == 0) { 7682f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, 7692f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "RADIUS DAS: No matches remaining after User-Name check"); 7702f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return NULL; 7712f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 7722f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, 7732f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "RADIUS DAS: User-Name match"); 7742f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 7752f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 7762f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (num_attr == 0) { 7772f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt /* 7782f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt * In theory, we could match all current associations, but it 7792f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt * seems safer to just reject requests that do not include any 7802f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt * session identification attributes. 7812f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt */ 7822f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, 7832f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "RADIUS DAS: No session identification attributes included"); 7842f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return NULL; 7852f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 7862f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 7872f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt selected = NULL; 7882f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt for (sta = hapd->sta_list; sta; sta = sta->next) { 7892f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (sta->radius_das_match) { 7902f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (selected) { 7912f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt *multi = 1; 7922f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return NULL; 7932f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 7942f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt selected = sta; 79504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 79604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 79704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 7982f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return selected; 7992f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt} 8002f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 8012f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 8022f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidtstatic int hostapd_das_disconnect_pmksa(struct hostapd_data *hapd, 8032f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt struct radius_das_attrs *attr) 8042f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt{ 8052f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (!hapd->wpa_auth) 8062f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return -1; 8072f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return wpa_auth_radius_das_disconnect_pmksa(hapd->wpa_auth, attr); 80804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 80904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 81004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 81104949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic enum radius_das_res 81204949598a23f501be6eec21697465fd46a28840aDmitry Shmidthostapd_das_disconnect(void *ctx, struct radius_das_attrs *attr) 81304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 81404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct hostapd_data *hapd = ctx; 81504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct sta_info *sta; 8162f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt int multi; 81704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 81804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (hostapd_das_nas_mismatch(hapd, attr)) 81904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return RADIUS_DAS_NAS_MISMATCH; 82004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 8212f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt sta = hostapd_das_find_sta(hapd, attr, &multi); 8222f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (sta == NULL) { 8232f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (multi) { 8242f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, 8252f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "RADIUS DAS: Multiple sessions match - not supported"); 8262f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return RADIUS_DAS_MULTI_SESSION_MATCH; 8272f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 8282f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (hostapd_das_disconnect_pmksa(hapd, attr) == 0) { 8292f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, 8302f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "RADIUS DAS: PMKSA cache entry matched"); 8312f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return RADIUS_DAS_SUCCESS; 8322f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 8332f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, "RADIUS DAS: No matching session found"); 83404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return RADIUS_DAS_SESSION_NOT_FOUND; 8352f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 83604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 8372f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_DEBUG, "RADIUS DAS: Found a matching session " MACSTR 8382f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt " - disconnecting", MAC2STR(sta->addr)); 83913ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr); 84013ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt 84104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_drv_sta_deauth(hapd, sta->addr, 84204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt WLAN_REASON_PREV_AUTH_NOT_VALID); 84304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ap_sta_deauthenticate(hapd, sta, WLAN_REASON_PREV_AUTH_NOT_VALID); 84404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 84504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return RADIUS_DAS_SUCCESS; 84604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 84704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 84804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_setup_bss - Per-BSS setup (initialization) 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hapd: Pointer to BSS data 854cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * @first: Whether this BSS is the first BSS of an interface; -1 = not first, 855cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * but interface may exist 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to initialize all per-BSS data structures and 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * resources. This gets called in a loop for each BSS when an interface is 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * initialized. Most of the modules that are initialized here will be 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * deinitialized in hostapd_cleanup(). 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_setup_bss(struct hostapd_data *hapd, int first) 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_bss_config *conf = hapd->conf; 8659d9e60286e05ae45025b672636490bd12586138dDmitry Shmidt u8 ssid[SSID_MAX_LEN + 1]; 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ssid_len, set_ssid; 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char force_ifname[IFNAMSIZ]; 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 if_addr[ETH_ALEN]; 8696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int flush_old_stations = 1; 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8715460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(hapd=%p (%s), first=%d)", 872661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt __func__, hapd, conf->iface, first); 8735460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 87450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt#ifdef EAP_SERVER_TNC 875661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (conf->tnc && tncs_global_init() < 0) { 87650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to initialize TNCS"); 87750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt return -1; 87850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt } 87950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt#endif /* EAP_SERVER_TNC */ 88050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt 8815460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt if (hapd->started) { 8825460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Interface %s was already started", 883661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt __func__, conf->iface); 8845460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt return -1; 8855460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt } 8865460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd->started = 1; 8875460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 888cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!first || first == -1) { 889661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (hostapd_mac_comp_empty(conf->bssid) == 0) { 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Allocate the next available BSSID. */ 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt do { 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt inc_byte_array(hapd->own_addr, ETH_ALEN); 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } while (mac_in_conf(hapd->iconf, hapd->own_addr)); 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Allocate the configured BSSID. */ 896661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt os_memcpy(hapd->own_addr, conf->bssid, ETH_ALEN); 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_mac_comp(hapd->own_addr, 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface->bss[0]->own_addr) == 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "BSS '%s' may not have " 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "BSSID set to the MAC address of " 903661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt "the radio", conf->iface); 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9085460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd->interface_added = 1; 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_if_add(hapd->iface->bss[0], WPA_IF_AP_BSS, 910661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt conf->iface, hapd->own_addr, hapd, 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &hapd->drv_priv, force_ifname, if_addr, 912661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt conf->bridge[0] ? conf->bridge : NULL, 913661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt first == -1)) { 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to add BSS (BSSID=" 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR ")", MAC2STR(hapd->own_addr)); 9163cf6f79011d16f23e60cbf2846aab0fd440511daDmitry Shmidt hapd->interface_added = 0; 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->wmm_enabled < 0) 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->wmm_enabled = hapd->iconf->ieee80211n; 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9246c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_MESH 9256c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (hapd->iface->mconf == NULL) 9266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt flush_old_stations = 0; 9276c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_MESH */ 9286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 9296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (flush_old_stations) 9306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hostapd_flush_old_stations(hapd, 9316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt WLAN_REASON_PREV_AUTH_NOT_VALID); 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_privacy(hapd, 0); 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_broadcast_wep_clear(hapd); 935661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (hostapd_setup_encryption(conf->iface, hapd)) 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Fetch the SSID from the system and use it or, 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * if one was specified in the config file, verify they 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * match. 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid_len = hostapd_get_ssid(hapd, ssid, sizeof(ssid)); 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid_len < 0) { 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not read SSID from system"); 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->ssid.ssid_set) { 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If SSID is specified in the config file and it differs 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * from what is being used then force installation of the 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * new SSID. 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt set_ssid = (conf->ssid.ssid_len != (size_t) ssid_len || 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(conf->ssid.ssid, ssid, ssid_len) != 0); 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * No SSID in the config file; just use the one we got 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * from the system. 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt set_ssid = 0; 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->ssid.ssid_len = ssid_len; 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conf->ssid.ssid, ssid, conf->ssid.ssid_len); 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!hostapd_drv_none(hapd)) { 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Using interface %s with hwaddr " MACSTR 96861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt " and ssid \"%s\"", 969661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt conf->iface, MAC2STR(hapd->own_addr), 970661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt wpa_ssid_txt(conf->ssid.ssid, conf->ssid.ssid_len)); 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_setup_wpa_psk(conf)) { 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "WPA-PSK setup failed."); 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Set SSID for the kernel driver (to be used in beacon and probe 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * response frames) */ 98061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (set_ssid && hostapd_set_ssid(hapd, conf->ssid.ssid, 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->ssid.ssid_len)) { 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver"); 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 986818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (wpa_debug_level <= MSG_MSGDUMP) 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->radius->msg_dumps = 1; 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->radius = radius_client_init(hapd, conf->radius); 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->radius == NULL) { 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "RADIUS client initialization failed."); 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 99404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 995661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (conf->radius_das_port) { 99604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct radius_das_conf das_conf; 99704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memset(&das_conf, 0, sizeof(das_conf)); 998661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt das_conf.port = conf->radius_das_port; 999661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt das_conf.shared_secret = conf->radius_das_shared_secret; 100004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt das_conf.shared_secret_len = 1001661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt conf->radius_das_shared_secret_len; 1002661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt das_conf.client_addr = &conf->radius_das_client_addr; 1003661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt das_conf.time_window = conf->radius_das_time_window; 100404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt das_conf.require_event_timestamp = 1005661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt conf->radius_das_require_event_timestamp; 100604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt das_conf.ctx = hapd; 100704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt das_conf.disconnect = hostapd_das_disconnect; 100804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hapd->radius_das = radius_das_init(&das_conf); 100904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (hapd->radius_das == NULL) { 101004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_ERROR, "RADIUS DAS initialization " 101104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "failed."); 101204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 101304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 101404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_acl_init(hapd)) { 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ACL initialization failed."); 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_init_wps(hapd, conf)) 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (authsrv_init(hapd) < 0) 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ieee802_1x_init(hapd)) { 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "IEEE 802.1X initialization failed."); 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1032661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if ((conf->wpa || conf->osen) && hostapd_setup_wpa(hapd)) 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (accounting_init(hapd)) { 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Accounting initialization failed."); 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1040661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (conf->ieee802_11f && 1041661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt (hapd->iapp = iapp_init(hapd, conf->iapp_iface)) == NULL) { 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "IEEE 802.11F (IAPP) initialization " 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed."); 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 104704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_INTERWORKING 104804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (gas_serv_init(hapd)) { 104904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_ERROR, "GAS server initialization failed"); 105004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 105104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 105204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 1053cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (conf->qos_map_set_len && 1054cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_drv_set_qos_map(hapd, conf->qos_map_set, 1055cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf->qos_map_set_len)) { 1056cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to initialize QoS Map"); 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1059cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#endif /* CONFIG_INTERWORKING */ 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (conf->bss_load_update_period && bss_load_update_init(hapd)) { 10626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_ERROR, "BSS Load initialization failed"); 10636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 10646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 10656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 10666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (conf->proxy_arp) { 10676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (x_snoop_init(hapd)) { 10686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_ERROR, 10696c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "Generic snooping infrastructure initialization failed"); 10706c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 10716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 10726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 10736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (dhcp_snoop_init(hapd)) { 10746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_ERROR, 10756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "DHCP snooping initialization failed"); 10766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 10776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 10786c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 10796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (ndisc_snoop_init(hapd)) { 10806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_ERROR, 10816c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "Neighbor Discovery snooping initialization failed"); 10826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 10836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 10846c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 10856c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!hostapd_drv_none(hapd) && vlan_init(hapd)) { 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "VLAN initialization failed."); 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1091661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (!conf->start_disabled && ieee802_11_set_beacon(hapd) < 0) 1092fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return -1; 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (hapd->wpa_auth && wpa_init_keys(hapd->wpa_auth) < 0) 10951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 10961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->driver && hapd->driver->set_operstate) 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->driver->set_operstate(hapd->drv_priv, 1); 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_tx_queue_params(struct hostapd_iface *iface) 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = iface->bss[0]; 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_tx_queue_params *p; 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11106c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_MESH 11116c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (iface->mconf == NULL) 11126c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return; 11136c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_MESH */ 11146c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < NUM_TX_QUEUES; i++) { 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = &iface->conf->tx_queue[i]; 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_set_tx_queue_params(hapd, i, p->aifs, p->cwmin, 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p->cwmax, p->burst)) { 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to set TX queue " 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "parameters for queue %d.", i); 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Continue anyway */ 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11288bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidtstatic int hostapd_set_acl_list(struct hostapd_data *hapd, 11298bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt struct mac_acl_entry *mac_acl, 11308bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt int n_entries, u8 accept_acl) 11318bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt{ 11328bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt struct hostapd_acl_params *acl_params; 11338bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt int i, err; 11348bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 11358bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt acl_params = os_zalloc(sizeof(*acl_params) + 11368bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt (n_entries * sizeof(acl_params->mac_acl[0]))); 11378bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt if (!acl_params) 11388bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt return -ENOMEM; 11398bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 11408bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt for (i = 0; i < n_entries; i++) 11418bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt os_memcpy(acl_params->mac_acl[i].addr, mac_acl[i].addr, 11428bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt ETH_ALEN); 11438bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 11448bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt acl_params->acl_policy = accept_acl; 11458bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt acl_params->num_mac_acl = n_entries; 11468bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 11478bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt err = hostapd_drv_set_acl(hapd, acl_params); 11488bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 11498bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt os_free(acl_params); 11508bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 11518bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt return err; 11528bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt} 11538bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 11548bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 11558bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidtstatic void hostapd_set_acl(struct hostapd_data *hapd) 11568bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt{ 11578bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt struct hostapd_config *conf = hapd->iconf; 11588bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt int err; 11598bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt u8 accept_acl; 11608bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 11618bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt if (hapd->iface->drv_max_acl_mac_addrs == 0) 11628bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt return; 11638bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 1164cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (conf->bss[0]->macaddr_acl == DENY_UNLESS_ACCEPTED) { 116543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt accept_acl = 1; 116643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt err = hostapd_set_acl_list(hapd, conf->bss[0]->accept_mac, 116743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt conf->bss[0]->num_accept_mac, 116843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt accept_acl); 116943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (err) { 117043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to set accept acl"); 117143cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt return; 11728bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } 1173cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } else if (conf->bss[0]->macaddr_acl == ACCEPT_UNLESS_DENIED) { 117443cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt accept_acl = 0; 117543cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt err = hostapd_set_acl_list(hapd, conf->bss[0]->deny_mac, 117643cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt conf->bss[0]->num_deny_mac, 117743cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt accept_acl); 117843cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt if (err) { 117943cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to set deny acl"); 118043cb578dfe2c492257636f6234a24178ed27789eDmitry Shmidt return; 11818bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } 11828bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } 11838bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt} 11848bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 11858bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 1186cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic int start_ctrl_iface_bss(struct hostapd_data *hapd) 1187cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 1188cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!hapd->iface->interfaces || 1189cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt !hapd->iface->interfaces->ctrl_iface_init) 1190cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 1191cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1192cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd->iface->interfaces->ctrl_iface_init(hapd)) { 1193cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, 1194cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "Failed to setup control interface for %s", 1195cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->conf->iface); 1196cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 1197cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1198cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1199cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 1200cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 1201cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1202cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1203cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic int start_ctrl_iface(struct hostapd_iface *iface) 1204cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 1205cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i; 1206cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1207cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!iface->interfaces || !iface->interfaces->ctrl_iface_init) 1208cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 1209cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1210cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (i = 0; i < iface->num_bss; i++) { 1211cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_data *hapd = iface->bss[i]; 1212cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (iface->interfaces->ctrl_iface_init(hapd)) { 1213cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, 1214cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "Failed to setup control interface for %s", 1215cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->conf->iface); 1216cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 1217cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1218cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1219cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1220cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 1221cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 1222cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1223cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1224cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic void channel_list_update_timeout(void *eloop_ctx, void *timeout_ctx) 1225cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 1226cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface *iface = eloop_ctx; 1227cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1228cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!iface->wait_channel_update) { 1229cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "Channel list update timeout, but interface was not waiting for it"); 1230cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return; 1231cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1232cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1233cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* 1234cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * It is possible that the existing channel list is acceptable, so try 1235cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * to proceed. 1236cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 1237cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_DEBUG, "Channel list update timeout - try to continue anyway"); 1238cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt setup_interface2(iface); 1239cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 1240cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1241cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1242e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtvoid hostapd_channel_list_updated(struct hostapd_iface *iface, int initiator) 1243cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 1244e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!iface->wait_channel_update || initiator != REGDOM_SET_BY_USER) 1245cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return; 1246cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1247cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_DEBUG, "Channel list updated - continue setup"); 1248cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt eloop_cancel_timeout(channel_list_update_timeout, iface, NULL); 1249cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt setup_interface2(iface); 1250cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 1251cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1252cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int setup_interface(struct hostapd_iface *iface) 12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = iface->bss[0]; 12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 1257cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1258a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt /* 1259a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt * It is possible that setup_interface() is called after the interface 1260a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt * was disabled etc., in which case driver_ap_teardown is possibly set 1261a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt * to 1. Clear it here so any other key/station deletion, which is not 1262a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt * part of a teardown flow, would also call the relevant driver 1263a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt * callbacks. 1264a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt */ 1265a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt iface->driver_ap_teardown = 0; 1266a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt 1267cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!iface->phy[0]) { 1268cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt const char *phy = hostapd_drv_get_radio_name(hapd); 1269cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (phy) { 1270cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_DEBUG, "phy: %s", phy); 1271cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_strlcpy(iface->phy, phy, sizeof(iface->phy)); 1272cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1273cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Make sure that all BSSes get configured with a pointer to the same 12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * driver interface. 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 1; i < iface->num_bss; i++) { 12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->bss[i]->driver = hapd->driver; 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->bss[i]->drv_priv = hapd->drv_priv; 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_validate_bssid_configuration(iface)) 12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1287cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* 1288cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * Initialize control interfaces early to allow external monitoring of 1289cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * channel setup operations that may take considerable amount of time 1290cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * especially for DFS cases. 1291cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 1292cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (start_ctrl_iface(iface)) 1293cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 1294cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iconf->country[0] && hapd->iconf->country[1]) { 1296cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt char country[4], previous_country[4]; 1297cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1298cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_set_state(iface, HAPD_IFACE_COUNTRY_UPDATE); 1299cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hostapd_get_country(hapd, previous_country) < 0) 1300cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt previous_country[0] = '\0'; 1301cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(country, hapd->iconf->country, 3); 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt country[3] = '\0'; 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_set_country(hapd, country) < 0) { 13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to set country code"); 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1308cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1309cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_DEBUG, "Previous country code %s, new country code %s", 1310cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt previous_country, country); 1311cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1312cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (os_strncmp(previous_country, country, 2) != 0) { 1313cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_DEBUG, "Continue interface setup after channel list update"); 1314cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->wait_channel_update = 1; 13159767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt eloop_register_timeout(5, 0, 1316cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt channel_list_update_timeout, 1317cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface, NULL); 1318cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 1319cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1322cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return setup_interface2(iface); 1323cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 1324cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1325cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1326cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic int setup_interface2(struct hostapd_iface *iface) 1327cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 1328cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->wait_channel_update = 0; 1329cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_get_hw_features(iface)) { 13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Not all drivers support this yet, so continue without hw 13328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * feature data. */ 13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 13348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = hostapd_select_hw_mode(iface); 13358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) { 13368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not select hw_mode and " 13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel. (%d)", ret); 1338b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1340391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (ret == 1) { 1341391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_DEBUG, "Interface initialization will be completed in a callback (ACS)"); 1342391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return 0; 1343391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = hostapd_check_ht_capab(iface); 13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) 1346b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 13478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret == 1) { 13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Interface initialization will " 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "be completed in a callback"); 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1352051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1353051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (iface->conf->ieee80211h) 1354051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_printf(MSG_DEBUG, "DFS support is enabled"); 13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return hostapd_setup_interface_complete(iface, 0); 1357b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt 1358b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidtfail: 1359b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt hostapd_set_state(iface, HAPD_IFACE_DISABLED); 1360b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_DISABLED); 1361b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (iface->interfaces && iface->interfaces->terminate_on_error) 1362b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt eloop_terminate(); 1363b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt return -1; 13648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1367cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt/** 1368cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_setup_interface_complete - Complete interface setup 1369cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * 1370cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * This function is called when previous steps in the interface setup has been 1371cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * completed. This can also start operations, e.g., DFS, that will require 1372cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * additional processing before interface is ready to be enabled. Such 1373cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * operations will call this function from eloop callbacks when finished. 1374cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_setup_interface_complete(struct hostapd_iface *iface, int err) 13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = iface->bss[0]; 13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t j; 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *prev_addr; 13806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt int delay_apply_cfg = 0; 1381203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt int res_dfs_offload = 0; 13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1383b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (err) 1384b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Completing interface initialization"); 1387cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (iface->conf->channel) { 1388051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#ifdef NEED_AP_MLME 1389051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt int res; 1390051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#endif /* NEED_AP_MLME */ 1391051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1392cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->freq = hostapd_hw_get_freq(hapd, iface->conf->channel); 13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Mode: %s Channel: %d " 13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Frequency: %d MHz", 1395cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_hw_mode_txt(iface->conf->hw_mode), 1396cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->channel, iface->freq); 13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1398051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#ifdef NEED_AP_MLME 1399661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt /* Handle DFS only if it is not offloaded to the driver */ 1400661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (!(iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)) { 1401661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt /* Check DFS */ 1402661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt res = hostapd_handle_dfs(iface); 1403661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (res <= 0) { 1404661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt if (res < 0) 1405661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt goto fail; 1406661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt return res; 1407661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt } 1408203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt } else { 1409203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt /* If DFS is offloaded to the driver */ 1410203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt res_dfs_offload = hostapd_handle_dfs_offload(iface); 1411203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt if (res_dfs_offload <= 0) { 1412203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt if (res_dfs_offload < 0) 1413203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt goto fail; 1414203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt } else { 1415203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt wpa_printf(MSG_DEBUG, 1416203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt "Proceed with AP/channel setup"); 1417203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt /* 1418203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt * If this is a DFS channel, move to completing 1419203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt * AP setup. 1420203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt */ 1421203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt if (res_dfs_offload == 1) 1422203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt goto dfs_offload; 1423203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt /* Otherwise fall through. */ 1424203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt } 1425b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt } 1426051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#endif /* NEED_AP_MLME */ 1427051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 14286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#ifdef CONFIG_MESH 14296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (iface->mconf != NULL) { 14306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_DEBUG, 14316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt "%s: Mesh configuration will be applied while joining the mesh network", 14326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt iface->bss[0]->conf->iface); 14336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt delay_apply_cfg = 1; 14346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 14356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif /* CONFIG_MESH */ 14366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 14376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!delay_apply_cfg && 14386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hostapd_set_freq(hapd, hapd->iconf->hw_mode, iface->freq, 14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iconf->channel, 14408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iconf->ieee80211n, 1441a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hapd->iconf->ieee80211ac, 1442a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hapd->iconf->secondary_channel, 1443a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hapd->iconf->vht_oper_chwidth, 1444a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hapd->iconf->vht_oper_centr_freq_seg0_idx, 1445a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hapd->iconf->vht_oper_centr_freq_seg1_idx)) { 14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not set channel for " 14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "kernel driver"); 1448b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface->current_mode) { 14531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (hostapd_prepare_rates(iface, iface->current_mode)) { 14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to prepare rates " 14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "table."); 14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, 14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_WARNING, 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to prepare rates table."); 1459b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iconf->rts_threshold > -1 && 14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_rts(hapd, hapd->iconf->rts_threshold)) { 14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not set RTS threshold for " 14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "kernel driver"); 1467b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iconf->fragm_threshold > -1 && 14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_frag(hapd, hapd->iconf->fragm_threshold)) { 14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not set fragmentation threshold " 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for kernel driver"); 1474b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev_addr = hapd->own_addr; 14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd = iface->bss[j]; 14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (j) 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN); 1483717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (hostapd_setup_bss(hapd, j == 0)) { 1484717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt do { 1485717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hapd = iface->bss[j]; 1486717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_bss_deinit_no_free(hapd); 1487717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_free_hapd_data(hapd); 1488717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt } while (j-- > 0); 1489b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 1490717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt } 14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0) 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev_addr = hapd->own_addr; 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1494cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd = iface->bss[0]; 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_tx_queue_params(iface); 14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_list_init(iface); 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15008bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt hostapd_set_acl(hapd); 15018bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_driver_commit(hapd) < 0) { 15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Failed to commit driver " 15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "configuration", __func__); 1505b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 150887fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen /* 150987fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen * WPS UPnP module can be initialized only when the "upnp_iface" is up. 151087fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen * If "interface" and "upnp_iface" are the same (e.g., non-bridge 151187fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen * mode), the interface is up only after driver_commit, so initialize 151287fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen * WPS after driver_commit. 151387fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen */ 151487fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen for (j = 0; j < iface->num_bss; j++) { 151587fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen if (hostapd_init_wps_complete(iface->bss[j])) 1516b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt goto fail; 151787fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen } 151887fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen 1519203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt if ((iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) && 1520203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt !res_dfs_offload) { 1521203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt /* 1522203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt * If freq is DFS, and DFS is offloaded to the driver, then wait 1523203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt * for CAC to complete. 1524203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt */ 1525203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: Wait for CAC to complete", __func__); 1526203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt return res_dfs_offload; 1527203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt } 1528203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt 1529203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt#ifdef NEED_AP_MLME 1530203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidtdfs_offload: 1531203eadb9eda41a1dde4a583edb4684319e3f399eDmitry Shmidt#endif /* NEED_AP_MLME */ 1532cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_set_state(iface, HAPD_IFACE_ENABLED); 1533cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_ENABLED); 15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->setup_complete_cb) 15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->setup_complete_cb(hapd->setup_complete_cb_ctx); 15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: Setup of interface done.", 15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->bss[0]->conf->iface); 1539b96dad47218788efffa3db0fe7f1b54a7d19e366Dmitry Shmidt if (iface->interfaces && iface->interfaces->terminate_on_error > 0) 1540b96dad47218788efffa3db0fe7f1b54a7d19e366Dmitry Shmidt iface->interfaces->terminate_on_error--; 15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1543b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt 1544b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidtfail: 1545b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt wpa_printf(MSG_ERROR, "Interface initialization failed"); 1546b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt hostapd_set_state(iface, HAPD_IFACE_DISABLED); 1547b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED); 1548b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt if (iface->interfaces && iface->interfaces->terminate_on_error) 1549b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt eloop_terminate(); 1550b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt return -1; 15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_setup_interface - Setup of an interface 15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @iface: Pointer to interface data. 15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Initializes the driver interface, validates the configuration, 15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * and sets driver parameters based on the configuration. 15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Flushes old stations, sets the channel, encryption, 15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * beacons, and WDS links based on the configuration. 1563cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * 1564cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * If interface setup requires more time, e.g., to perform HT co-ex scans, ACS, 1565cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * or DFS operations, this function returns 0 before such operations have been 1566cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * completed. The pending operations are registered into eloop and will be 1567cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * completed from eloop callbacks. Those callbacks end up calling 1568cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_setup_interface_complete() once setup has been completed. 15698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 15708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_setup_interface(struct hostapd_iface *iface) 15718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = setup_interface(iface); 15758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) { 15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Unable to setup interface.", 15778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->bss[0]->conf->iface); 15788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 15828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 15868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_alloc_bss_data - Allocate and initialize per-BSS data 15878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hapd_iface: Pointer to interface data 15888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conf: Pointer to per-interface configuration 15898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @bss: Pointer to per-BSS configuration for this BSS 15908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to allocated BSS data 15918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 15928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to allocate per-BSS data structure. This data will be 15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * freed after hostapd_cleanup() is called for it during interface 15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * deinitialization. 15958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 15968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct hostapd_data * 15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidthostapd_alloc_bss_data(struct hostapd_iface *hapd_iface, 15988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_config *conf, 15998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_bss_config *bss) 16008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd; 16028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd = os_zalloc(sizeof(*hapd)); 16048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd == NULL) 16058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 16068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->new_assoc_sta_cb = hostapd_new_assoc_sta; 16088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iconf = conf; 16098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf = bss; 16108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface = hapd_iface; 16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->driver = hapd->iconf->driver; 161204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hapd->ctrl_sock = -1; 16138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return hapd; 16158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16185460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidtstatic void hostapd_bss_deinit(struct hostapd_data *hapd) 16195460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt{ 16205460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: deinit bss %s", __func__, 16215460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd->conf->iface); 1622717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_bss_deinit_no_free(hapd); 1623f73259cc00af557e36add405799b7f2326587c13Dmitry Shmidt wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED); 16245460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_cleanup(hapd); 16255460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt} 16265460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 16275460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid hostapd_interface_deinit(struct hostapd_iface *iface) 16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1630cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt int j; 16318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16325460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); 16338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface == NULL) 16348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1636f73259cc00af557e36add405799b7f2326587c13Dmitry Shmidt hostapd_set_state(iface, HAPD_IFACE_DISABLED); 1637f73259cc00af557e36add405799b7f2326587c13Dmitry Shmidt 16387832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt#ifdef CONFIG_IEEE80211N 16397832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt#ifdef NEED_AP_MLME 16407832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt hostapd_stop_setup_timers(iface); 16417832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt eloop_cancel_timeout(ap_ht2040_timeout, iface, NULL); 16427832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt#endif /* NEED_AP_MLME */ 16437832adbbd72a1b784b7fb74a71a5d4085b0cb0d3Dmitry Shmidt#endif /* CONFIG_IEEE80211N */ 1644cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt eloop_cancel_timeout(channel_list_update_timeout, iface, NULL); 1645cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->wait_channel_update = 0; 1646cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 16475460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt for (j = iface->num_bss - 1; j >= 0; j--) 16485460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_bss_deinit(iface->bss[j]); 16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid hostapd_interface_free(struct hostapd_iface *iface) 16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t j; 16555460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); 16565460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 16575460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: free hapd %p", 16585460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, iface->bss[j]); 16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(iface->bss[j]); 16605460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt } 16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_cleanup_iface(iface); 16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1665cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt/** 1666cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_init - Allocate and initialize per-interface data 1667cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * @config_file: Path to the configuration file 1668cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * Returns: Pointer to the allocated interface data or %NULL on failure 1669cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * 1670cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * This function is used to allocate main data structures for per-interface 1671cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * data. The allocated data buffer will be freed by calling 1672cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_cleanup_iface(). 1673cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 1674cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstruct hostapd_iface * hostapd_init(struct hapd_interfaces *interfaces, 1675cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt const char *config_file) 1676cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 1677cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface *hapd_iface = NULL; 1678cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_config *conf = NULL; 1679cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_data *hapd; 1680cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i; 1681cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1682cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface = os_zalloc(sizeof(*hapd_iface)); 1683cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd_iface == NULL) 1684cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto fail; 1685cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1686cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->config_fname = os_strdup(config_file); 1687cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd_iface->config_fname == NULL) 1688cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto fail; 1689cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1690cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf = interfaces->config_read_cb(hapd_iface->config_fname); 1691cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (conf == NULL) 1692cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto fail; 1693cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->conf = conf; 1694cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1695cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->num_bss = conf->num_bss; 1696cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->bss = os_calloc(conf->num_bss, 1697cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt sizeof(struct hostapd_data *)); 1698cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd_iface->bss == NULL) 1699cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto fail; 1700cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1701cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (i = 0; i < conf->num_bss; i++) { 1702cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd = hapd_iface->bss[i] = 1703cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_alloc_bss_data(hapd_iface, conf, 1704cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf->bss[i]); 1705cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd == NULL) 1706cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto fail; 1707cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->msg_ctx = hapd; 1708cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1709cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1710cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return hapd_iface; 1711cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1712cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtfail: 1713cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to set up interface with %s", 1714cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt config_file); 1715cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (conf) 1716cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_config_free(conf); 1717cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd_iface) { 1718cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_free(hapd_iface->config_fname); 1719cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_free(hapd_iface->bss); 17205460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: free iface %p", 17215460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, hapd_iface); 1722cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_free(hapd_iface); 1723cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1724cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1725cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 1726cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1727cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1728cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic int ifname_in_use(struct hapd_interfaces *interfaces, const char *ifname) 1729cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 1730cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i, j; 1731cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1732cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (i = 0; i < interfaces->count; i++) { 1733cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface *iface = interfaces->iface[i]; 1734cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 1735cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_data *hapd = iface->bss[j]; 1736cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (os_strcmp(ifname, hapd->conf->iface) == 0) 1737cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 1; 1738cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1739cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1740cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1741cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 1742cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 1743cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1744cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1745cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt/** 1746cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_interface_init_bss - Read configuration file and init BSS data 1747cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * 1748cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * This function is used to parse configuration file for a BSS. This BSS is 1749cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * added to an existing interface sharing the same radio (if any) or a new 1750cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * interface is created if this is the first interface on a radio. This 1751cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * allocate memory for the BSS. No actual driver operations are started. 1752cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * 1753cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * This is similar to hostapd_interface_init(), but for a case where the 1754cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * configuration is used to add a single BSS instead of all BSSes for a radio. 1755cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 1756cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstruct hostapd_iface * 1757cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidthostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy, 1758cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt const char *config_fname, int debug) 1759cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 1760cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface *new_iface = NULL, *iface = NULL; 1761cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_data *hapd; 1762cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt int k; 1763cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i, bss_idx; 1764cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1765cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!phy || !*phy) 1766cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1767cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1768cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (i = 0; i < interfaces->count; i++) { 1769cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (os_strcmp(interfaces->iface[i]->phy, phy) == 0) { 1770cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface = interfaces->iface[i]; 1771cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt break; 1772cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1773cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1774cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1775cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "Configuration file: %s (phy %s)%s", 1776cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt config_fname, phy, iface ? "" : " --> new PHY"); 1777cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (iface) { 1778cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_config *conf; 1779cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_bss_config **tmp_conf; 1780cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_data **tmp_bss; 1781cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_bss_config *bss; 1782cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt const char *ifname; 1783cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1784cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* Add new BSS to existing iface */ 1785cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf = interfaces->config_read_cb(config_fname); 1786cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (conf == NULL) 1787cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1788cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (conf->num_bss > 1) { 1789cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "Multiple BSSes specified in BSS-config"); 1790cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_config_free(conf); 1791cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1792cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1793cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1794cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt ifname = conf->bss[0]->iface; 1795cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (ifname[0] != '\0' && ifname_in_use(interfaces, ifname)) { 1796cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, 1797cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "Interface name %s already in use", ifname); 1798cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_config_free(conf); 1799cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1800cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1801cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1802cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt tmp_conf = os_realloc_array( 1803cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->bss, iface->conf->num_bss + 1, 1804cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt sizeof(struct hostapd_bss_config *)); 1805cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt tmp_bss = os_realloc_array(iface->bss, iface->num_bss + 1, 1806cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt sizeof(struct hostapd_data *)); 1807cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (tmp_bss) 1808cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->bss = tmp_bss; 1809cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (tmp_conf) { 1810cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->bss = tmp_conf; 1811cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->last_bss = tmp_conf[0]; 1812cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1813cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (tmp_bss == NULL || tmp_conf == NULL) { 1814cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_config_free(conf); 1815cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1816cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1817cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt bss = iface->conf->bss[iface->conf->num_bss] = conf->bss[0]; 1818cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->num_bss++; 1819cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1820cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd = hostapd_alloc_bss_data(iface, iface->conf, bss); 1821cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd == NULL) { 1822cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->num_bss--; 1823cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_config_free(conf); 1824cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1825cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1826cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->last_bss = bss; 1827cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->bss[iface->num_bss] = hapd; 1828cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->msg_ctx = hapd; 1829cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1830cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt bss_idx = iface->num_bss++; 1831cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf->num_bss--; 1832cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf->bss[0] = NULL; 1833cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_config_free(conf); 1834cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } else { 1835cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* Add a new iface with the first BSS */ 1836cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt new_iface = iface = hostapd_init(interfaces, config_fname); 1837cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!iface) 1838cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1839cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_strlcpy(iface->phy, phy, sizeof(iface->phy)); 1840cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->interfaces = interfaces; 1841cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt bss_idx = 0; 1842cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1843cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1844cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (k = 0; k < debug; k++) { 1845cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (iface->bss[bss_idx]->conf->logger_stdout_level > 0) 1846cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->bss[bss_idx]->conf->logger_stdout_level--; 1847cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1848cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1849cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (iface->conf->bss[bss_idx]->iface[0] == '\0' && 1850cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt !hostapd_drv_none(iface->bss[bss_idx])) { 1851cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "Interface name not specified in %s", 1852cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt config_fname); 1853cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (new_iface) 1854cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_interface_deinit_free(new_iface); 1855cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1856cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1857cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1858cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return iface; 1859cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 1860cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 186161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 186261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid hostapd_interface_deinit_free(struct hostapd_iface *iface) 186361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 186461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const struct wpa_driver_ops *driver; 186561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt void *drv_priv; 18665460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 18675460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); 186861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (iface == NULL) 186961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 18705460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: num_bss=%u conf->num_bss=%u", 18715460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, (unsigned int) iface->num_bss, 18725460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt (unsigned int) iface->conf->num_bss); 187361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt driver = iface->bss[0]->driver; 187461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt drv_priv = iface->bss[0]->drv_priv; 187561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_interface_deinit(iface); 18765460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", 18775460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, driver, drv_priv); 1878717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (driver && driver->hapd_deinit && drv_priv) { 187961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt driver->hapd_deinit(drv_priv); 1880717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt iface->bss[0]->drv_priv = NULL; 1881717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt } 188261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_interface_free(iface); 188361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 188461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 188561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 188615907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidtstatic void hostapd_deinit_driver(const struct wpa_driver_ops *driver, 188715907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt void *drv_priv, 188815907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt struct hostapd_iface *hapd_iface) 188915907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt{ 189015907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt size_t j; 189115907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt 189215907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", 189315907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt __func__, driver, drv_priv); 189415907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt if (driver && driver->hapd_deinit && drv_priv) { 189515907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt driver->hapd_deinit(drv_priv); 189615907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt for (j = 0; j < hapd_iface->num_bss; j++) { 189715907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s:bss[%d]->drv_priv=%p", 189815907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt __func__, (int) j, 189915907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt hapd_iface->bss[j]->drv_priv); 190015907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt if (hapd_iface->bss[j]->drv_priv == drv_priv) 190115907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt hapd_iface->bss[j]->drv_priv = NULL; 190215907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt } 190315907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt } 190415907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt} 190515907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt 190615907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt 190761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint hostapd_enable_iface(struct hostapd_iface *hapd_iface) 190861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 1909717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt size_t j; 1910717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 191161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface->bss[0]->drv_priv != NULL) { 191261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "Interface %s already enabled", 1913cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->conf->bss[0]->iface); 191461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 191561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 191661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 191761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "Enable interface %s", 1918cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->conf->bss[0]->iface); 191961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1920717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt for (j = 0; j < hapd_iface->num_bss; j++) 1921717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_set_security_params(hapd_iface->conf->bss[j], 1); 1922344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt if (hostapd_config_check(hapd_iface->conf, 1) < 0) { 1923344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt wpa_printf(MSG_INFO, "Invalid configuration - cannot enable"); 1924344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt return -1; 1925344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt } 1926344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt 192761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface->interfaces == NULL || 192861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface->interfaces->driver_init == NULL || 1929cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->interfaces->driver_init(hapd_iface)) 1930cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 1931cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1932cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hostapd_setup_interface(hapd_iface)) { 193315907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt hostapd_deinit_driver(hapd_iface->bss[0]->driver, 193415907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt hapd_iface->bss[0]->drv_priv, 193515907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt hapd_iface); 193661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 193761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 1938cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 193961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 194061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 194161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 194261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 194361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint hostapd_reload_iface(struct hostapd_iface *hapd_iface) 194461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 194561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t j; 194661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 194761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "Reload interface %s", 1948cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->conf->bss[0]->iface); 1949cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (j = 0; j < hapd_iface->num_bss; j++) 1950717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_set_security_params(hapd_iface->conf->bss[j], 1); 1951344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt if (hostapd_config_check(hapd_iface->conf, 1) < 0) { 1952cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "Updated configuration is invalid"); 1953cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 195461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 1955cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_clear_old(hapd_iface); 1956cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (j = 0; j < hapd_iface->num_bss; j++) 1957cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_reload_bss(hapd_iface->bss[j]); 1958cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 195961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 196061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 196161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 196261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 196361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint hostapd_disable_iface(struct hostapd_iface *hapd_iface) 196461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 196561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t j; 196661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const struct wpa_driver_ops *driver; 196761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt void *drv_priv; 196861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 196961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface == NULL) 197061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 1971717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 1972717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt if (hapd_iface->bss[0]->drv_priv == NULL) { 1973717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt wpa_printf(MSG_INFO, "Interface %s already disabled", 1974717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hapd_iface->conf->bss[0]->iface); 1975717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt return -1; 1976717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt } 1977717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt 1978cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_msg(hapd_iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_DISABLED); 197961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt driver = hapd_iface->bss[0]->driver; 198061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt drv_priv = hapd_iface->bss[0]->drv_priv; 198161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1982a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt hapd_iface->driver_ap_teardown = 1983a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt !!(hapd_iface->drv_flags & 1984a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT); 1985a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt 1986a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt /* same as hostapd_interface_deinit without deinitializing ctrl-iface */ 198761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (j = 0; j < hapd_iface->num_bss; j++) { 198861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_data *hapd = hapd_iface->bss[j]; 1989717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt hostapd_bss_deinit_no_free(hapd); 199061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_free_hapd_data(hapd); 199161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 199261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 199315907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt hostapd_deinit_driver(driver, drv_priv, hapd_iface); 199461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 199561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* From hostapd_cleanup_iface: These were initialized in 199661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * hostapd_setup_interface and hostapd_setup_interface_complete 199761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 199861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_cleanup_iface_partial(hapd_iface); 199961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 20005605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_printf(MSG_DEBUG, "Interface %s disabled", 20015605286c30e1701491bd3af974ae423727750eddDmitry Shmidt hapd_iface->bss[0]->conf->iface); 2002cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_set_state(hapd_iface, HAPD_IFACE_DISABLED); 200361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 200461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 200561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 200661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 200761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic struct hostapd_iface * 200861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidthostapd_iface_alloc(struct hapd_interfaces *interfaces) 200961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 201061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_iface **iface, *hapd_iface; 201161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 201261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt iface = os_realloc_array(interfaces->iface, interfaces->count + 1, 201361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sizeof(struct hostapd_iface *)); 201461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (iface == NULL) 201561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 201661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->iface = iface; 201761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface = interfaces->iface[interfaces->count] = 201861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_zalloc(sizeof(*hapd_iface)); 201961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface == NULL) { 202061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Failed to allocate memory for " 202161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "the interface", __func__); 202261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 202361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 202461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->count++; 202561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface->interfaces = interfaces; 202661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 202761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return hapd_iface; 202861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 202961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 203061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 203161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic struct hostapd_config * 203261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidthostapd_config_alloc(struct hapd_interfaces *interfaces, const char *ifname, 203361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const char *ctrl_iface) 203461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 203561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_bss_config *bss; 203661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_config *conf; 203761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 203861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Allocates memory for bss and conf */ 203961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt conf = hostapd_config_defaults(); 204061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (conf == NULL) { 204161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Failed to allocate memory for " 204261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "configuration", __func__); 204361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 204461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 204561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 204661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt conf->driver = wpa_drivers[0]; 204761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (conf->driver == NULL) { 204861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "No driver wrappers registered!"); 204961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_config_free(conf); 205061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 205161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 205261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2053cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt bss = conf->last_bss = conf->bss[0]; 205461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 205561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_strlcpy(bss->iface, ifname, sizeof(bss->iface)); 205661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt bss->ctrl_interface = os_strdup(ctrl_iface); 205761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (bss->ctrl_interface == NULL) { 205861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_config_free(conf); 205961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 206061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 206161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 206261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Reading configuration file skipped, will be done in SET! 206361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * From reading the configuration till the end has to be done in 206461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * SET 206561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 206661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return conf; 206761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 206861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 206961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2070ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidtstatic int hostapd_data_alloc(struct hostapd_iface *hapd_iface, 2071ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt struct hostapd_config *conf) 207261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 207361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t i; 207461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_data *hapd; 207561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 20766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hapd_iface->bss = os_calloc(conf->num_bss, 207761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sizeof(struct hostapd_data *)); 207861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface->bss == NULL) 2079ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return -1; 208061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 208161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (i = 0; i < conf->num_bss; i++) { 208261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd = hapd_iface->bss[i] = 2083cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_alloc_bss_data(hapd_iface, conf, conf->bss[i]); 2084ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (hapd == NULL) { 2085ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt while (i > 0) { 2086ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt i--; 2087ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt os_free(hapd_iface->bss[i]); 2088ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt hapd_iface->bss[i] = NULL; 2089ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 2090ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt os_free(hapd_iface->bss); 2091ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt hapd_iface->bss = NULL; 2092ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return -1; 2093ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 209461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd->msg_ctx = hapd; 209561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 209661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2097ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt hapd_iface->conf = conf; 2098ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt hapd_iface->num_bss = conf->num_bss; 209961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2100ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return 0; 210161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 210261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 210361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 210461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint hostapd_add_iface(struct hapd_interfaces *interfaces, char *buf) 210561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 210661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_config *conf = NULL; 2107cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface *hapd_iface = NULL, *new_iface = NULL; 2108cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_data *hapd; 210961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char *ptr; 2110cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i, j; 2111cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt const char *conf_file = NULL, *phy_name = NULL; 2112cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2113cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (os_strncmp(buf, "bss_config=", 11) == 0) { 2114cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt char *pos; 2115cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt phy_name = buf + 11; 2116cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt pos = os_strchr(phy_name, ':'); 2117cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!pos) 2118cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 2119cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt *pos++ = '\0'; 2120cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf_file = pos; 2121cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!os_strlen(conf_file)) 2122cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 2123cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2124cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface = hostapd_interface_init_bss(interfaces, phy_name, 2125cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf_file, 0); 2126cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!hapd_iface) 2127cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 2128cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (j = 0; j < interfaces->count; j++) { 2129cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (interfaces->iface[j] == hapd_iface) 2130cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt break; 2131cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2132cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (j == interfaces->count) { 2133cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface **tmp; 2134cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt tmp = os_realloc_array(interfaces->iface, 2135cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt interfaces->count + 1, 2136cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt sizeof(struct hostapd_iface *)); 2137cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!tmp) { 2138cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_interface_deinit_free(hapd_iface); 2139cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 2140cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2141cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt interfaces->iface = tmp; 2142cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt interfaces->iface[interfaces->count++] = hapd_iface; 2143cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt new_iface = hapd_iface; 2144cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2145cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2146cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (new_iface) { 2147ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (interfaces->driver_init(hapd_iface)) 2148cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto fail; 21496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 21506c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (hostapd_setup_interface(hapd_iface)) { 21516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hostapd_deinit_driver( 21526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hapd_iface->bss[0]->driver, 21536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hapd_iface->bss[0]->drv_priv, 21546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hapd_iface); 21556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt goto fail; 21566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 2157cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } else { 2158cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* Assign new BSS with bss[0]'s driver info */ 2159cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd = hapd_iface->bss[hapd_iface->num_bss - 1]; 2160cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->driver = hapd_iface->bss[0]->driver; 2161cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->drv_priv = hapd_iface->bss[0]->drv_priv; 2162cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_memcpy(hapd->own_addr, hapd_iface->bss[0]->own_addr, 2163cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt ETH_ALEN); 2164cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2165cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (start_ctrl_iface_bss(hapd) < 0 || 21665460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt (hapd_iface->state == HAPD_IFACE_ENABLED && 21675460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_setup_bss(hapd, -1))) { 2168b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt hostapd_cleanup(hapd); 21697d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt hapd_iface->bss[hapd_iface->num_bss - 1] = NULL; 2170cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->conf->num_bss--; 2171cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->num_bss--; 21725460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: free hapd %p %s", 21735460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, hapd, hapd->conf->iface); 2174ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt hostapd_config_free_bss(hapd->conf); 2175ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt hapd->conf = NULL; 2176cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_free(hapd); 2177cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 2178cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2179cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2180cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 2181cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 218261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 218361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ptr = os_strchr(buf, ' '); 218461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (ptr == NULL) 218561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 218661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *ptr++ = '\0'; 218761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 21885605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (os_strncmp(ptr, "config=", 7) == 0) 21895605286c30e1701491bd3af974ae423727750eddDmitry Shmidt conf_file = ptr + 7; 21905605286c30e1701491bd3af974ae423727750eddDmitry Shmidt 219161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (i = 0; i < interfaces->count; i++) { 2192cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!os_strcmp(interfaces->iface[i]->conf->bss[0]->iface, 219361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf)) { 219461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_INFO, "Cannot add interface - it " 219561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "already exists"); 219661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 219761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 219861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 219961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 220061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface = hostapd_iface_alloc(interfaces); 220161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface == NULL) { 220261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Failed to allocate memory " 220361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "for interface", __func__); 220461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt goto fail; 220561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 2206ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt new_iface = hapd_iface; 220761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 22085605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (conf_file && interfaces->config_read_cb) { 22095605286c30e1701491bd3af974ae423727750eddDmitry Shmidt conf = interfaces->config_read_cb(conf_file); 22105605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (conf && conf->bss) 2211cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_strlcpy(conf->bss[0]->iface, buf, 2212cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt sizeof(conf->bss[0]->iface)); 22135605286c30e1701491bd3af974ae423727750eddDmitry Shmidt } else 22145605286c30e1701491bd3af974ae423727750eddDmitry Shmidt conf = hostapd_config_alloc(interfaces, buf, ptr); 22155605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (conf == NULL || conf->bss == NULL) { 221661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Failed to allocate memory " 221761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "for configuration", __func__); 221861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt goto fail; 221961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 222061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2221ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (hostapd_data_alloc(hapd_iface, conf) < 0) { 222261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Failed to allocate memory " 222361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "for hostapd", __func__); 222461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt goto fail; 222561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 2226ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conf = NULL; 222761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2228cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (start_ctrl_iface(hapd_iface) < 0) 222961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt goto fail; 2230cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2231ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_INFO, "Add interface '%s'", 2232ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt hapd_iface->conf->bss[0]->iface); 223361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 223461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 223561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 223661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtfail: 223761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (conf) 223861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_config_free(conf); 223961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface) { 2240cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd_iface->bss) { 22415460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt for (i = 0; i < hapd_iface->num_bss; i++) { 22425460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd = hapd_iface->bss[i]; 22437d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt if (!hapd) 22447d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt continue; 22457d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt if (hapd_iface->interfaces && 22465460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd_iface->interfaces->ctrl_iface_deinit) 22475460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd_iface->interfaces-> 22485460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt ctrl_iface_deinit(hapd); 22495460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: free hapd %p (%s)", 22505460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, hapd_iface->bss[i], 22517d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt hapd->conf->iface); 22526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hostapd_cleanup(hapd); 22537d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt os_free(hapd); 22547d5c8f257a74ac0d12828962a492e8b84ef83923Dmitry Shmidt hapd_iface->bss[i] = NULL; 22555460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt } 2256cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_free(hapd_iface->bss); 22576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hapd_iface->bss = NULL; 2258cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2259ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (new_iface) { 2260ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt interfaces->count--; 2261ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt interfaces->iface[interfaces->count] = NULL; 2262ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 22636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt hostapd_cleanup_iface(hapd_iface); 226461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 226561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 226661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 226761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 226861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 2269cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic int hostapd_remove_bss(struct hostapd_iface *iface, unsigned int idx) 2270cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 2271cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i; 2272cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 22735460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_INFO, "Remove BSS '%s'", iface->conf->bss[idx]->iface); 2274cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 22755460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt /* Remove hostapd_data only if it has already been initialized */ 22765460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt if (idx < iface->num_bss) { 22775460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt struct hostapd_data *hapd = iface->bss[idx]; 2278cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 22795460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_bss_deinit(hapd); 22805460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: free hapd %p (%s)", 22815460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, hapd, hapd->conf->iface); 22825460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_config_free_bss(hapd->conf); 2283ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt hapd->conf = NULL; 22845460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt os_free(hapd); 22855460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 22865460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt iface->num_bss--; 22875460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 22885460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt for (i = idx; i < iface->num_bss; i++) 22895460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt iface->bss[i] = iface->bss[i + 1]; 22905460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt } else { 22915460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_config_free_bss(iface->conf->bss[idx]); 22925460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt iface->conf->bss[idx] = NULL; 22935460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt } 2294cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2295cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->num_bss--; 22965460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt for (i = idx; i < iface->conf->num_bss; i++) 2297cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->bss[i] = iface->conf->bss[i + 1]; 2298cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2299cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 2300cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 2301cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2302cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 230361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint hostapd_remove_iface(struct hapd_interfaces *interfaces, char *buf) 230461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 230561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_iface *hapd_iface; 2306cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i, j, k = 0; 230761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 230861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (i = 0; i < interfaces->count; i++) { 230961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface = interfaces->iface[i]; 231061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface == NULL) 231161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 23125460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt if (!os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) { 231361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_INFO, "Remove interface '%s'", buf); 2314a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt hapd_iface->driver_ap_teardown = 2315a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt !!(hapd_iface->drv_flags & 2316a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT); 2317a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt 231861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_interface_deinit_free(hapd_iface); 231961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt k = i; 232061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt while (k < (interfaces->count - 1)) { 232161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->iface[k] = 232261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->iface[k + 1]; 232361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt k++; 232461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 232561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->count--; 232661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 232761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 2328cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2329cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (j = 0; j < hapd_iface->conf->num_bss; j++) { 2330a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt if (!os_strcmp(hapd_iface->conf->bss[j]->iface, buf)) { 2331a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt hapd_iface->driver_ap_teardown = 2332a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt !(hapd_iface->drv_flags & 2333a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT); 2334cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return hostapd_remove_bss(hapd_iface, j); 2335a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt } 2336cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 233761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 233861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 233961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 234061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 234161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 23428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 23438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_new_assoc_sta - Notify that a new station associated with the AP 23448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hapd: Pointer to BSS data 23458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sta: Pointer to the associated STA data 23468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @reassoc: 1 to indicate this was a re-association; 0 = first association 23478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 23488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function will be called whenever a station associates with the AP. It 23498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * can be called from ieee802_11.c for drivers that export MLME to hostapd and 23508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * from drv_callbacks.c based on driver events for drivers that take care of 23518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * management frames (IEEE 802.11 authentication and association) internally. 23528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 23538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta, 23548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int reassoc) 23558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->tkip_countermeasures) { 23578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_drv_sta_deauth(hapd, sta->addr, 23588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_REASON_MICHAEL_MIC_FAILURE); 23598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 23608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_prune_associations(hapd, sta->addr); 23638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* IEEE 802.11F (IAPP) */ 23658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ieee802_11f) 23668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iapp_new_station(hapd->iapp, sta); 23678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P 23698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->p2p_ie == NULL && !sta->no_p2p_set) { 23708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->no_p2p_set = 1; 23718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->num_sta_no_p2p++; 23728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->num_sta_no_p2p == 1) 23738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_p2p_non_p2p_sta_connected(hapd); 23748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */ 23768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Start accounting here, if IEEE 802.1X and WPA are not used. 23788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * IEEE 802.1X/WPA code will start accounting after the station has 23798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * been authorized. */ 23802ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt if (!hapd->conf->ieee802_1x && !hapd->conf->wpa && !hapd->conf->osen) { 23812ac5f6049e74103a8fe8e9c78b330020081d7df4Dmitry Shmidt ap_sta_set_authorized(hapd, sta, 1); 238204f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt os_get_reltime(&sta->connected_time); 23838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt accounting_sta_start(hapd, sta); 2384d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 23858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Start IEEE 802.1X authentication process for new stations */ 23878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_new_station(hapd, sta); 23888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reassoc) { 23898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->auth_alg != WLAN_AUTH_FT && 23908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS))) 23918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH); 23928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 23938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm); 239404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 239501904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_INACTIVITY_TIMER)) { 239601904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: reschedule ap_handle_timer timeout " 239701904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt "for " MACSTR " (%d seconds - ap_max_inactivity)", 239801904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt __func__, MAC2STR(sta->addr), 239901904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt hapd->conf->ap_max_inactivity); 240001904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt eloop_cancel_timeout(ap_handle_timer, hapd, sta); 240101904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt eloop_register_timeout(hapd->conf->ap_max_inactivity, 0, 240201904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt ap_handle_timer, hapd, sta); 240301904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt } 24048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2405cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2406cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2407cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtconst char * hostapd_state_text(enum hostapd_iface_state s) 2408cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 2409cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt switch (s) { 2410cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_UNINITIALIZED: 2411cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "UNINITIALIZED"; 2412cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_DISABLED: 2413cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "DISABLED"; 2414cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_COUNTRY_UPDATE: 2415cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "COUNTRY_UPDATE"; 2416cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_ACS: 2417cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "ACS"; 2418cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_HT_SCAN: 2419cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "HT_SCAN"; 2420cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_DFS: 2421cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "DFS"; 2422cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_ENABLED: 2423cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "ENABLED"; 2424cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2425cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2426cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "UNKNOWN"; 2427cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 2428cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2429cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2430cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtvoid hostapd_set_state(struct hostapd_iface *iface, enum hostapd_iface_state s) 2431cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 2432cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "%s: interface state %s->%s", 2433cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->bss[0]->iface, hostapd_state_text(iface->state), 2434cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_state_text(s)); 2435cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->state = s; 2436cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 2437e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2438e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2439e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt#ifdef NEED_AP_MLME 2440e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2441e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtstatic void free_beacon_data(struct beacon_data *beacon) 2442e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 2443e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_free(beacon->head); 2444e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->head = NULL; 2445e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_free(beacon->tail); 2446e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->tail = NULL; 2447e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_free(beacon->probe_resp); 2448e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->probe_resp = NULL; 2449e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_free(beacon->beacon_ies); 2450e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->beacon_ies = NULL; 2451e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_free(beacon->proberesp_ies); 2452e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->proberesp_ies = NULL; 2453e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_free(beacon->assocresp_ies); 2454e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->assocresp_ies = NULL; 2455e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 2456e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2457e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2458d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidtstatic int hostapd_build_beacon_data(struct hostapd_data *hapd, 2459e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct beacon_data *beacon) 2460e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 2461e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct wpabuf *beacon_extra, *proberesp_extra, *assocresp_extra; 2462e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct wpa_driver_ap_params params; 2463e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt int ret; 2464e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 246501904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt os_memset(beacon, 0, sizeof(*beacon)); 2466e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = ieee802_11_build_ap_params(hapd, ¶ms); 2467e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret < 0) 2468e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 2469e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2470e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = hostapd_build_ap_extra_ies(hapd, &beacon_extra, 2471e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &proberesp_extra, 2472e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &assocresp_extra); 2473e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) 2474e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_ap_params; 2475e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2476e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = -1; 2477e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->head = os_malloc(params.head_len); 2478e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!beacon->head) 2479e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_ap_extra_ies; 2480e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2481e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memcpy(beacon->head, params.head, params.head_len); 2482e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->head_len = params.head_len; 2483e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2484e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->tail = os_malloc(params.tail_len); 2485e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!beacon->tail) 2486e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_beacon; 2487e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2488e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memcpy(beacon->tail, params.tail, params.tail_len); 2489e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->tail_len = params.tail_len; 2490e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2491e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (params.proberesp != NULL) { 2492e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->probe_resp = os_malloc(params.proberesp_len); 2493e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!beacon->probe_resp) 2494e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_beacon; 2495e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2496e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memcpy(beacon->probe_resp, params.proberesp, 2497e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt params.proberesp_len); 2498e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->probe_resp_len = params.proberesp_len; 2499e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2500e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2501e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* copy the extra ies */ 2502e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (beacon_extra) { 2503e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->beacon_ies = os_malloc(wpabuf_len(beacon_extra)); 2504e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!beacon->beacon_ies) 2505e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_beacon; 2506e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2507e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memcpy(beacon->beacon_ies, 2508e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon_extra->buf, wpabuf_len(beacon_extra)); 2509e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->beacon_ies_len = wpabuf_len(beacon_extra); 2510e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2511e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2512e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (proberesp_extra) { 2513e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->proberesp_ies = 2514e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_malloc(wpabuf_len(proberesp_extra)); 2515e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!beacon->proberesp_ies) 2516e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_beacon; 2517e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2518e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memcpy(beacon->proberesp_ies, proberesp_extra->buf, 2519e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt wpabuf_len(proberesp_extra)); 2520e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->proberesp_ies_len = wpabuf_len(proberesp_extra); 2521e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2522e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2523e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (assocresp_extra) { 2524e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->assocresp_ies = 2525e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_malloc(wpabuf_len(assocresp_extra)); 2526e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!beacon->assocresp_ies) 2527e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_beacon; 2528e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2529e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memcpy(beacon->assocresp_ies, assocresp_extra->buf, 2530e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt wpabuf_len(assocresp_extra)); 2531e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->assocresp_ies_len = wpabuf_len(assocresp_extra); 2532e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2533e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2534e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = 0; 2535e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtfree_beacon: 2536e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* if the function fails, the caller should not free beacon data */ 2537e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) 2538e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt free_beacon_data(beacon); 2539e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2540e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtfree_ap_extra_ies: 2541e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt hostapd_free_ap_extra_ies(hapd, beacon_extra, proberesp_extra, 2542e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt assocresp_extra); 2543e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtfree_ap_params: 2544e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ieee802_11_free_ap_params(¶ms); 2545e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 2546e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 2547e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2548e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2549e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt/* 2550e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt * TODO: This flow currently supports only changing frequency within the 2551e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt * same hw_mode. Any other changes to MAC parameters or provided settings (even 2552e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt * width) are not supported. 2553e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt */ 2554e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtstatic int hostapd_change_config_freq(struct hostapd_data *hapd, 2555e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct hostapd_config *conf, 2556e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct hostapd_freq_params *params, 2557e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct hostapd_freq_params *old_params) 2558e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 2559e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt int channel; 2560e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2561e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!params->channel) { 2562e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* check if the new channel is supported by hw */ 2563d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt params->channel = hostapd_hw_get_channel(hapd, params->freq); 2564e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2565e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2566d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt channel = params->channel; 2567d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt if (!channel) 2568d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt return -1; 2569d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 2570e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* if a pointer to old_params is provided we save previous state */ 2571e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (old_params) { 2572e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt old_params->channel = conf->channel; 2573e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt old_params->ht_enabled = conf->ieee80211n; 2574e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt old_params->sec_channel_offset = conf->secondary_channel; 2575e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2576e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2577e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt conf->channel = channel; 2578e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt conf->ieee80211n = params->ht_enabled; 2579e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt conf->secondary_channel = params->sec_channel_offset; 2580e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2581e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* TODO: maybe call here hostapd_config_check here? */ 2582e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2583e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return 0; 2584e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 2585e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2586e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2587d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidtstatic int hostapd_fill_csa_settings(struct hostapd_data *hapd, 2588e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct csa_settings *settings) 2589e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 2590d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt struct hostapd_iface *iface = hapd->iface; 2591e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct hostapd_freq_params old_freq; 2592e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt int ret; 2593e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2594e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memset(&old_freq, 0, sizeof(old_freq)); 2595d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt if (!iface || !iface->freq || hapd->csa_in_progress) 2596e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return -1; 2597e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2598e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = hostapd_change_config_freq(iface->bss[0], iface->conf, 2599e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &settings->freq_params, 2600e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &old_freq); 2601e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) 2602e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 2603e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2604d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt ret = hostapd_build_beacon_data(hapd, &settings->beacon_after); 2605e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2606e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* change back the configuration */ 2607e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt hostapd_change_config_freq(iface->bss[0], iface->conf, 2608e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &old_freq, NULL); 2609e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2610e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) 2611e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 2612e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2613e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* set channel switch parameters for csa ie */ 2614d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->cs_freq_params = settings->freq_params; 2615d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->cs_count = settings->cs_count; 2616d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->cs_block_tx = settings->block_tx; 2617e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2618d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt ret = hostapd_build_beacon_data(hapd, &settings->beacon_csa); 2619e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) { 2620e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt free_beacon_data(&settings->beacon_after); 2621e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 2622e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2623e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2624d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt settings->counter_offset_beacon = hapd->cs_c_off_beacon; 2625d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt settings->counter_offset_presp = hapd->cs_c_off_proberesp; 2626e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2627e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return 0; 2628e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 2629e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2630e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2631e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtvoid hostapd_cleanup_cs_params(struct hostapd_data *hapd) 2632e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 2633d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt os_memset(&hapd->cs_freq_params, 0, sizeof(hapd->cs_freq_params)); 2634d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->cs_count = 0; 2635d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->cs_block_tx = 0; 2636d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->cs_c_off_beacon = 0; 2637d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->cs_c_off_proberesp = 0; 2638d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->csa_in_progress = 0; 2639e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 2640e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2641e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2642e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtint hostapd_switch_channel(struct hostapd_data *hapd, 2643e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct csa_settings *settings) 2644e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 2645e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt int ret; 26466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 26476c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA)) { 26486c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt wpa_printf(MSG_INFO, "CSA is not supported"); 26496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return -1; 26506c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt } 26516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 2652d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt ret = hostapd_fill_csa_settings(hapd, settings); 2653e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) 2654e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 2655e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2656e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = hostapd_drv_switch_channel(hapd, settings); 2657e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt free_beacon_data(&settings->beacon_csa); 2658e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt free_beacon_data(&settings->beacon_after); 2659e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2660e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) { 2661e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* if we failed, clean cs parameters */ 2662e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt hostapd_cleanup_cs_params(hapd); 2663e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 2664e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2665e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2666d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hapd->csa_in_progress = 1; 2667e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return 0; 2668e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 2669e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2670d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 2671d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidtvoid 2672d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidthostapd_switch_channel_fallback(struct hostapd_iface *iface, 2673d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt const struct hostapd_freq_params *freq_params) 2674d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt{ 2675d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt int vht_seg0_idx = 0, vht_seg1_idx = 0, vht_bw = VHT_CHANWIDTH_USE_HT; 2676d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt unsigned int i; 2677d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 2678d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt wpa_printf(MSG_DEBUG, "Restarting all CSA-related BSSes"); 2679d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 2680d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt if (freq_params->center_freq1) 2681d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt vht_seg0_idx = 36 + (freq_params->center_freq1 - 5180) / 5; 2682d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt if (freq_params->center_freq2) 2683d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt vht_seg1_idx = 36 + (freq_params->center_freq2 - 5180) / 5; 2684d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 2685d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt switch (freq_params->bandwidth) { 2686d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt case 0: 2687d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt case 20: 2688d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt case 40: 2689d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt vht_bw = VHT_CHANWIDTH_USE_HT; 2690d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt break; 2691d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt case 80: 2692d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt if (freq_params->center_freq2) 2693d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt vht_bw = VHT_CHANWIDTH_80P80MHZ; 2694d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt else 2695d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt vht_bw = VHT_CHANWIDTH_80MHZ; 2696d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt break; 2697d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt case 160: 2698d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt vht_bw = VHT_CHANWIDTH_160MHZ; 2699d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt break; 2700d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt default: 2701d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt wpa_printf(MSG_WARNING, "Unknown CSA bandwidth: %d", 2702d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt freq_params->bandwidth); 2703d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt break; 2704d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt } 2705d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 2706d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt iface->freq = freq_params->freq; 2707d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt iface->conf->channel = freq_params->channel; 2708d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt iface->conf->secondary_channel = freq_params->sec_channel_offset; 2709d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt iface->conf->vht_oper_centr_freq_seg0_idx = vht_seg0_idx; 2710d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt iface->conf->vht_oper_centr_freq_seg1_idx = vht_seg1_idx; 2711d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt iface->conf->vht_oper_chwidth = vht_bw; 2712d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt iface->conf->ieee80211n = freq_params->ht_enabled; 2713d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt iface->conf->ieee80211ac = freq_params->vht_enabled; 2714d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 2715d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt /* 2716d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt * cs_params must not be cleared earlier because the freq_params 2717d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt * argument may actually point to one of these. 2718d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt */ 2719d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt for (i = 0; i < iface->num_bss; i++) 2720d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hostapd_cleanup_cs_params(iface->bss[i]); 2721d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 2722d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hostapd_disable_iface(iface); 2723d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt hostapd_enable_iface(iface); 2724d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt} 2725d30ac604c9f6da71a0dd7f46d25be05a2a62cfbbDmitry Shmidt 2726e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt#endif /* NEED_AP_MLME */ 2727