main.c revision 4b06059785b935dd1f4f09314e4e12c417d2c6a4
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd / main() 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2002-2011, 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#ifndef CONFIG_NATIVE_WINDOWS 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <syslog.h> 120ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt#include <grp.h> 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/common.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/eloop.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/random.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/tls.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/version.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "drivers/driver.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_server/eap.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_server/tncs.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/hostapd.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/ap_config.h" 2504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "ap/ap_drv_ops.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "config_file.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_register.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "dump_state.h" 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ctrl_iface.h" 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtextern int wpa_debug_level; 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtextern int wpa_debug_show_keys; 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtextern int wpa_debug_timestamp; 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtextern struct wpa_driver_ops *wpa_drivers[]; 371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstruct hapd_global { 401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt void **drv_priv; 411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t drv_count; 421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}; 431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic struct hapd_global global; 451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_HOSTAPD_LOGGER 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module, 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int level, const char *txt, size_t len) 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = ctx; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *format, *module_str; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int maxlen; 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int conf_syslog_level, conf_stdout_level; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int conf_syslog, conf_stdout; 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt maxlen = len + 100; 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt format = os_malloc(maxlen); 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!format) 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd && hapd->conf) { 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf_syslog_level = hapd->conf->logger_syslog_level; 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf_stdout_level = hapd->conf->logger_stdout_level; 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf_syslog = hapd->conf->logger_syslog; 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf_stdout = hapd->conf->logger_stdout; 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf_syslog_level = conf_stdout_level = 0; 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf_syslog = conf_stdout = (unsigned int) -1; 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (module) { 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_MODULE_IEEE80211: 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str = "IEEE 802.11"; 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_MODULE_IEEE8021X: 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str = "IEEE 802.1X"; 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_MODULE_RADIUS: 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str = "RADIUS"; 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_MODULE_WPA: 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str = "WPA"; 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_MODULE_DRIVER: 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str = "DRIVER"; 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_MODULE_IAPP: 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str = "IAPP"; 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_MODULE_MLME: 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str = "MLME"; 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str = NULL; 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd && hapd->conf && addr) 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(format, maxlen, "%s: STA " MACSTR "%s%s: %s", 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->iface, MAC2STR(addr), 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str ? " " : "", module_str, txt); 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (hapd && hapd->conf) 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(format, maxlen, "%s:%s%s %s", 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->iface, module_str ? " " : "", 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str, txt); 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (addr) 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(format, maxlen, "STA " MACSTR "%s%s: %s", 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(addr), module_str ? " " : "", 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str, txt); 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(format, maxlen, "%s%s%s", 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str, module_str ? ": " : "", txt); 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((conf_stdout & module) && level >= conf_stdout_level) { 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_debug_print_timestamp(); 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt printf("%s\n", format); 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((conf_syslog & module) && level >= conf_syslog_level) { 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int priority; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (level) { 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_LEVEL_DEBUG_VERBOSE: 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_LEVEL_DEBUG: 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priority = LOG_DEBUG; 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_LEVEL_INFO: 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priority = LOG_INFO; 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_LEVEL_NOTICE: 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priority = LOG_NOTICE; 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_LEVEL_WARNING: 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priority = LOG_WARNING; 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priority = LOG_INFO; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt syslog(priority, "%s", format); 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(format); 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_HOSTAPD_LOGGER */ 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_init - Allocate and initialize per-interface data 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @config_file: Path to the configuration file 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the allocated interface data or %NULL on failure 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to allocate main data structures for per-interface 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * data. The allocated data buffer will be freed by calling 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd_cleanup_iface(). 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct hostapd_iface * hostapd_init(const char *config_file) 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_iface *hapd_iface = NULL; 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_config *conf = NULL; 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd; 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd_iface = os_zalloc(sizeof(*hapd_iface)); 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd_iface == NULL) 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd_iface->config_fname = os_strdup(config_file); 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd_iface->config_fname == NULL) 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf = hostapd_config_read(hapd_iface->config_fname); 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf == NULL) 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd_iface->conf = conf; 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd_iface->num_bss = conf->num_bss; 18061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hapd_iface->bss = os_calloc(conf->num_bss, 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(struct hostapd_data *)); 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd_iface->bss == NULL) 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < conf->num_bss; i++) { 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd = hapd_iface->bss[i] = 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_alloc_bss_data(hapd_iface, conf, 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &conf->bss[i]); 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd == NULL) 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->msg_ctx = hapd; 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return hapd_iface; 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 1974b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to set up interface with %s", 1984b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt config_file); 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conf) 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_config_free(conf); 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd_iface) { 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(hapd_iface->config_fname); 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(hapd_iface->bss); 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(hapd_iface); 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_driver_init(struct hostapd_iface *iface) 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_init_params params; 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = iface->bss[0]; 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_bss_config *conf = hapd->conf; 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *b = conf->bssid; 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_capa capa; 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->driver == NULL || hapd->driver->hapd_init == NULL) { 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "No hostapd driver wrapper available"); 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Initialize the driver interface */ 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5])) 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b = NULL; 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 2291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (i = 0; wpa_drivers[i]; i++) { 2301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_drivers[i] != hapd->driver) 2311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 2321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (global.drv_priv[i] == NULL && 2341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_drivers[i]->global_init) { 2351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt global.drv_priv[i] = wpa_drivers[i]->global_init(); 2361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (global.drv_priv[i] == NULL) { 2371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_ERROR, "Failed to initialize " 2381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "driver '%s'", 2391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_drivers[i]->name); 2401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 2411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 2421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 2431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.global_priv = global.drv_priv[i]; 2451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 2461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.bssid = b; 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ifname = hapd->conf->iface; 24961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt params.ssid = hapd->conf->ssid.ssid; 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssid_len = hapd->conf->ssid.ssid_len; 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.test_socket = hapd->conf->test_socket; 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.use_pae_group_addr = hapd->conf->use_pae_group_addr; 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.num_bridge = hapd->iface->num_bss; 25561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt params.bridge = os_calloc(hapd->iface->num_bss, sizeof(char *)); 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params.bridge == NULL) 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < hapd->iface->num_bss; i++) { 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *bss = hapd->iface->bss[i]; 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bss->conf->bridge[0]) 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.bridge[i] = bss->conf->bridge; 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.own_addr = hapd->own_addr; 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->drv_priv = hapd->driver->hapd_init(hapd, ¶ms); 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(params.bridge); 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->drv_priv == NULL) { 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "%s driver initialization failed.", 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->driver->name); 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->driver = NULL; 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->driver->get_capa && 2761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt hapd->driver->get_capa(hapd->drv_priv, &capa) == 0) { 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->drv_flags = capa.flags; 2781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt iface->probe_resp_offloads = capa.probe_resp_offloads; 279444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt iface->extended_capa = capa.extended_capa; 280444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt iface->extended_capa_mask = capa.extended_capa_mask; 281444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt iface->extended_capa_len = capa.extended_capa_len; 2821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct hostapd_iface * 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidthostapd_interface_init(struct hapd_interfaces *interfaces, 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *config_fname, int debug) 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_iface *iface; 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int k; 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Configuration file: %s", config_fname); 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface = hostapd_init(config_fname); 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!iface) 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->interfaces = interfaces; 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (k = 0; k < debug; k++) { 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface->bss[0]->conf->logger_stdout_level > 0) 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->bss[0]->conf->logger_stdout_level--; 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3064b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (iface->conf->bss[0].iface[0] == '\0' && 3074b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt !hostapd_drv_none(iface->bss[0])) { 3084b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt wpa_printf(MSG_ERROR, "Interface name not specified in %s", 3094b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt config_fname); 3104b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt hostapd_interface_deinit_free(iface); 3114b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt return NULL; 3124b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt } 3134b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt 3144b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (hostapd_driver_init(iface) || 3154b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt hostapd_setup_interface(iface)) { 3164b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt hostapd_interface_deinit_free(iface); 3174b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt return NULL; 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return iface; 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * handle_term - SIGINT and SIGTERM handler to terminate hostapd process 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_term(int sig, void *signal_ctx) 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Signal %d received - terminating", sig); 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_terminate(); 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int handle_reload_iface(struct hostapd_iface *iface, void *ctx) 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_reload_config(iface) < 0) { 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "Failed to read new configuration " 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "file - continuing with old."); 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * handle_reload - SIGHUP handler to reload configuration 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_reload(int sig, void *signal_ctx) 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hapd_interfaces *interfaces = signal_ctx; 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Signal %d received - reloading configuration", 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sig); 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_for_each_interface(interfaces, handle_reload_iface, NULL); 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_dump_state(int sig, void *signal_ctx) 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef HOSTAPD_DUMP_STATE 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hapd_interfaces *interfaces = signal_ctx; 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_for_each_interface(interfaces, handle_dump_state_iface, NULL); 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* HOSTAPD_DUMP_STATE */ 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 36875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenstatic int hostapd_global_init(struct hapd_interfaces *interfaces, 36975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen const char *entropy_file) 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int i; 3721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memset(&global, 0, sizeof(global)); 3741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger_register_cb(hostapd_logger_cb); 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_server_register_methods()) { 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to register EAP methods"); 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eloop_init()) { 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to initialize event loop"); 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 38775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen random_init(entropy_file); 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_signal(SIGHUP, handle_reload, interfaces); 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_signal(SIGUSR1, handle_dump_state, interfaces); 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_signal_terminate(handle_term, interfaces); 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt openlog("hostapd", 0, LOG_DAEMON); 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (i = 0; wpa_drivers[i]; i++) 4001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt global.drv_count++; 4011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (global.drv_count == 0) { 4021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_ERROR, "No drivers enabled"); 4031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 4041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 40561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt global.drv_priv = os_calloc(global.drv_count, sizeof(void *)); 4061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (global.drv_priv == NULL) 4071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 4081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_global_deinit(const char *pid_file) 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int i; 4161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (i = 0; wpa_drivers[i] && global.drv_priv; i++) { 4181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!global.drv_priv[i]) 4191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 4201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_drivers[i]->global_deinit(global.drv_priv[i]); 4211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 4221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_free(global.drv_priv); 4231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt global.drv_priv = NULL; 4241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_SERVER_TNC 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs_global_deinit(); 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_SERVER_TNC */ 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt random_deinit(); 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_destroy(); 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt closelog(); 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_server_unregister_methods(); 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_daemonize_terminate(pid_file); 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_global_run(struct hapd_interfaces *ifaces, int daemonize, 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pid_file) 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_SERVER_TNC 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int tnc = 0; 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, k; 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; !tnc && i < ifaces->count; i++) { 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (k = 0; k < ifaces->iface[i]->num_bss; k++) { 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ifaces->iface[i]->bss[0]->conf->tnc) { 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tnc++; 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tnc && tncs_global_init() < 0) { 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to initialize TNCS"); 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_SERVER_TNC */ 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (daemonize && os_daemonize(pid_file)) { 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("daemon"); 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_run(); 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void show_version(void) 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fprintf(stderr, 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "hostapd v" VERSION_STR "\n" 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "User space daemon for IEEE 802.11 AP management,\n" 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator\n" 482a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt "Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi> " 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "and contributors\n"); 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void usage(void) 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt show_version(); 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fprintf(stderr, 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "\n" 49275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen "usage: hostapd [-hdBKtv] [-P <PID file>] [-e <entropy file>] " 49361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "\\\n" 4940ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt " [-g <global ctrl_iface>] [-G <group>] \\\n" 4950ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt " <configuration file(s)>\n" 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "\n" 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "options:\n" 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -h show this usage\n" 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -d show more debug messages (-dd for even more)\n" 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -B run daemon in the background\n" 50175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen " -e entropy file\n" 50261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt " -g global control interface path\n" 5030ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt " -G group for control interfaces\n" 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -P PID file\n" 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -K include key data in debug messages\n" 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_DEBUG_FILE 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -f log output to debug file instead of stdout\n" 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_DEBUG_FILE */ 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -t include timestamps in some debug messages\n" 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -v show hostapd version\n"); 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt exit(1); 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * hostapd_msg_ifname_cb(void *ctx) 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = ctx; 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd && hapd->iconf && hapd->iconf->bss) 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return hapd->iconf->bss->iface; 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 52561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int hostapd_get_global_ctrl_iface(struct hapd_interfaces *interfaces, 52661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const char *path) 52761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 52861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char *pos; 52961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(interfaces->global_iface_path); 53061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->global_iface_path = os_strdup(path); 53161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (interfaces->global_iface_path == NULL) 53261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 53361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos = os_strrchr(interfaces->global_iface_path, '/'); 53461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (pos == NULL) { 5351e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt wpa_printf(MSG_ERROR, "No '/' in the global control interface " 5361e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt "file"); 53761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(interfaces->global_iface_path); 53861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->global_iface_path = NULL; 53961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 54061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 54161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 54261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *pos = '\0'; 54361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->global_iface_name = pos + 1; 54461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 54561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 54661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 54761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 54861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 5490ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidtstatic int hostapd_get_ctrl_iface_group(struct hapd_interfaces *interfaces, 5500ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt const char *group) 5510ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt{ 5520ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS 5530ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt struct group *grp; 5540ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt grp = getgrnam(group); 5550ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt if (grp == NULL) { 5560ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt wpa_printf(MSG_ERROR, "Unknown group '%s'", group); 5570ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt return -1; 5580ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt } 5590ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt interfaces->ctrl_iface_group = grp->gr_gid; 5600ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 5610ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt return 0; 5620ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt} 5630ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt 5640ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint main(int argc, char *argv[]) 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hapd_interfaces interfaces; 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 1; 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int c, debug = 0, daemonize = 0; 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pid_file = NULL; 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *log_file = NULL; 57375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen const char *entropy_file = NULL; 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_program_init()) 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 57861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memset(&interfaces, 0, sizeof(interfaces)); 57961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.reload_config = hostapd_reload_config; 58061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.config_read_cb = hostapd_config_read; 58161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.for_each_interface = hostapd_for_each_interface; 58261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.ctrl_iface_init = hostapd_ctrl_iface_init; 58361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.ctrl_iface_deinit = hostapd_ctrl_iface_deinit; 58461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.driver_init = hostapd_driver_init; 58561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.global_iface_path = NULL; 58661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.global_iface_name = NULL; 58761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.global_ctrl_sock = -1; 58861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (;;) { 5900ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt c = getopt(argc, argv, "Bde:f:hKP:tvg:G:"); 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (c < 0) 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (c) { 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'h': 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usage(); 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'd': 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt debug++; 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_debug_level > 0) 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_debug_level--; 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'B': 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt daemonize++; 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 60575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen case 'e': 60675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen entropy_file = optarg; 60775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen break; 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'f': 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt log_file = optarg; 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'K': 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_debug_show_keys++; 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'P': 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(pid_file); 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pid_file = os_rel2abs_path(optarg); 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 't': 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_debug_timestamp++; 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'v': 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt show_version(); 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt exit(1); 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 62561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case 'g': 6261e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt if (hostapd_get_global_ctrl_iface(&interfaces, optarg)) 6271e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt return -1; 62861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 6290ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt case 'G': 6301e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt if (hostapd_get_ctrl_iface_group(&interfaces, optarg)) 6311e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt return -1; 6320ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt break; 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usage(); 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 63961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (optind == argc && interfaces.global_iface_path == NULL) 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usage(); 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg_register_ifname_cb(hostapd_msg_ifname_cb); 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (log_file) 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_debug_open_file(log_file); 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt interfaces.count = argc - optind; 64861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (interfaces.count) { 64961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.iface = os_calloc(interfaces.count, 65061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sizeof(struct hostapd_iface *)); 65161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (interfaces.iface == NULL) { 65261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "malloc failed"); 65361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 65461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6574b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (hostapd_global_init(&interfaces, entropy_file)) { 6584b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to initilize global context"); 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6604b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt } 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Initialize interfaces */ 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < interfaces.count; i++) { 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt interfaces.iface[i] = hostapd_interface_init(&interfaces, 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt argv[optind + i], 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt debug); 6674b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (!interfaces.iface[i]) { 6684b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to initialize interface"); 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 6704b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt } 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 67361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_global_ctrl_iface_init(&interfaces); 67461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 6754b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (hostapd_global_run(&interfaces, daemonize, pid_file)) { 6764b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to start eloop"); 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 6784b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt } 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = 0; 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out: 68361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_global_ctrl_iface_deinit(&interfaces); 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Deinitialize all interfaces */ 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < interfaces.count; i++) 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_interface_deinit_free(interfaces.iface[i]); 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(interfaces.iface); 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_global_deinit(pid_file); 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(pid_file); 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (log_file) 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_debug_close_file(); 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_program_deinit(); 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 699