hostapd.c revision 9767226d8e6a1adaa33beb9f517ef40dddfa460c
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" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "hostapd.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "authsrv.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "sta_info.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "accounting.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_list.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "beacon.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "iapp.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ieee802_1x.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ieee802_11_auth.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "vlan_init.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_auth.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps_hostapd.h" 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "hw_features.h" 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_auth_glue.h" 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_drv_ops.h" 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_config.h" 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_hostapd.h" 3404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "gas_serv.h" 35051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#include "dfs.h" 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason); 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd); 40c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidtstatic int hostapd_broadcast_wep_clear(struct hostapd_data *hapd); 41cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic int setup_interface2(struct hostapd_iface *iface); 42cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic void channel_list_update_timeout(void *eloop_ctx, void *timeout_ctx); 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint hostapd_for_each_interface(struct hapd_interfaces *interfaces, 4604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int (*cb)(struct hostapd_iface *iface, 4704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt void *ctx), void *ctx) 4804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 4904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt size_t i; 5004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int ret; 5104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 5204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (i = 0; i < interfaces->count; i++) { 5304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ret = cb(interfaces->iface[i], ctx); 5404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ret) 5504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return ret; 5604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 5704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 5804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 5904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 6004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 6104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_reload_bss(struct hostapd_data *hapd) 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 64cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_ssid *ssid; 65cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_client_reconfig(hapd->radius, hapd->conf->radius); 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 70cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt ssid = &hapd->conf->ssid; 71cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!ssid->wpa_psk_set && ssid->wpa_psk && !ssid->wpa_psk->next && 72cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt ssid->wpa_passphrase_set && ssid->wpa_passphrase) { 73cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* 74cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * Force PSK to be derived again since SSID or passphrase may 75cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * have changed. 76cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 77cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_free(ssid->wpa_psk); 78cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt ssid->wpa_psk = NULL; 79cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_setup_wpa_psk(hapd->conf)) { 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to re-configure WPA PSK " 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "after reloading configuration"); 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ieee802_1x || hapd->conf->wpa) 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 1); 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_drv_ieee8021x(hapd, hapd->conf->iface, 0); 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (hapd->conf->wpa && hapd->wpa_auth == NULL) { 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_setup_wpa(hapd); 921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (hapd->wpa_auth) 931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_init_keys(hapd->wpa_auth); 941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else if (hapd->conf->wpa) { 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *wpa_ie; 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t wpa_ie_len; 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_reconfig_wpa(hapd); 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &wpa_ie_len); 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_set_generic_elem(hapd, wpa_ie, wpa_ie_len)) 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to configure WPA IE for " 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "the kernel driver."); 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (hapd->wpa_auth) { 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_deinit(hapd->wpa_auth); 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->wpa_auth = NULL; 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_privacy(hapd, 0); 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_setup_encryption(hapd->conf->iface, hapd); 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_generic_elem(hapd, (u8 *) "", 0); 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_11_set_beacon(hapd); 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_update_wps(hapd); 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ssid.ssid_set && 11461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_set_ssid(hapd, hapd->conf->ssid.ssid, 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->ssid.ssid_len)) { 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver"); 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* try to continue */ 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Reconfigured interface %s", hapd->conf->iface); 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 123444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidtstatic void hostapd_clear_old(struct hostapd_iface *iface) 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t j; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Deauthenticate all stations since the new configuration may not 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * allow them to use the BSS anymore. 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 13204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_flush_old_stations(iface->bss[j], 13304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt WLAN_REASON_PREV_AUTH_NOT_VALID); 134c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt hostapd_broadcast_wep_clear(iface->bss[j]); 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: update dynamic data based on changed configuration 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * items (e.g., open/close sockets, etc.) */ 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_client_flush(iface->bss[j]->radius, 0); 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 142444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt} 143444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt 144444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt 145444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidtint hostapd_reload_config(struct hostapd_iface *iface) 146444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt{ 147444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt struct hostapd_data *hapd = iface->bss[0]; 148444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt struct hostapd_config *newconf, *oldconf; 149444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt size_t j; 150444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt 151444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt if (iface->config_fname == NULL) { 152444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt /* Only in-memory config in use - assume it has been updated */ 153444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt hostapd_clear_old(iface); 154444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) 155444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt hostapd_reload_bss(iface->bss[j]); 156444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt return 0; 157444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt } 158444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt 159444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt if (iface->interfaces == NULL || 160444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt iface->interfaces->config_read_cb == NULL) 161444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt return -1; 162444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt newconf = iface->interfaces->config_read_cb(iface->config_fname); 163444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt if (newconf == NULL) 164444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt return -1; 165444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt 166444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt hostapd_clear_old(iface); 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt oldconf = hapd->iconf; 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->conf = newconf; 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd = iface->bss[j]; 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iconf = newconf; 174cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->conf = newconf->bss[j]; 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_reload_bss(hapd); 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_config_free(oldconf); 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_broadcast_key_clear_iface(struct hostapd_data *hapd, 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *ifname) 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < NUM_WEP_KEYS; i++) { 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE, NULL, i, 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, NULL, 0, NULL, 0)) { 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to clear default " 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "encryption keys (ifname=%s keyidx=%d)", 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ifname, i); 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ieee80211w) { 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = NUM_WEP_KEYS; i < NUM_WEP_KEYS + 2; i++) { 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_drv_set_key(ifname, hapd, WPA_ALG_NONE, 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, i, 0, NULL, 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, NULL, 0)) { 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to clear " 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "default mgmt encryption keys " 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(ifname=%s keyidx=%d)", ifname, i); 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_broadcast_wep_clear(struct hostapd_data *hapd) 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_broadcast_key_clear_iface(hapd, hapd->conf->iface); 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_broadcast_wep_set(struct hostapd_data *hapd) 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int errors = 0, idx; 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_ssid *ssid = &hapd->conf->ssid; 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idx = ssid->wep.idx; 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->wep.default_len && 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_drv_set_key(hapd->conf->iface, 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd, WPA_ALG_WEP, broadcast_ether_addr, idx, 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1, NULL, 0, ssid->wep.key[idx], 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid->wep.len[idx])) { 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "Could not set WEP encryption."); 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt errors++; 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return errors; 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void hostapd_free_hapd_data(struct hostapd_data *hapd) 24104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 242fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt if (!hapd->started) { 243fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Interface %s wasn't started", 244fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt __func__, hapd->conf->iface); 245fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt return; 246fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt } 247fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt hapd->started = 0; 248fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt 2495460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface); 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iapp_deinit(hapd->iapp); 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iapp = NULL; 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt accounting_deinit(hapd); 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_deinit_wpa(hapd); 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt vlan_deinit(hapd); 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_acl_deinit(hapd); 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt radius_client_deinit(hapd->radius); 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->radius = NULL; 25904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt radius_das_deinit(hapd->radius_das); 26004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hapd->radius_das = NULL; 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_deinit_wps(hapd); 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt authsrv_deinit(hapd); 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2675460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt if (hapd->interface_added && 2685460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_if_remove(hapd, WPA_IF_AP_BSS, hapd->conf->iface)) { 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "Failed to remove BSS interface %s", 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->iface); 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(hapd->probereq_cb); 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->probereq_cb = NULL; 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(hapd->p2p_beacon_ie); 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->p2p_beacon_ie = NULL; 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(hapd->p2p_probe_resp_ie); 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->p2p_probe_resp_ie = NULL; 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */ 2821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpabuf_free(hapd->time_adv); 28404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 28504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_INTERWORKING 28604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt gas_serv_deinit(hapd); 28704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_INTERWORKING */ 288d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 289d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SQLITE 290d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_free(hapd->tmp_eap_user.identity); 291d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt os_free(hapd->tmp_eap_user.password); 292d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SQLITE */ 29304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 29404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 29504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 29604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/** 29704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * hostapd_cleanup - Per-BSS cleanup (deinitialization) 29804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @hapd: Pointer to BSS data 29904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * 30004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * This function is used to free all per-BSS data structures and resources. 3015460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt * Most of the modules that are initialized in hostapd_setup_bss() are 3025460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt * deinitialized here. 30304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 30404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void hostapd_cleanup(struct hostapd_data *hapd) 30504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 3065460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(hapd=%p (%s))", __func__, hapd, 3075460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd->conf->iface); 30861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd->iface->interfaces && 30961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd->iface->interfaces->ctrl_iface_deinit) 31061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd->iface->interfaces->ctrl_iface_deinit(hapd); 31104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_free_hapd_data(hapd); 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void hostapd_cleanup_iface_partial(struct hostapd_iface *iface) 31604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 3175460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); 31804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_free_hw_features(iface->hw_features, iface->num_hw_features); 31904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt iface->hw_features = NULL; 32004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(iface->current_rates); 32104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt iface->current_rates = NULL; 32204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(iface->basic_rates); 32304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt iface->basic_rates = NULL; 32404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ap_list_deinit(iface); 32504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 32604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 32704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_cleanup_iface - Complete per-interface cleanup 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @iface: Pointer to interface data 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called after per-BSS data structures are deinitialized 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * with hostapd_cleanup(). 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_cleanup_iface(struct hostapd_iface *iface) 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3375460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); 338cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt eloop_cancel_timeout(channel_list_update_timeout, iface, NULL); 339cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 34004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_cleanup_iface_partial(iface); 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_config_free(iface->conf); 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->conf = NULL; 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(iface->config_fname); 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(iface->bss); 3465460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: free iface=%p", __func__, iface); 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(iface); 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 35104949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void hostapd_clear_wep(struct hostapd_data *hapd) 35204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 35304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (hapd->drv_priv) { 35404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_set_privacy(hapd, 0); 35504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_broadcast_wep_clear(hapd); 35604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 35704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 35804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 35904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd) 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_broadcast_wep_set(hapd); 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ssid.wep.default_len) { 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_privacy(hapd, 1); 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 37175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen /* 37275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * When IEEE 802.1X is not enabled, the driver may need to know how to 37375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen * set authentication algorithms for static WEP. 37475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen */ 37575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen hostapd_drv_set_authmode(hapd, hapd->conf->auth_algs); 37675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 4; i++) { 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ssid.wep.key[i] && 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_drv_set_key(iface, hapd, WPA_ALG_WEP, NULL, i, 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i == hapd->conf->ssid.wep.idx, NULL, 0, 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->ssid.wep.key[i], 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->ssid.wep.len[i])) { 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "Could not set WEP " 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "encryption."); 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ssid.wep.key[i] && 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i == hapd->conf->ssid.wep.idx) 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_privacy(hapd, 1); 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 39604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason) 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 addr[ETH_ALEN]; 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_drv_none(hapd) || hapd->drv_priv == NULL) 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "Flushing old station entries"); 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_flush(hapd)) { 4061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_msg(hapd->msg_ctx, MSG_WARNING, "Could not connect to " 4071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "kernel driver"); 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "Deauthenticate all stations"); 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(addr, 0xff, ETH_ALEN); 41204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_drv_sta_deauth(hapd, addr, reason); 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_free_stas(hapd); 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_validate_bssid_configuration - Validate BSSID configuration 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @iface: Pointer to interface data 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to validate that the configured BSSIDs are valid. 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_validate_bssid_configuration(struct hostapd_iface *iface) 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 mask[ETH_ALEN] = { 0 }; 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = iface->bss[0]; 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int i = iface->conf->num_bss, bits = 0, j; 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int auto_addr = 0; 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_drv_none(hapd)) 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Generate BSSID mask that is large enough to cover the BSSIDs. */ 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Determine the bits necessary to cover the number of BSSIDs. */ 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i--; i; i >>= 1) 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bits++; 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Determine the bits necessary to any configured BSSIDs, 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if they are higher than the number of BSSIDs. */ 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < iface->conf->num_bss; j++) { 445cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hostapd_mac_comp_empty(iface->conf->bss[j]->bssid) == 0) { 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (j) 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auto_addr++; 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < ETH_ALEN; i++) { 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mask[i] |= 453cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->bss[j]->bssid[i] ^ 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->own_addr[i]; 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!auto_addr) 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto skip_mask_ext; 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < ETH_ALEN && mask[i] == 0; i++) 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ; 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt j = 0; 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i < ETH_ALEN) { 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt j = (5 - i) * 8; 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (mask[i] != 0) { 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mask[i] >>= 1; 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt j++; 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bits < j) 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bits = j; 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bits > 40) { 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Too many bits in the BSSID mask (%u)", 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bits); 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(mask, 0xff, ETH_ALEN); 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt j = bits / 8; 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 5; i > 5 - j; i--) 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mask[i] = 0; 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt j = bits % 8; 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (j--) 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mask[i] <<= 1; 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtskip_mask_ext: 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "BSS count %lu, BSSID mask " MACSTR " (%d bits)", 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) iface->conf->num_bss, MAC2STR(mask), bits); 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!auto_addr) 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < ETH_ALEN; i++) { 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((hapd->own_addr[i] & mask[i]) != hapd->own_addr[i]) { 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Invalid BSSID mask " MACSTR 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " for start address " MACSTR ".", 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(mask), MAC2STR(hapd->own_addr)); 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Start address must be the " 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "first address in the block (i.e., addr " 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "AND mask == addr)."); 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int mac_in_conf(struct hostapd_config *conf, const void *a) 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < conf->num_bss; i++) { 518cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hostapd_mac_comp(conf->bss[i]->bssid, a) == 0) { 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifndef CONFIG_NO_RADIUS 52804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 52904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int hostapd_das_nas_mismatch(struct hostapd_data *hapd, 53004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct radius_das_attrs *attr) 53104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 53204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* TODO */ 53304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 53404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 53504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 53604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 53704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic struct sta_info * hostapd_das_find_sta(struct hostapd_data *hapd, 53804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct radius_das_attrs *attr) 53904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 54004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct sta_info *sta = NULL; 54104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt char buf[128]; 54204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 54304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (attr->sta_addr) 54404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sta = ap_get_sta(hapd, attr->sta_addr); 54504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 54604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (sta == NULL && attr->acct_session_id && 54704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt attr->acct_session_id_len == 17) { 54804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (sta = hapd->sta_list; sta; sta = sta->next) { 54904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_snprintf(buf, sizeof(buf), "%08X-%08X", 55004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sta->acct_session_id_hi, 55104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sta->acct_session_id_lo); 55204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (os_memcmp(attr->acct_session_id, buf, 17) == 0) 55304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 55404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 55504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 55604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 55704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (sta == NULL && attr->cui) { 55804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (sta = hapd->sta_list; sta; sta = sta->next) { 55904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpabuf *cui; 56004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt cui = ieee802_1x_get_radius_cui(sta->eapol_sm); 56104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (cui && wpabuf_len(cui) == attr->cui_len && 56204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcmp(wpabuf_head(cui), attr->cui, 56304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt attr->cui_len) == 0) 56404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 56504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 56604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 56704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 56804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (sta == NULL && attr->user_name) { 56904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (sta = hapd->sta_list; sta; sta = sta->next) { 57004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 *identity; 57104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt size_t identity_len; 57204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt identity = ieee802_1x_get_identity(sta->eapol_sm, 57304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt &identity_len); 57404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (identity && 57504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt identity_len == attr->user_name_len && 57604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcmp(identity, attr->user_name, identity_len) 57704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt == 0) 57804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 57904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 58004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 58104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 58204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return sta; 58304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 58404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 58504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 58604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic enum radius_das_res 58704949598a23f501be6eec21697465fd46a28840aDmitry Shmidthostapd_das_disconnect(void *ctx, struct radius_das_attrs *attr) 58804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 58904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct hostapd_data *hapd = ctx; 59004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct sta_info *sta; 59104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 59204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (hostapd_das_nas_mismatch(hapd, attr)) 59304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return RADIUS_DAS_NAS_MISMATCH; 59404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 59504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sta = hostapd_das_find_sta(hapd, attr); 59604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (sta == NULL) 59704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return RADIUS_DAS_SESSION_NOT_FOUND; 59804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 59904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_drv_sta_deauth(hapd, sta->addr, 60004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt WLAN_REASON_PREV_AUTH_NOT_VALID); 60104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ap_sta_deauthenticate(hapd, sta, WLAN_REASON_PREV_AUTH_NOT_VALID); 60204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 60304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return RADIUS_DAS_SUCCESS; 60404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 60504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 60604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_setup_bss - Per-BSS setup (initialization) 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hapd: Pointer to BSS data 612cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * @first: Whether this BSS is the first BSS of an interface; -1 = not first, 613cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * but interface may exist 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to initialize all per-BSS data structures and 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * resources. This gets called in a loop for each BSS when an interface is 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * initialized. Most of the modules that are initialized here will be 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * deinitialized in hostapd_cleanup(). 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_setup_bss(struct hostapd_data *hapd, int first) 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_bss_config *conf = hapd->conf; 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ssid[HOSTAPD_MAX_SSID_LEN + 1]; 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ssid_len, set_ssid; 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char force_ifname[IFNAMSIZ]; 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 if_addr[ETH_ALEN]; 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6285460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(hapd=%p (%s), first=%d)", 6295460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, hapd, hapd->conf->iface, first); 6305460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 6315460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt if (hapd->started) { 6325460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Interface %s was already started", 6335460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, hapd->conf->iface); 6345460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt return -1; 6355460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt } 6365460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd->started = 1; 6375460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 638cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!first || first == -1) { 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0) { 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Allocate the next available BSSID. */ 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt do { 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt inc_byte_array(hapd->own_addr, ETH_ALEN); 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } while (mac_in_conf(hapd->iconf, hapd->own_addr)); 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Allocate the configured BSSID. */ 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(hapd->own_addr, hapd->conf->bssid, ETH_ALEN); 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_mac_comp(hapd->own_addr, 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface->bss[0]->own_addr) == 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) { 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "BSS '%s' may not have " 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "BSSID set to the MAC address of " 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "the radio", hapd->conf->iface); 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6585460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd->interface_added = 1; 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_if_add(hapd->iface->bss[0], WPA_IF_AP_BSS, 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->iface, hapd->own_addr, hapd, 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &hapd->drv_priv, force_ifname, if_addr, 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->bridge[0] ? hapd->conf->bridge : 663cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt NULL, first == -1)) { 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to add BSS (BSSID=" 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR ")", MAC2STR(hapd->own_addr)); 6663cf6f79011d16f23e60cbf2846aab0fd440511daDmitry Shmidt hapd->interface_added = 0; 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->wmm_enabled < 0) 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->wmm_enabled = hapd->iconf->ieee80211n; 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 67404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hostapd_flush_old_stations(hapd, WLAN_REASON_PREV_AUTH_NOT_VALID); 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_privacy(hapd, 0); 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_broadcast_wep_clear(hapd); 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_setup_encryption(hapd->conf->iface, hapd)) 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Fetch the SSID from the system and use it or, 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * if one was specified in the config file, verify they 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * match. 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid_len = hostapd_get_ssid(hapd, ssid, sizeof(ssid)); 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid_len < 0) { 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not read SSID from system"); 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf->ssid.ssid_set) { 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If SSID is specified in the config file and it differs 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * from what is being used then force installation of the 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * new SSID. 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt set_ssid = (conf->ssid.ssid_len != (size_t) ssid_len || 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(conf->ssid.ssid, ssid, ssid_len) != 0); 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * No SSID in the config file; just use the one we got 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * from the system. 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt set_ssid = 0; 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->ssid.ssid_len = ssid_len; 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conf->ssid.ssid, ssid, conf->ssid.ssid_len); 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!hostapd_drv_none(hapd)) { 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Using interface %s with hwaddr " MACSTR 71161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt " and ssid \"%s\"", 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->iface, MAC2STR(hapd->own_addr), 71361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_ssid_txt(hapd->conf->ssid.ssid, 71461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd->conf->ssid.ssid_len)); 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_setup_wpa_psk(conf)) { 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "WPA-PSK setup failed."); 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Set SSID for the kernel driver (to be used in beacon and probe 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * response frames) */ 72461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (set_ssid && hostapd_set_ssid(hapd, conf->ssid.ssid, 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->ssid.ssid_len)) { 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver"); 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_debug_level == MSG_MSGDUMP) 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf->radius->msg_dumps = 1; 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_RADIUS 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->radius = radius_client_init(hapd, conf->radius); 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->radius == NULL) { 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "RADIUS client initialization failed."); 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 73804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 73904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (hapd->conf->radius_das_port) { 74004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct radius_das_conf das_conf; 74104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memset(&das_conf, 0, sizeof(das_conf)); 74204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt das_conf.port = hapd->conf->radius_das_port; 74304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt das_conf.shared_secret = hapd->conf->radius_das_shared_secret; 74404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt das_conf.shared_secret_len = 74504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hapd->conf->radius_das_shared_secret_len; 74604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt das_conf.client_addr = &hapd->conf->radius_das_client_addr; 74704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt das_conf.time_window = hapd->conf->radius_das_time_window; 74804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt das_conf.require_event_timestamp = 74904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hapd->conf->radius_das_require_event_timestamp; 75004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt das_conf.ctx = hapd; 75104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt das_conf.disconnect = hostapd_das_disconnect; 75204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hapd->radius_das = radius_das_init(&das_conf); 75304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (hapd->radius_das == NULL) { 75404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_ERROR, "RADIUS DAS initialization " 75504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "failed."); 75604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 75704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 75804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_RADIUS */ 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_acl_init(hapd)) { 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "ACL initialization failed."); 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_init_wps(hapd, conf)) 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (authsrv_init(hapd) < 0) 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ieee802_1x_init(hapd)) { 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "IEEE 802.1X initialization failed."); 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->wpa && hostapd_setup_wpa(hapd)) 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (accounting_init(hapd)) { 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Accounting initialization failed."); 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ieee802_11f && 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (hapd->iapp = iapp_init(hapd, hapd->conf->iapp_iface)) == NULL) { 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "IEEE 802.11F (IAPP) initialization " 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed."); 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 79104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_INTERWORKING 79204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (gas_serv_init(hapd)) { 79304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_ERROR, "GAS server initialization failed"); 79404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return -1; 79504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 79604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 797cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (conf->qos_map_set_len && 798cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_drv_set_qos_map(hapd, conf->qos_map_set, 799cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf->qos_map_set_len)) { 800cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to initialize QoS Map"); 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 803cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#endif /* CONFIG_INTERWORKING */ 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!hostapd_drv_none(hapd) && vlan_init(hapd)) { 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "VLAN initialization failed."); 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 810fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (!hapd->conf->start_disabled && ieee802_11_set_beacon(hapd) < 0) 811fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt return -1; 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (hapd->wpa_auth && wpa_init_keys(hapd->wpa_auth) < 0) 8141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 8151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->driver && hapd->driver->set_operstate) 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->driver->set_operstate(hapd->drv_priv, 1); 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_tx_queue_params(struct hostapd_iface *iface) 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = iface->bss[0]; 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_tx_queue_params *p; 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < NUM_TX_QUEUES; i++) { 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = &iface->conf->tx_queue[i]; 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_set_tx_queue_params(hapd, i, p->aifs, p->cwmin, 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p->cwmax, p->burst)) { 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to set TX queue " 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "parameters for queue %d.", i); 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Continue anyway */ 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8428bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidtstatic int hostapd_set_acl_list(struct hostapd_data *hapd, 8438bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt struct mac_acl_entry *mac_acl, 8448bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt int n_entries, u8 accept_acl) 8458bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt{ 8468bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt struct hostapd_acl_params *acl_params; 8478bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt int i, err; 8488bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 8498bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt acl_params = os_zalloc(sizeof(*acl_params) + 8508bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt (n_entries * sizeof(acl_params->mac_acl[0]))); 8518bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt if (!acl_params) 8528bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt return -ENOMEM; 8538bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 8548bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt for (i = 0; i < n_entries; i++) 8558bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt os_memcpy(acl_params->mac_acl[i].addr, mac_acl[i].addr, 8568bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt ETH_ALEN); 8578bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 8588bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt acl_params->acl_policy = accept_acl; 8598bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt acl_params->num_mac_acl = n_entries; 8608bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 8618bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt err = hostapd_drv_set_acl(hapd, acl_params); 8628bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 8638bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt os_free(acl_params); 8648bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 8658bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt return err; 8668bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt} 8678bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 8688bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 8698bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidtstatic void hostapd_set_acl(struct hostapd_data *hapd) 8708bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt{ 8718bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt struct hostapd_config *conf = hapd->iconf; 8728bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt int err; 8738bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt u8 accept_acl; 8748bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 8758bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt if (hapd->iface->drv_max_acl_mac_addrs == 0) 8768bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt return; 877cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!(conf->bss[0]->num_accept_mac || conf->bss[0]->num_deny_mac)) 8788bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt return; 8798bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 880cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (conf->bss[0]->macaddr_acl == DENY_UNLESS_ACCEPTED) { 881cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (conf->bss[0]->num_accept_mac) { 8828bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt accept_acl = 1; 883cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt err = hostapd_set_acl_list(hapd, 884cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf->bss[0]->accept_mac, 885cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf->bss[0]->num_accept_mac, 8868bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt accept_acl); 8878bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt if (err) { 8888bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to set accept acl"); 8898bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt return; 8908bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } 8918bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } else { 8928bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt wpa_printf(MSG_DEBUG, "Mismatch between ACL Policy & Accept/deny lists file"); 8938bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } 894cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } else if (conf->bss[0]->macaddr_acl == ACCEPT_UNLESS_DENIED) { 895cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (conf->bss[0]->num_deny_mac) { 8968bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt accept_acl = 0; 897cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt err = hostapd_set_acl_list(hapd, conf->bss[0]->deny_mac, 898cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf->bss[0]->num_deny_mac, 8998bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt accept_acl); 9008bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt if (err) { 9018bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to set deny acl"); 9028bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt return; 9038bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } 9048bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } else { 9058bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt wpa_printf(MSG_DEBUG, "Mismatch between ACL Policy & Accept/deny lists file"); 9068bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } 9078bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt } 9088bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt} 9098bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 9108bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 911cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic int start_ctrl_iface_bss(struct hostapd_data *hapd) 912cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 913cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!hapd->iface->interfaces || 914cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt !hapd->iface->interfaces->ctrl_iface_init) 915cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 916cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 917cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd->iface->interfaces->ctrl_iface_init(hapd)) { 918cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, 919cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "Failed to setup control interface for %s", 920cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->conf->iface); 921cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 922cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 923cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 924cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 925cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 926cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 927cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 928cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic int start_ctrl_iface(struct hostapd_iface *iface) 929cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 930cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i; 931cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 932cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!iface->interfaces || !iface->interfaces->ctrl_iface_init) 933cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 934cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 935cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (i = 0; i < iface->num_bss; i++) { 936cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_data *hapd = iface->bss[i]; 937cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (iface->interfaces->ctrl_iface_init(hapd)) { 938cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, 939cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "Failed to setup control interface for %s", 940cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->conf->iface); 941cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 942cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 943cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 944cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 945cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 946cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 947cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 948cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 949cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic void channel_list_update_timeout(void *eloop_ctx, void *timeout_ctx) 950cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 951cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface *iface = eloop_ctx; 952cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 953cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!iface->wait_channel_update) { 954cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "Channel list update timeout, but interface was not waiting for it"); 955cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return; 956cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 957cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 958cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* 959cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * It is possible that the existing channel list is acceptable, so try 960cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * to proceed. 961cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 962cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_DEBUG, "Channel list update timeout - try to continue anyway"); 963cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt setup_interface2(iface); 964cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 965cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 966cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 967e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtvoid hostapd_channel_list_updated(struct hostapd_iface *iface, int initiator) 968cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 969e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!iface->wait_channel_update || initiator != REGDOM_SET_BY_USER) 970cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return; 971cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 972cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_DEBUG, "Channel list updated - continue setup"); 973cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt eloop_cancel_timeout(channel_list_update_timeout, iface, NULL); 974cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt setup_interface2(iface); 975cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 976cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 977cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int setup_interface(struct hostapd_iface *iface) 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = iface->bss[0]; 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 982cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 983cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!iface->phy[0]) { 984cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt const char *phy = hostapd_drv_get_radio_name(hapd); 985cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (phy) { 986cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_DEBUG, "phy: %s", phy); 987cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_strlcpy(iface->phy, phy, sizeof(iface->phy)); 988cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 989cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Make sure that all BSSes get configured with a pointer to the same 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * driver interface. 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 1; i < iface->num_bss; i++) { 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->bss[i]->driver = hapd->driver; 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->bss[i]->drv_priv = hapd->drv_priv; 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_validate_bssid_configuration(iface)) 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1003cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* 1004cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * Initialize control interfaces early to allow external monitoring of 1005cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * channel setup operations that may take considerable amount of time 1006cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * especially for DFS cases. 1007cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 1008cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (start_ctrl_iface(iface)) 1009cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 1010cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iconf->country[0] && hapd->iconf->country[1]) { 1012cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt char country[4], previous_country[4]; 1013cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1014cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_set_state(iface, HAPD_IFACE_COUNTRY_UPDATE); 1015cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hostapd_get_country(hapd, previous_country) < 0) 1016cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt previous_country[0] = '\0'; 1017cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(country, hapd->iconf->country, 3); 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt country[3] = '\0'; 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_set_country(hapd, country) < 0) { 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to set country code"); 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1024cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1025cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_DEBUG, "Previous country code %s, new country code %s", 1026cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt previous_country, country); 1027cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1028cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (os_strncmp(previous_country, country, 2) != 0) { 1029cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_DEBUG, "Continue interface setup after channel list update"); 1030cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->wait_channel_update = 1; 10319767226d8e6a1adaa33beb9f517ef40dddfa460cDmitry Shmidt eloop_register_timeout(5, 0, 1032cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt channel_list_update_timeout, 1033cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface, NULL); 1034cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 1035cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1038cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return setup_interface2(iface); 1039cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 1040cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1041cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1042cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic int setup_interface2(struct hostapd_iface *iface) 1043cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 1044cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->wait_channel_update = 0; 1045cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_get_hw_features(iface)) { 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Not all drivers support this yet, so continue without hw 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * feature data. */ 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = hostapd_select_hw_mode(iface); 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) { 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not select hw_mode and " 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "channel. (%d)", ret); 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1056391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt if (ret == 1) { 1057391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt wpa_printf(MSG_DEBUG, "Interface initialization will be completed in a callback (ACS)"); 1058391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt return 0; 1059391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt } 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = hostapd_check_ht_capab(iface); 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret == 1) { 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Interface initialization will " 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "be completed in a callback"); 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1068051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1069051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (iface->conf->ieee80211h) 1070051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt wpa_printf(MSG_DEBUG, "DFS support is enabled"); 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return hostapd_setup_interface_complete(iface, 0); 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1076cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt/** 1077cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_setup_interface_complete - Complete interface setup 1078cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * 1079cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * This function is called when previous steps in the interface setup has been 1080cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * completed. This can also start operations, e.g., DFS, that will require 1081cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * additional processing before interface is ready to be enabled. Such 1082cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * operations will call this function from eloop callbacks when finished. 1083cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_setup_interface_complete(struct hostapd_iface *iface, int err) 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = iface->bss[0]; 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t j; 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *prev_addr; 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (err) { 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Interface initialization failed"); 1092cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_set_state(iface, HAPD_IFACE_DISABLED); 1093b96dad47218788efffa3db0fe7f1b54a7d19e366Dmitry Shmidt if (iface->interfaces && iface->interfaces->terminate_on_error) 1094b96dad47218788efffa3db0fe7f1b54a7d19e366Dmitry Shmidt eloop_terminate(); 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Completing interface initialization"); 1099cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (iface->conf->channel) { 1100051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#ifdef NEED_AP_MLME 1101051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt int res; 1102051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#endif /* NEED_AP_MLME */ 1103051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 1104cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->freq = hostapd_hw_get_freq(hapd, iface->conf->channel); 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Mode: %s Channel: %d " 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Frequency: %d MHz", 1107cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_hw_mode_txt(iface->conf->hw_mode), 1108cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->channel, iface->freq); 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1110051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#ifdef NEED_AP_MLME 1111051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt /* Check DFS */ 1112cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt res = hostapd_handle_dfs(iface); 1113051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (res <= 0) 1114051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt return res; 1115051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt#endif /* NEED_AP_MLME */ 1116051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_set_freq(hapd, hapd->iconf->hw_mode, iface->freq, 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iconf->channel, 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iconf->ieee80211n, 1120a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hapd->iconf->ieee80211ac, 1121a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hapd->iconf->secondary_channel, 1122a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hapd->iconf->vht_oper_chwidth, 1123a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hapd->iconf->vht_oper_centr_freq_seg0_idx, 1124a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt hapd->iconf->vht_oper_centr_freq_seg1_idx)) { 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not set channel for " 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "kernel driver"); 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface->current_mode) { 11321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (hostapd_prepare_rates(iface, iface->current_mode)) { 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to prepare rates " 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "table."); 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HOSTAPD_LEVEL_WARNING, 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Failed to prepare rates table."); 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iconf->rts_threshold > -1 && 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_rts(hapd, hapd->iconf->rts_threshold)) { 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not set RTS threshold for " 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "kernel driver"); 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->iconf->fragm_threshold > -1 && 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_set_frag(hapd, hapd->iconf->fragm_threshold)) { 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Could not set fragmentation threshold " 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for kernel driver"); 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev_addr = hapd->own_addr; 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd = iface->bss[j]; 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (j) 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN); 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_setup_bss(hapd, j == 0)) 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0) 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev_addr = hapd->own_addr; 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1167cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd = iface->bss[0]; 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_tx_queue_params(iface); 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ap_list_init(iface); 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11738bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt hostapd_set_acl(hapd); 11748bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_driver_commit(hapd) < 0) { 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Failed to commit driver " 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "configuration", __func__); 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118187fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen /* 118287fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen * WPS UPnP module can be initialized only when the "upnp_iface" is up. 118387fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen * If "interface" and "upnp_iface" are the same (e.g., non-bridge 118487fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen * mode), the interface is up only after driver_commit, so initialize 118587fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen * WPS after driver_commit. 118687fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen */ 118787fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen for (j = 0; j < iface->num_bss; j++) { 118887fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen if (hostapd_init_wps_complete(iface->bss[j])) 118987fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen return -1; 119087fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen } 119187fd279308af3f806848c8f2ab65ef18c6ac4c30Jouni Malinen 1192cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_set_state(iface, HAPD_IFACE_ENABLED); 1193cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_ENABLED); 11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->setup_complete_cb) 11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->setup_complete_cb(hapd->setup_complete_cb_ctx); 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: Setup of interface done.", 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->bss[0]->conf->iface); 1199b96dad47218788efffa3db0fe7f1b54a7d19e366Dmitry Shmidt if (iface->interfaces && iface->interfaces->terminate_on_error > 0) 1200b96dad47218788efffa3db0fe7f1b54a7d19e366Dmitry Shmidt iface->interfaces->terminate_on_error--; 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_setup_interface - Setup of an interface 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @iface: Pointer to interface data. 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Initializes the driver interface, validates the configuration, 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * and sets driver parameters based on the configuration. 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Flushes old stations, sets the channel, encryption, 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * beacons, and WDS links based on the configuration. 1215cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * 1216cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * If interface setup requires more time, e.g., to perform HT co-ex scans, ACS, 1217cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * or DFS operations, this function returns 0 before such operations have been 1218cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * completed. The pending operations are registered into eloop and will be 1219cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * completed from eloop callbacks. Those callbacks end up calling 1220cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_setup_interface_complete() once setup has been completed. 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_setup_interface(struct hostapd_iface *iface) 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = setup_interface(iface); 12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) { 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Unable to setup interface.", 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->bss[0]->conf->iface); 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_alloc_bss_data - Allocate and initialize per-BSS data 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hapd_iface: Pointer to interface data 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conf: Pointer to per-interface configuration 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @bss: Pointer to per-BSS configuration for this BSS 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to allocated BSS data 12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to allocate per-BSS data structure. This data will be 12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * freed after hostapd_cleanup() is called for it during interface 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * deinitialization. 12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct hostapd_data * 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidthostapd_alloc_bss_data(struct hostapd_iface *hapd_iface, 12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_config *conf, 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_bss_config *bss) 12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd; 12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd = os_zalloc(sizeof(*hapd)); 12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd == NULL) 12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->new_assoc_sta_cb = hostapd_new_assoc_sta; 12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iconf = conf; 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf = bss; 12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->iface = hapd_iface; 12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->driver = hapd->iconf->driver; 126404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hapd->ctrl_sock = -1; 12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return hapd; 12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12705460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidtstatic void hostapd_bss_deinit(struct hostapd_data *hapd) 12715460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt{ 12725460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: deinit bss %s", __func__, 12735460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd->conf->iface); 12745460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_free_stas(hapd); 12755460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING); 12765460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_clear_wep(hapd); 12775460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_cleanup(hapd); 12785460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt} 12795460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 12805460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid hostapd_interface_deinit(struct hostapd_iface *iface) 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1283cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt int j; 12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12855460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface == NULL) 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1289cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt eloop_cancel_timeout(channel_list_update_timeout, iface, NULL); 1290cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->wait_channel_update = 0; 1291cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 12925460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt for (j = iface->num_bss - 1; j >= 0; j--) 12935460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_bss_deinit(iface->bss[j]); 12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid hostapd_interface_free(struct hostapd_iface *iface) 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t j; 13005460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); 13015460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 13025460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: free hapd %p", 13035460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, iface->bss[j]); 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(iface->bss[j]); 13055460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt } 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_cleanup_iface(iface); 13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1310cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt/** 1311cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_init - Allocate and initialize per-interface data 1312cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * @config_file: Path to the configuration file 1313cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * Returns: Pointer to the allocated interface data or %NULL on failure 1314cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * 1315cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * This function is used to allocate main data structures for per-interface 1316cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * data. The allocated data buffer will be freed by calling 1317cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_cleanup_iface(). 1318cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 1319cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstruct hostapd_iface * hostapd_init(struct hapd_interfaces *interfaces, 1320cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt const char *config_file) 1321cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 1322cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface *hapd_iface = NULL; 1323cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_config *conf = NULL; 1324cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_data *hapd; 1325cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i; 1326cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1327cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface = os_zalloc(sizeof(*hapd_iface)); 1328cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd_iface == NULL) 1329cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto fail; 1330cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1331cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->config_fname = os_strdup(config_file); 1332cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd_iface->config_fname == NULL) 1333cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto fail; 1334cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1335cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf = interfaces->config_read_cb(hapd_iface->config_fname); 1336cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (conf == NULL) 1337cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto fail; 1338cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->conf = conf; 1339cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1340cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->num_bss = conf->num_bss; 1341cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->bss = os_calloc(conf->num_bss, 1342cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt sizeof(struct hostapd_data *)); 1343cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd_iface->bss == NULL) 1344cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto fail; 1345cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1346cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (i = 0; i < conf->num_bss; i++) { 1347cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd = hapd_iface->bss[i] = 1348cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_alloc_bss_data(hapd_iface, conf, 1349cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf->bss[i]); 1350cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd == NULL) 1351cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto fail; 1352cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->msg_ctx = hapd; 1353cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1354cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1355cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return hapd_iface; 1356cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1357cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtfail: 1358cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to set up interface with %s", 1359cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt config_file); 1360cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (conf) 1361cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_config_free(conf); 1362cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd_iface) { 1363cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_free(hapd_iface->config_fname); 1364cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_free(hapd_iface->bss); 13655460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: free iface %p", 13665460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, hapd_iface); 1367cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_free(hapd_iface); 1368cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1369cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1370cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 1371cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1372cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1373cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic int ifname_in_use(struct hapd_interfaces *interfaces, const char *ifname) 1374cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 1375cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i, j; 1376cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1377cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (i = 0; i < interfaces->count; i++) { 1378cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface *iface = interfaces->iface[i]; 1379cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (j = 0; j < iface->num_bss; j++) { 1380cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_data *hapd = iface->bss[j]; 1381cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (os_strcmp(ifname, hapd->conf->iface) == 0) 1382cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 1; 1383cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1384cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1385cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1386cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 1387cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 1388cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1389cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1390cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt/** 1391cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_interface_init_bss - Read configuration file and init BSS data 1392cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * 1393cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * This function is used to parse configuration file for a BSS. This BSS is 1394cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * added to an existing interface sharing the same radio (if any) or a new 1395cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * interface is created if this is the first interface on a radio. This 1396cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * allocate memory for the BSS. No actual driver operations are started. 1397cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * 1398cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * This is similar to hostapd_interface_init(), but for a case where the 1399cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * configuration is used to add a single BSS instead of all BSSes for a radio. 1400cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 1401cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstruct hostapd_iface * 1402cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidthostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy, 1403cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt const char *config_fname, int debug) 1404cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 1405cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface *new_iface = NULL, *iface = NULL; 1406cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_data *hapd; 1407cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt int k; 1408cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i, bss_idx; 1409cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1410cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!phy || !*phy) 1411cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1412cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1413cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (i = 0; i < interfaces->count; i++) { 1414cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (os_strcmp(interfaces->iface[i]->phy, phy) == 0) { 1415cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface = interfaces->iface[i]; 1416cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt break; 1417cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1418cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1419cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1420cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "Configuration file: %s (phy %s)%s", 1421cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt config_fname, phy, iface ? "" : " --> new PHY"); 1422cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (iface) { 1423cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_config *conf; 1424cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_bss_config **tmp_conf; 1425cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_data **tmp_bss; 1426cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_bss_config *bss; 1427cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt const char *ifname; 1428cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1429cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* Add new BSS to existing iface */ 1430cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf = interfaces->config_read_cb(config_fname); 1431cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (conf == NULL) 1432cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1433cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (conf->num_bss > 1) { 1434cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "Multiple BSSes specified in BSS-config"); 1435cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_config_free(conf); 1436cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1437cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1438cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1439cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt ifname = conf->bss[0]->iface; 1440cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (ifname[0] != '\0' && ifname_in_use(interfaces, ifname)) { 1441cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, 1442cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "Interface name %s already in use", ifname); 1443cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_config_free(conf); 1444cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1445cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1446cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1447cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt tmp_conf = os_realloc_array( 1448cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->bss, iface->conf->num_bss + 1, 1449cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt sizeof(struct hostapd_bss_config *)); 1450cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt tmp_bss = os_realloc_array(iface->bss, iface->num_bss + 1, 1451cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt sizeof(struct hostapd_data *)); 1452cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (tmp_bss) 1453cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->bss = tmp_bss; 1454cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (tmp_conf) { 1455cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->bss = tmp_conf; 1456cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->last_bss = tmp_conf[0]; 1457cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1458cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (tmp_bss == NULL || tmp_conf == NULL) { 1459cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_config_free(conf); 1460cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1461cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1462cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt bss = iface->conf->bss[iface->conf->num_bss] = conf->bss[0]; 1463cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->num_bss++; 1464cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1465cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd = hostapd_alloc_bss_data(iface, iface->conf, bss); 1466cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd == NULL) { 1467cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->num_bss--; 1468cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_config_free(conf); 1469cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1470cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1471cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->last_bss = bss; 1472cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->bss[iface->num_bss] = hapd; 1473cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->msg_ctx = hapd; 1474cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1475cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt bss_idx = iface->num_bss++; 1476cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf->num_bss--; 1477cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf->bss[0] = NULL; 1478cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_config_free(conf); 1479cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } else { 1480cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* Add a new iface with the first BSS */ 1481cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt new_iface = iface = hostapd_init(interfaces, config_fname); 1482cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!iface) 1483cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1484cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_strlcpy(iface->phy, phy, sizeof(iface->phy)); 1485cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->interfaces = interfaces; 1486cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt bss_idx = 0; 1487cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1488cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1489cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (k = 0; k < debug; k++) { 1490cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (iface->bss[bss_idx]->conf->logger_stdout_level > 0) 1491cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->bss[bss_idx]->conf->logger_stdout_level--; 1492cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1493cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1494cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (iface->conf->bss[bss_idx]->iface[0] == '\0' && 1495cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt !hostapd_drv_none(iface->bss[bss_idx])) { 1496cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "Interface name not specified in %s", 1497cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt config_fname); 1498cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (new_iface) 1499cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_interface_deinit_free(new_iface); 1500cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return NULL; 1501cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1502cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1503cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return iface; 1504cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 1505cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 150661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 150761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid hostapd_interface_deinit_free(struct hostapd_iface *iface) 150861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 150961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const struct wpa_driver_ops *driver; 151061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt void *drv_priv; 15115460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 15125460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface); 151361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (iface == NULL) 151461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 15155460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: num_bss=%u conf->num_bss=%u", 15165460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, (unsigned int) iface->num_bss, 15175460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt (unsigned int) iface->conf->num_bss); 151861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt driver = iface->bss[0]->driver; 151961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt drv_priv = iface->bss[0]->drv_priv; 152061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_interface_deinit(iface); 15215460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", 15225460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, driver, drv_priv); 152361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (driver && driver->hapd_deinit && drv_priv) 152461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt driver->hapd_deinit(drv_priv); 152561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_interface_free(iface); 152661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 152761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 152861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 152961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint hostapd_enable_iface(struct hostapd_iface *hapd_iface) 153061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 153161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface->bss[0]->drv_priv != NULL) { 153261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "Interface %s already enabled", 1533cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->conf->bss[0]->iface); 153461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 153561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 153661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 153761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "Enable interface %s", 1538cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->conf->bss[0]->iface); 153961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1540344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt if (hostapd_config_check(hapd_iface->conf, 1) < 0) { 1541344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt wpa_printf(MSG_INFO, "Invalid configuration - cannot enable"); 1542344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt return -1; 1543344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt } 1544344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt 154561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface->interfaces == NULL || 154661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface->interfaces->driver_init == NULL || 1547cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->interfaces->driver_init(hapd_iface)) 1548cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 1549cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1550cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hostapd_setup_interface(hapd_iface)) { 1551cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt const struct wpa_driver_ops *driver; 1552cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt void *drv_priv; 1553cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1554cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt driver = hapd_iface->bss[0]->driver; 1555cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt drv_priv = hapd_iface->bss[0]->drv_priv; 15565460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", 15575460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, driver, drv_priv); 1558cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (driver && driver->hapd_deinit && drv_priv) { 1559cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt driver->hapd_deinit(drv_priv); 1560cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->bss[0]->drv_priv = NULL; 1561cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 156261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 156361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 1564cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 156561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 156661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 156761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 156861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 156961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint hostapd_reload_iface(struct hostapd_iface *hapd_iface) 157061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 157161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t j; 157261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 157361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_DEBUG, "Reload interface %s", 1574cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->conf->bss[0]->iface); 1575cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (j = 0; j < hapd_iface->num_bss; j++) 1576cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_set_security_params(hapd_iface->conf->bss[j]); 1577344abd362cfe2d03ed956666527352826b67bde5Dmitry Shmidt if (hostapd_config_check(hapd_iface->conf, 1) < 0) { 1578cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "Updated configuration is invalid"); 1579cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 158061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 1581cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_clear_old(hapd_iface); 1582cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (j = 0; j < hapd_iface->num_bss; j++) 1583cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_reload_bss(hapd_iface->bss[j]); 1584cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 158561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 158661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 158761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 158861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 158961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint hostapd_disable_iface(struct hostapd_iface *hapd_iface) 159061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 159161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t j; 159261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const struct wpa_driver_ops *driver; 159361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt void *drv_priv; 159461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 159561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface == NULL) 159661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 1597cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_msg(hapd_iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_DISABLED); 159861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt driver = hapd_iface->bss[0]->driver; 159961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt drv_priv = hapd_iface->bss[0]->drv_priv; 160061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 160161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* whatever hostapd_interface_deinit does */ 160261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (j = 0; j < hapd_iface->num_bss; j++) { 160361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_data *hapd = hapd_iface->bss[j]; 160461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_free_stas(hapd); 160561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING); 160661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_clear_wep(hapd); 160761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_free_hapd_data(hapd); 160861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 160961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 16105460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", 16115460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, driver, drv_priv); 161261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (driver && driver->hapd_deinit && drv_priv) { 161361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt driver->hapd_deinit(drv_priv); 161461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface->bss[0]->drv_priv = NULL; 161561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 161661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 161761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* From hostapd_cleanup_iface: These were initialized in 161861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * hostapd_setup_interface and hostapd_setup_interface_complete 161961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 162061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_cleanup_iface_partial(hapd_iface); 162161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 16225605286c30e1701491bd3af974ae423727750eddDmitry Shmidt wpa_printf(MSG_DEBUG, "Interface %s disabled", 16235605286c30e1701491bd3af974ae423727750eddDmitry Shmidt hapd_iface->bss[0]->conf->iface); 1624cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_set_state(hapd_iface, HAPD_IFACE_DISABLED); 162561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 162661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 162761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 162861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 162961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic struct hostapd_iface * 163061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidthostapd_iface_alloc(struct hapd_interfaces *interfaces) 163161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 163261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_iface **iface, *hapd_iface; 163361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 163461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt iface = os_realloc_array(interfaces->iface, interfaces->count + 1, 163561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sizeof(struct hostapd_iface *)); 163661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (iface == NULL) 163761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 163861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->iface = iface; 163961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface = interfaces->iface[interfaces->count] = 164061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_zalloc(sizeof(*hapd_iface)); 164161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface == NULL) { 164261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Failed to allocate memory for " 164361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "the interface", __func__); 164461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 164561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 164661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->count++; 164761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface->interfaces = interfaces; 164861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 164961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return hapd_iface; 165061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 165161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 165261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 165361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic struct hostapd_config * 165461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidthostapd_config_alloc(struct hapd_interfaces *interfaces, const char *ifname, 165561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const char *ctrl_iface) 165661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 165761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_bss_config *bss; 165861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_config *conf; 165961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 166061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Allocates memory for bss and conf */ 166161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt conf = hostapd_config_defaults(); 166261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (conf == NULL) { 166361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Failed to allocate memory for " 166461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "configuration", __func__); 166561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 166661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 166761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 166861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt conf->driver = wpa_drivers[0]; 166961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (conf->driver == NULL) { 167061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "No driver wrappers registered!"); 167161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_config_free(conf); 167261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 167361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 167461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1675cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt bss = conf->last_bss = conf->bss[0]; 167661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 167761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_strlcpy(bss->iface, ifname, sizeof(bss->iface)); 167861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt bss->ctrl_interface = os_strdup(ctrl_iface); 167961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (bss->ctrl_interface == NULL) { 168061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_config_free(conf); 168161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 168261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 168361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 168461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Reading configuration file skipped, will be done in SET! 168561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * From reading the configuration till the end has to be done in 168661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * SET 168761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 168861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return conf; 168961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 169061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 169161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 169261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic struct hostapd_iface * hostapd_data_alloc( 169361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hapd_interfaces *interfaces, struct hostapd_config *conf) 169461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 169561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt size_t i; 169661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_iface *hapd_iface = 169761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->iface[interfaces->count - 1]; 169861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_data *hapd; 169961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 170061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface->conf = conf; 170161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface->num_bss = conf->num_bss; 170261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 170361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface->bss = os_zalloc(conf->num_bss * 170461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sizeof(struct hostapd_data *)); 170561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface->bss == NULL) 170661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 170761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 170861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (i = 0; i < conf->num_bss; i++) { 170961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd = hapd_iface->bss[i] = 1710cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_alloc_bss_data(hapd_iface, conf, conf->bss[i]); 171161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd == NULL) 171261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return NULL; 171361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd->msg_ctx = hapd; 171461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 171561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 171661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface->interfaces = interfaces; 171761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 171861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return hapd_iface; 171961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 172061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 172161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 172261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint hostapd_add_iface(struct hapd_interfaces *interfaces, char *buf) 172361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 172461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_config *conf = NULL; 1725cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface *hapd_iface = NULL, *new_iface = NULL; 1726cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_data *hapd; 172761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char *ptr; 1728cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i, j; 1729cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt const char *conf_file = NULL, *phy_name = NULL; 1730cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1731cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (os_strncmp(buf, "bss_config=", 11) == 0) { 1732cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt char *pos; 1733cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt phy_name = buf + 11; 1734cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt pos = os_strchr(phy_name, ':'); 1735cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!pos) 1736cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 1737cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt *pos++ = '\0'; 1738cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf_file = pos; 1739cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!os_strlen(conf_file)) 1740cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 1741cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1742cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface = hostapd_interface_init_bss(interfaces, phy_name, 1743cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt conf_file, 0); 1744cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!hapd_iface) 1745cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 1746cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (j = 0; j < interfaces->count; j++) { 1747cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (interfaces->iface[j] == hapd_iface) 1748cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt break; 1749cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1750cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (j == interfaces->count) { 1751cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface **tmp; 1752cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt tmp = os_realloc_array(interfaces->iface, 1753cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt interfaces->count + 1, 1754cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt sizeof(struct hostapd_iface *)); 1755cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!tmp) { 1756cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_interface_deinit_free(hapd_iface); 1757cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 1758cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1759cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt interfaces->iface = tmp; 1760cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt interfaces->iface[interfaces->count++] = hapd_iface; 1761cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt new_iface = hapd_iface; 1762cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1763cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1764cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (new_iface) { 1765cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (interfaces->driver_init(hapd_iface) || 1766cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_setup_interface(hapd_iface)) { 1767cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt interfaces->count--; 1768cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto fail; 1769cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1770cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } else { 1771cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* Assign new BSS with bss[0]'s driver info */ 1772cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd = hapd_iface->bss[hapd_iface->num_bss - 1]; 1773cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->driver = hapd_iface->bss[0]->driver; 1774cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->drv_priv = hapd_iface->bss[0]->drv_priv; 1775cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_memcpy(hapd->own_addr, hapd_iface->bss[0]->own_addr, 1776cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt ETH_ALEN); 1777cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1778cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (start_ctrl_iface_bss(hapd) < 0 || 17795460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt (hapd_iface->state == HAPD_IFACE_ENABLED && 17805460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_setup_bss(hapd, -1))) { 1781cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->conf->num_bss--; 1782cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd_iface->num_bss--; 17835460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: free hapd %p %s", 17845460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, hapd, hapd->conf->iface); 1785cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_free(hapd); 1786cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 1787cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1788cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 1789cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 1790cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 179161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 179261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ptr = os_strchr(buf, ' '); 179361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (ptr == NULL) 179461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 179561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *ptr++ = '\0'; 179661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 17975605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (os_strncmp(ptr, "config=", 7) == 0) 17985605286c30e1701491bd3af974ae423727750eddDmitry Shmidt conf_file = ptr + 7; 17995605286c30e1701491bd3af974ae423727750eddDmitry Shmidt 180061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (i = 0; i < interfaces->count; i++) { 1801cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!os_strcmp(interfaces->iface[i]->conf->bss[0]->iface, 180261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt buf)) { 180361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_INFO, "Cannot add interface - it " 180461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "already exists"); 180561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 180661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 180761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 180861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 180961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface = hostapd_iface_alloc(interfaces); 181061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface == NULL) { 181161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Failed to allocate memory " 181261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "for interface", __func__); 181361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt goto fail; 181461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 181561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 18165605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (conf_file && interfaces->config_read_cb) { 18175605286c30e1701491bd3af974ae423727750eddDmitry Shmidt conf = interfaces->config_read_cb(conf_file); 18185605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (conf && conf->bss) 1819cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_strlcpy(conf->bss[0]->iface, buf, 1820cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt sizeof(conf->bss[0]->iface)); 18215605286c30e1701491bd3af974ae423727750eddDmitry Shmidt } else 18225605286c30e1701491bd3af974ae423727750eddDmitry Shmidt conf = hostapd_config_alloc(interfaces, buf, ptr); 18235605286c30e1701491bd3af974ae423727750eddDmitry Shmidt if (conf == NULL || conf->bss == NULL) { 182461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Failed to allocate memory " 182561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "for configuration", __func__); 182661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt goto fail; 182761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 182861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 182961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface = hostapd_data_alloc(interfaces, conf); 183061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface == NULL) { 183161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Failed to allocate memory " 183261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "for hostapd", __func__); 183361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt goto fail; 183461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 183561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1836cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (start_ctrl_iface(hapd_iface) < 0) 183761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt goto fail; 1838cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1839cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "Add interface '%s'", conf->bss[0]->iface); 184061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 184161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 184261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 184361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtfail: 184461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (conf) 184561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_config_free(conf); 184661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface) { 1847cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd_iface->bss) { 18485460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt for (i = 0; i < hapd_iface->num_bss; i++) { 18495460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd = hapd_iface->bss[i]; 18505460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt if (hapd && hapd_iface->interfaces && 18515460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd_iface->interfaces->ctrl_iface_deinit) 18525460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd_iface->interfaces-> 18535460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt ctrl_iface_deinit(hapd); 18545460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: free hapd %p (%s)", 18555460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, hapd_iface->bss[i], 18565460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hapd_iface->bss[i]->conf->iface); 1857cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_free(hapd_iface->bss[i]); 18585460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt } 1859cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_free(hapd_iface->bss); 1860cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 18615460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: free iface %p", 18625460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, hapd_iface); 186361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(hapd_iface); 186461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 186561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 186661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 186761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 186861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 1869cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtstatic int hostapd_remove_bss(struct hostapd_iface *iface, unsigned int idx) 1870cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 1871cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i; 1872cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 18735460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_INFO, "Remove BSS '%s'", iface->conf->bss[idx]->iface); 1874cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 18755460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt /* Remove hostapd_data only if it has already been initialized */ 18765460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt if (idx < iface->num_bss) { 18775460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt struct hostapd_data *hapd = iface->bss[idx]; 1878cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 18795460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_bss_deinit(hapd); 18805460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: free hapd %p (%s)", 18815460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt __func__, hapd, hapd->conf->iface); 18825460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_config_free_bss(hapd->conf); 18835460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt os_free(hapd); 18845460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 18855460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt iface->num_bss--; 18865460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt 18875460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt for (i = idx; i < iface->num_bss; i++) 18885460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt iface->bss[i] = iface->bss[i + 1]; 18895460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt } else { 18905460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt hostapd_config_free_bss(iface->conf->bss[idx]); 18915460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt iface->conf->bss[idx] = NULL; 18925460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt } 1893cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1894cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->num_bss--; 18955460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt for (i = idx; i < iface->conf->num_bss; i++) 1896cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->bss[i] = iface->conf->bss[i + 1]; 1897cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1898cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return 0; 1899cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 1900cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1901cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 190261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint hostapd_remove_iface(struct hapd_interfaces *interfaces, char *buf) 190361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 190461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_iface *hapd_iface; 1905cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i, j, k = 0; 190661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 190761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (i = 0; i < interfaces->count; i++) { 190861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface = interfaces->iface[i]; 190961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hapd_iface == NULL) 191061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 19115460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt if (!os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) { 191261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_INFO, "Remove interface '%s'", buf); 191361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_interface_deinit_free(hapd_iface); 191461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt k = i; 191561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt while (k < (interfaces->count - 1)) { 191661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->iface[k] = 191761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->iface[k + 1]; 191861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt k++; 191961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 192061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->count--; 192161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 192261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 1923cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1924cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (j = 0; j < hapd_iface->conf->num_bss; j++) { 1925cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (!os_strcmp(hapd_iface->conf->bss[j]->iface, buf)) 1926cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return hostapd_remove_bss(hapd_iface, j); 1927cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 192861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 192961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 193061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 193161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 193261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_new_assoc_sta - Notify that a new station associated with the AP 19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hapd: Pointer to BSS data 19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sta: Pointer to the associated STA data 19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @reassoc: 1 to indicate this was a re-association; 0 = first association 19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function will be called whenever a station associates with the AP. It 19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * can be called from ieee802_11.c for drivers that export MLME to hostapd and 19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * from drv_callbacks.c based on driver events for drivers that take care of 19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * management frames (IEEE 802.11 authentication and association) internally. 19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 19448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta, 19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int reassoc) 19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->tkip_countermeasures) { 19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_drv_sta_deauth(hapd, sta->addr, 19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_REASON_MICHAEL_MIC_FAILURE); 19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_prune_associations(hapd, sta->addr); 19548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* IEEE 802.11F (IAPP) */ 19568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->conf->ieee802_11f) 19578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iapp_new_station(hapd->iapp, sta); 19588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P 19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->p2p_ie == NULL && !sta->no_p2p_set) { 19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sta->no_p2p_set = 1; 19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->num_sta_no_p2p++; 19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->num_sta_no_p2p == 1) 19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_p2p_non_p2p_sta_connected(hapd); 19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */ 19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Start accounting here, if IEEE 802.1X and WPA are not used. 19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * IEEE 802.1X/WPA code will start accounting after the station has 19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * been authorized. */ 1971d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (!hapd->conf->ieee802_1x && !hapd->conf->wpa) { 197204f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt os_get_reltime(&sta->connected_time); 19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt accounting_sta_start(hapd, sta); 1974d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Start IEEE 802.1X authentication process for new stations */ 19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_1x_new_station(hapd, sta); 19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reassoc) { 19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sta->auth_alg != WLAN_AUTH_FT && 19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !(sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS))) 19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH); 19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm); 198404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 198501904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_INACTIVITY_TIMER)) { 198601904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: reschedule ap_handle_timer timeout " 198701904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt "for " MACSTR " (%d seconds - ap_max_inactivity)", 198801904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt __func__, MAC2STR(sta->addr), 198901904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt hapd->conf->ap_max_inactivity); 199001904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt eloop_cancel_timeout(ap_handle_timer, hapd, sta); 199101904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt eloop_register_timeout(hapd->conf->ap_max_inactivity, 0, 199201904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt ap_handle_timer, hapd, sta); 199301904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt } 19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1995cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1996cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 1997cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtconst char * hostapd_state_text(enum hostapd_iface_state s) 1998cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 1999cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt switch (s) { 2000cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_UNINITIALIZED: 2001cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "UNINITIALIZED"; 2002cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_DISABLED: 2003cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "DISABLED"; 2004cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_COUNTRY_UPDATE: 2005cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "COUNTRY_UPDATE"; 2006cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_ACS: 2007cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "ACS"; 2008cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_HT_SCAN: 2009cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "HT_SCAN"; 2010cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_DFS: 2011cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "DFS"; 2012cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case HAPD_IFACE_ENABLED: 2013cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "ENABLED"; 2014cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 2015cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2016cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return "UNKNOWN"; 2017cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 2018cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2019cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 2020cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtvoid hostapd_set_state(struct hostapd_iface *iface, enum hostapd_iface_state s) 2021cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt{ 2022cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "%s: interface state %s->%s", 2023cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->conf->bss[0]->iface, hostapd_state_text(iface->state), 2024cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_state_text(s)); 2025cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface->state = s; 2026cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt} 2027e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2028e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2029e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt#ifdef NEED_AP_MLME 2030e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2031e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtstatic void free_beacon_data(struct beacon_data *beacon) 2032e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 2033e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_free(beacon->head); 2034e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->head = NULL; 2035e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_free(beacon->tail); 2036e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->tail = NULL; 2037e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_free(beacon->probe_resp); 2038e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->probe_resp = NULL; 2039e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_free(beacon->beacon_ies); 2040e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->beacon_ies = NULL; 2041e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_free(beacon->proberesp_ies); 2042e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->proberesp_ies = NULL; 2043e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_free(beacon->assocresp_ies); 2044e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->assocresp_ies = NULL; 2045e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 2046e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2047e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2048e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtstatic int hostapd_build_beacon_data(struct hostapd_iface *iface, 2049e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct beacon_data *beacon) 2050e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 2051e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct wpabuf *beacon_extra, *proberesp_extra, *assocresp_extra; 2052e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct wpa_driver_ap_params params; 2053e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt int ret; 2054e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct hostapd_data *hapd = iface->bss[0]; 2055e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 205601904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt os_memset(beacon, 0, sizeof(*beacon)); 2057e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = ieee802_11_build_ap_params(hapd, ¶ms); 2058e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret < 0) 2059e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 2060e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2061e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = hostapd_build_ap_extra_ies(hapd, &beacon_extra, 2062e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &proberesp_extra, 2063e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &assocresp_extra); 2064e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) 2065e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_ap_params; 2066e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2067e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = -1; 2068e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->head = os_malloc(params.head_len); 2069e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!beacon->head) 2070e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_ap_extra_ies; 2071e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2072e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memcpy(beacon->head, params.head, params.head_len); 2073e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->head_len = params.head_len; 2074e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2075e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->tail = os_malloc(params.tail_len); 2076e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!beacon->tail) 2077e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_beacon; 2078e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2079e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memcpy(beacon->tail, params.tail, params.tail_len); 2080e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->tail_len = params.tail_len; 2081e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2082e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (params.proberesp != NULL) { 2083e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->probe_resp = os_malloc(params.proberesp_len); 2084e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!beacon->probe_resp) 2085e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_beacon; 2086e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2087e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memcpy(beacon->probe_resp, params.proberesp, 2088e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt params.proberesp_len); 2089e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->probe_resp_len = params.proberesp_len; 2090e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2091e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2092e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* copy the extra ies */ 2093e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (beacon_extra) { 2094e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->beacon_ies = os_malloc(wpabuf_len(beacon_extra)); 2095e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!beacon->beacon_ies) 2096e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_beacon; 2097e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2098e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memcpy(beacon->beacon_ies, 2099e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon_extra->buf, wpabuf_len(beacon_extra)); 2100e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->beacon_ies_len = wpabuf_len(beacon_extra); 2101e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2102e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2103e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (proberesp_extra) { 2104e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->proberesp_ies = 2105e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_malloc(wpabuf_len(proberesp_extra)); 2106e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!beacon->proberesp_ies) 2107e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_beacon; 2108e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2109e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memcpy(beacon->proberesp_ies, proberesp_extra->buf, 2110e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt wpabuf_len(proberesp_extra)); 2111e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->proberesp_ies_len = wpabuf_len(proberesp_extra); 2112e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2113e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2114e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (assocresp_extra) { 2115e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->assocresp_ies = 2116e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_malloc(wpabuf_len(assocresp_extra)); 2117e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!beacon->assocresp_ies) 2118e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt goto free_beacon; 2119e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2120e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memcpy(beacon->assocresp_ies, assocresp_extra->buf, 2121e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt wpabuf_len(assocresp_extra)); 2122e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt beacon->assocresp_ies_len = wpabuf_len(assocresp_extra); 2123e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2124e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2125e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = 0; 2126e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtfree_beacon: 2127e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* if the function fails, the caller should not free beacon data */ 2128e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) 2129e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt free_beacon_data(beacon); 2130e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2131e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtfree_ap_extra_ies: 2132e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt hostapd_free_ap_extra_ies(hapd, beacon_extra, proberesp_extra, 2133e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt assocresp_extra); 2134e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtfree_ap_params: 2135e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ieee802_11_free_ap_params(¶ms); 2136e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 2137e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 2138e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2139e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2140e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt/* 2141e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt * TODO: This flow currently supports only changing frequency within the 2142e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt * same hw_mode. Any other changes to MAC parameters or provided settings (even 2143e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt * width) are not supported. 2144e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt */ 2145e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtstatic int hostapd_change_config_freq(struct hostapd_data *hapd, 2146e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct hostapd_config *conf, 2147e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct hostapd_freq_params *params, 2148e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct hostapd_freq_params *old_params) 2149e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 2150e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt int channel; 2151e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2152e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!params->channel) { 2153e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* check if the new channel is supported by hw */ 2154e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt channel = hostapd_hw_get_channel(hapd, params->freq); 2155e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!channel) 2156e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return -1; 2157e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } else { 2158e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt channel = params->channel; 2159e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2160e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2161e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* if a pointer to old_params is provided we save previous state */ 2162e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (old_params) { 2163e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt old_params->channel = conf->channel; 2164e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt old_params->ht_enabled = conf->ieee80211n; 2165e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt old_params->sec_channel_offset = conf->secondary_channel; 2166e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2167e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2168e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt conf->channel = channel; 2169e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt conf->ieee80211n = params->ht_enabled; 2170e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt conf->secondary_channel = params->sec_channel_offset; 2171e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2172e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* TODO: maybe call here hostapd_config_check here? */ 2173e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2174e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return 0; 2175e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 2176e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2177e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2178e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtstatic int hostapd_fill_csa_settings(struct hostapd_iface *iface, 2179e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct csa_settings *settings) 2180e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 2181e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct hostapd_freq_params old_freq; 2182e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt int ret; 2183e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2184e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt os_memset(&old_freq, 0, sizeof(old_freq)); 2185e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (!iface || !iface->freq || iface->csa_in_progress) 2186e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return -1; 2187e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2188e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = hostapd_change_config_freq(iface->bss[0], iface->conf, 2189e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &settings->freq_params, 2190e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &old_freq); 2191e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) 2192e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 2193e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2194e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = hostapd_build_beacon_data(iface, &settings->beacon_after); 2195e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2196e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* change back the configuration */ 2197e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt hostapd_change_config_freq(iface->bss[0], iface->conf, 2198e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt &old_freq, NULL); 2199e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2200e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) 2201e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 2202e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2203e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* set channel switch parameters for csa ie */ 2204fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt iface->cs_freq_params = settings->freq_params; 2205e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt iface->cs_count = settings->cs_count; 2206e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt iface->cs_block_tx = settings->block_tx; 2207e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2208e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = hostapd_build_beacon_data(iface, &settings->beacon_csa); 2209e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) { 2210e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt free_beacon_data(&settings->beacon_after); 2211e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 2212e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2213e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2214e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt settings->counter_offset_beacon = iface->cs_c_off_beacon; 2215e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt settings->counter_offset_presp = iface->cs_c_off_proberesp; 2216e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2217e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return 0; 2218e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 2219e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2220e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2221e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtvoid hostapd_cleanup_cs_params(struct hostapd_data *hapd) 2222e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 2223fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt os_memset(&hapd->iface->cs_freq_params, 0, 2224fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt sizeof(hapd->iface->cs_freq_params)); 2225e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt hapd->iface->cs_count = 0; 2226e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt hapd->iface->cs_block_tx = 0; 2227e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt hapd->iface->cs_c_off_beacon = 0; 2228e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt hapd->iface->cs_c_off_proberesp = 0; 2229e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt hapd->iface->csa_in_progress = 0; 2230e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 2231e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2232e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2233e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtint hostapd_switch_channel(struct hostapd_data *hapd, 2234e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt struct csa_settings *settings) 2235e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{ 2236e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt int ret; 2237e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = hostapd_fill_csa_settings(hapd->iface, settings); 2238e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) 2239e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 2240e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2241e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt ret = hostapd_drv_switch_channel(hapd, settings); 2242e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt free_beacon_data(&settings->beacon_csa); 2243e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt free_beacon_data(&settings->beacon_after); 2244e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2245e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt if (ret) { 2246e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt /* if we failed, clean cs parameters */ 2247e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt hostapd_cleanup_cs_params(hapd); 2248e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return ret; 2249e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt } 2250e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2251e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt hapd->iface->csa_in_progress = 1; 2252e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt return 0; 2253e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt} 2254e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt 2255e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt#endif /* NEED_AP_MLME */ 2256