main.c revision 818ea489ef32dcdc7c098d8a336d6e1dd8996112
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" 1796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt#include "utils/uuid.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/random.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/tls.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/version.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "drivers/driver.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_server/eap.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_server/tncs.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/hostapd.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/ap_config.h" 2604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "ap/ap_drv_ops.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "config_file.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_register.h" 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ctrl_iface.h" 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstruct hapd_global { 331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt void **drv_priv; 341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t drv_count; 351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}; 361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic struct hapd_global global; 381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_HOSTAPD_LOGGER 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module, 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int level, const char *txt, size_t len) 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = ctx; 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *format, *module_str; 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int maxlen; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int conf_syslog_level, conf_stdout_level; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int conf_syslog, conf_stdout; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt maxlen = len + 100; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt format = os_malloc(maxlen); 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!format) 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd && hapd->conf) { 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf_syslog_level = hapd->conf->logger_syslog_level; 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf_stdout_level = hapd->conf->logger_stdout_level; 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf_syslog = hapd->conf->logger_syslog; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf_stdout = hapd->conf->logger_stdout; 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf_syslog_level = conf_stdout_level = 0; 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf_syslog = conf_stdout = (unsigned int) -1; 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (module) { 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_MODULE_IEEE80211: 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str = "IEEE 802.11"; 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_MODULE_IEEE8021X: 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str = "IEEE 802.1X"; 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_MODULE_RADIUS: 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str = "RADIUS"; 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_MODULE_WPA: 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str = "WPA"; 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_MODULE_DRIVER: 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str = "DRIVER"; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_MODULE_IAPP: 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str = "IAPP"; 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_MODULE_MLME: 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str = "MLME"; 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str = NULL; 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd && hapd->conf && addr) 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(format, maxlen, "%s: STA " MACSTR "%s%s: %s", 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->iface, MAC2STR(addr), 9596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt module_str ? " " : "", module_str ? module_str : "", 9696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt txt); 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (hapd && hapd->conf) 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(format, maxlen, "%s:%s%s %s", 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->iface, module_str ? " " : "", 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str, txt); 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (addr) 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(format, maxlen, "STA " MACSTR "%s%s: %s", 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(addr), module_str ? " " : "", 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str, txt); 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(format, maxlen, "%s%s%s", 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str, module_str ? ": " : "", txt); 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((conf_stdout & module) && level >= conf_stdout_level) { 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_debug_print_timestamp(); 111cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "%s", format); 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((conf_syslog & module) && level >= conf_syslog_level) { 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int priority; 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (level) { 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_LEVEL_DEBUG_VERBOSE: 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_LEVEL_DEBUG: 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priority = LOG_DEBUG; 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_LEVEL_INFO: 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priority = LOG_INFO; 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_LEVEL_NOTICE: 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priority = LOG_NOTICE; 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_LEVEL_WARNING: 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priority = LOG_WARNING; 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priority = LOG_INFO; 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt syslog(priority, "%s", format); 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(format); 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_HOSTAPD_LOGGER */ 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 145cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_driver_init - Preparate driver interface 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_driver_init(struct hostapd_iface *iface) 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_init_params params; 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = iface->bss[0]; 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_bss_config *conf = hapd->conf; 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *b = conf->bssid; 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_capa capa; 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->driver == NULL || hapd->driver->hapd_init == NULL) { 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "No hostapd driver wrapper available"); 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Initialize the driver interface */ 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5])) 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b = NULL; 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 1661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (i = 0; wpa_drivers[i]; i++) { 1671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_drivers[i] != hapd->driver) 1681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 1691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (global.drv_priv[i] == NULL && 1711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_drivers[i]->global_init) { 1721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt global.drv_priv[i] = wpa_drivers[i]->global_init(); 1731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (global.drv_priv[i] == NULL) { 1741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_ERROR, "Failed to initialize " 1751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "driver '%s'", 1761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_drivers[i]->name); 1771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 1781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 1791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 1801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.global_priv = global.drv_priv[i]; 1821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 1831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.bssid = b; 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ifname = hapd->conf->iface; 18661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt params.ssid = hapd->conf->ssid.ssid; 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssid_len = hapd->conf->ssid.ssid_len; 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.test_socket = hapd->conf->test_socket; 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.use_pae_group_addr = hapd->conf->use_pae_group_addr; 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.num_bridge = hapd->iface->num_bss; 19261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt params.bridge = os_calloc(hapd->iface->num_bss, sizeof(char *)); 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params.bridge == NULL) 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < hapd->iface->num_bss; i++) { 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *bss = hapd->iface->bss[i]; 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bss->conf->bridge[0]) 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.bridge[i] = bss->conf->bridge; 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.own_addr = hapd->own_addr; 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->drv_priv = hapd->driver->hapd_init(hapd, ¶ms); 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(params.bridge); 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->drv_priv == NULL) { 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "%s driver initialization failed.", 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->driver->name); 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->driver = NULL; 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->driver->get_capa && 2131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt hapd->driver->get_capa(hapd->drv_priv, &capa) == 0) { 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->drv_flags = capa.flags; 2151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt iface->probe_resp_offloads = capa.probe_resp_offloads; 216444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt iface->extended_capa = capa.extended_capa; 217444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt iface->extended_capa_mask = capa.extended_capa_mask; 218444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt iface->extended_capa_len = capa.extended_capa_len; 2198bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt iface->drv_max_acl_mac_addrs = capa.max_acl_mac_addrs; 2201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 226cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt/** 227cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_interface_init - Read configuration file and init BSS data 228cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * 229cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * This function is used to parse configuration file for a full interface (one 230cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * or more BSSes sharing the same radio) and allocate memory for the BSS 231cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * interfaces. No actiual driver operations are started. 232cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct hostapd_iface * 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidthostapd_interface_init(struct hapd_interfaces *interfaces, 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *config_fname, int debug) 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_iface *iface; 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int k; 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Configuration file: %s", config_fname); 241cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface = hostapd_init(interfaces, config_fname); 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!iface) 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->interfaces = interfaces; 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (k = 0; k < debug; k++) { 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface->bss[0]->conf->logger_stdout_level > 0) 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->bss[0]->conf->logger_stdout_level--; 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 251cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (iface->conf->bss[0]->iface[0] == '\0' && 2524b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt !hostapd_drv_none(iface->bss[0])) { 2534b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt wpa_printf(MSG_ERROR, "Interface name not specified in %s", 2544b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt config_fname); 2554b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt hostapd_interface_deinit_free(iface); 2564b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt return NULL; 2574b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt } 2584b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return iface; 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * handle_term - SIGINT and SIGTERM handler to terminate hostapd process 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_term(int sig, void *signal_ctx) 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Signal %d received - terminating", sig); 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_terminate(); 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int handle_reload_iface(struct hostapd_iface *iface, void *ctx) 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_reload_config(iface) < 0) { 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "Failed to read new configuration " 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "file - continuing with old."); 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * handle_reload - SIGHUP handler to reload configuration 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_reload(int sig, void *signal_ctx) 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hapd_interfaces *interfaces = signal_ctx; 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Signal %d received - reloading configuration", 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sig); 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_for_each_interface(interfaces, handle_reload_iface, NULL); 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_dump_state(int sig, void *signal_ctx) 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 299fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt /* Not used anymore - ignore signal */ 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenstatic int hostapd_global_init(struct hapd_interfaces *interfaces, 30575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen const char *entropy_file) 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int i; 3081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memset(&global, 0, sizeof(global)); 3101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger_register_cb(hostapd_logger_cb); 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_server_register_methods()) { 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to register EAP methods"); 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eloop_init()) { 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to initialize event loop"); 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen random_init(entropy_file); 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_signal(SIGHUP, handle_reload, interfaces); 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_signal(SIGUSR1, handle_dump_state, interfaces); 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_signal_terminate(handle_term, interfaces); 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt openlog("hostapd", 0, LOG_DAEMON); 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (i = 0; wpa_drivers[i]; i++) 3361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt global.drv_count++; 3371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (global.drv_count == 0) { 3381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_ERROR, "No drivers enabled"); 3391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 3401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 34161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt global.drv_priv = os_calloc(global.drv_count, sizeof(void *)); 3421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (global.drv_priv == NULL) 3431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 3441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_global_deinit(const char *pid_file) 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int i; 3521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (i = 0; wpa_drivers[i] && global.drv_priv; i++) { 3541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!global.drv_priv[i]) 3551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 3561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_drivers[i]->global_deinit(global.drv_priv[i]); 3571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 3581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_free(global.drv_priv); 3591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt global.drv_priv = NULL; 3601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_SERVER_TNC 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs_global_deinit(); 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_SERVER_TNC */ 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt random_deinit(); 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_destroy(); 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt closelog(); 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_server_unregister_methods(); 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_daemonize_terminate(pid_file); 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_global_run(struct hapd_interfaces *ifaces, int daemonize, 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pid_file) 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_SERVER_TNC 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int tnc = 0; 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, k; 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; !tnc && i < ifaces->count; i++) { 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (k = 0; k < ifaces->iface[i]->num_bss; k++) { 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ifaces->iface[i]->bss[0]->conf->tnc) { 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tnc++; 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tnc && tncs_global_init() < 0) { 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to initialize TNCS"); 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_SERVER_TNC */ 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (daemonize && os_daemonize(pid_file)) { 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt perror("daemon"); 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_run(); 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void show_version(void) 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fprintf(stderr, 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "hostapd v" VERSION_STR "\n" 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "User space daemon for IEEE 802.11 AP management,\n" 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator\n" 418fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt "Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi> " 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "and contributors\n"); 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void usage(void) 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt show_version(); 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fprintf(stderr, 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "\n" 42875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen "usage: hostapd [-hdBKtv] [-P <PID file>] [-e <entropy file>] " 42961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "\\\n" 4300ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt " [-g <global ctrl_iface>] [-G <group>] \\\n" 4310ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt " <configuration file(s)>\n" 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "\n" 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "options:\n" 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -h show this usage\n" 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -d show more debug messages (-dd for even more)\n" 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -B run daemon in the background\n" 43775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen " -e entropy file\n" 43861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt " -g global control interface path\n" 4390ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt " -G group for control interfaces\n" 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -P PID file\n" 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -K include key data in debug messages\n" 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_DEBUG_FILE 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -f log output to debug file instead of stdout\n" 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_DEBUG_FILE */ 445cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#ifdef CONFIG_DEBUG_LINUX_TRACING 446cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt " -T = record to Linux tracing in addition to logging\n" 447cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt " (records all messages regardless of debug verbosity)\n" 448cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#endif /* CONFIG_DEBUG_LINUX_TRACING */ 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -t include timestamps in some debug messages\n" 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -v show hostapd version\n"); 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt exit(1); 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * hostapd_msg_ifname_cb(void *ctx) 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = ctx; 459cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hapd && hapd->iconf && hapd->iconf->bss && 460cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hapd->iconf->num_bss > 0 && hapd->iconf->bss[0]) 461cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return hapd->iconf->bss[0]->iface; 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 46661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int hostapd_get_global_ctrl_iface(struct hapd_interfaces *interfaces, 46761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const char *path) 46861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 46961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char *pos; 47061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(interfaces->global_iface_path); 47161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->global_iface_path = os_strdup(path); 47261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (interfaces->global_iface_path == NULL) 47361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 47461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos = os_strrchr(interfaces->global_iface_path, '/'); 47561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (pos == NULL) { 4761e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt wpa_printf(MSG_ERROR, "No '/' in the global control interface " 4771e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt "file"); 47861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(interfaces->global_iface_path); 47961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->global_iface_path = NULL; 48061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 48161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 48261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 48361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *pos = '\0'; 48461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->global_iface_name = pos + 1; 48561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 48661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 48761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 48861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 48961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 4900ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidtstatic int hostapd_get_ctrl_iface_group(struct hapd_interfaces *interfaces, 4910ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt const char *group) 4920ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt{ 4930ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS 4940ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt struct group *grp; 4950ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt grp = getgrnam(group); 4960ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt if (grp == NULL) { 4970ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt wpa_printf(MSG_ERROR, "Unknown group '%s'", group); 4980ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt return -1; 4990ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt } 5000ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt interfaces->ctrl_iface_group = grp->gr_gid; 5010ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 5020ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt return 0; 5030ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt} 5040ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt 5050ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt 50696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt#ifdef CONFIG_WPS 50796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidtstatic int gen_uuid(const char *txt_addr) 50896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt{ 50996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt u8 addr[ETH_ALEN]; 51096be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt u8 uuid[UUID_LEN]; 51196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt char buf[100]; 51296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt 51396be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt if (hwaddr_aton(txt_addr, addr) < 0) 51496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt return -1; 51596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt 51696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt uuid_gen_mac_addr(addr, uuid); 51796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt if (uuid_bin2str(uuid, buf, sizeof(buf)) < 0) 51896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt return -1; 51996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt 52096be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt printf("%s\n", buf); 52196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt 52296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt return 0; 52396be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt} 52496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt#endif /* CONFIG_WPS */ 52596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt 52696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint main(int argc, char *argv[]) 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hapd_interfaces interfaces; 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 1; 531cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i, j; 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int c, debug = 0, daemonize = 0; 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pid_file = NULL; 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *log_file = NULL; 53575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen const char *entropy_file = NULL; 536cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt char **bss_config = NULL, **tmp_bss; 537cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t num_bss_configs = 0; 538cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#ifdef CONFIG_DEBUG_LINUX_TRACING 539cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt int enable_trace_dbg = 0; 540cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#endif /* CONFIG_DEBUG_LINUX_TRACING */ 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_program_init()) 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 54561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memset(&interfaces, 0, sizeof(interfaces)); 54661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.reload_config = hostapd_reload_config; 54761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.config_read_cb = hostapd_config_read; 54861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.for_each_interface = hostapd_for_each_interface; 54961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.ctrl_iface_init = hostapd_ctrl_iface_init; 55061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.ctrl_iface_deinit = hostapd_ctrl_iface_deinit; 55161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.driver_init = hostapd_driver_init; 55261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.global_iface_path = NULL; 55361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.global_iface_name = NULL; 55461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.global_ctrl_sock = -1; 55561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (;;) { 55796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt c = getopt(argc, argv, "b:Bde:f:hKP:Ttu:vg:G:"); 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (c < 0) 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (c) { 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'h': 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usage(); 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'd': 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt debug++; 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_debug_level > 0) 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_debug_level--; 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'B': 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt daemonize++; 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 57275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen case 'e': 57375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen entropy_file = optarg; 57475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen break; 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'f': 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt log_file = optarg; 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'K': 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_debug_show_keys++; 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'P': 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(pid_file); 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pid_file = os_rel2abs_path(optarg); 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 't': 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_debug_timestamp++; 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 588cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#ifdef CONFIG_DEBUG_LINUX_TRACING 589cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case 'T': 590cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt enable_trace_dbg = 1; 591cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt break; 592cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#endif /* CONFIG_DEBUG_LINUX_TRACING */ 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'v': 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt show_version(); 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt exit(1); 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 59761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case 'g': 5981e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt if (hostapd_get_global_ctrl_iface(&interfaces, optarg)) 5991e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt return -1; 60061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 6010ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt case 'G': 6021e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt if (hostapd_get_ctrl_iface_group(&interfaces, optarg)) 6031e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt return -1; 6040ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt break; 605cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case 'b': 606cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt tmp_bss = os_realloc_array(bss_config, 607cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt num_bss_configs + 1, 608cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt sizeof(char *)); 609cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (tmp_bss == NULL) 610cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto out; 611cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt bss_config = tmp_bss; 612cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt bss_config[num_bss_configs++] = optarg; 613cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt break; 61496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt#ifdef CONFIG_WPS 61596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt case 'u': 61696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt return gen_uuid(optarg); 61796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt#endif /* CONFIG_WPS */ 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usage(); 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 624cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (optind == argc && interfaces.global_iface_path == NULL && 625cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt num_bss_configs == 0) 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usage(); 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg_register_ifname_cb(hostapd_msg_ifname_cb); 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (log_file) 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_debug_open_file(log_file); 632cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#ifdef CONFIG_DEBUG_LINUX_TRACING 633cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (enable_trace_dbg) { 634cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt int tret = wpa_debug_open_linux_tracing(); 635cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (tret) { 636cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to enable trace logging"); 637cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 638cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 639cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 640cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#endif /* CONFIG_DEBUG_LINUX_TRACING */ 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt interfaces.count = argc - optind; 643cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (interfaces.count || num_bss_configs) { 644cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt interfaces.iface = os_calloc(interfaces.count + num_bss_configs, 64561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sizeof(struct hostapd_iface *)); 64661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (interfaces.iface == NULL) { 64761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "malloc failed"); 64861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 64961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6524b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (hostapd_global_init(&interfaces, entropy_file)) { 6534b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to initilize global context"); 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6554b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt } 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 657cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* Allocate and parse configuration for full interface files */ 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < interfaces.count; i++) { 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt interfaces.iface[i] = hostapd_interface_init(&interfaces, 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt argv[optind + i], 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt debug); 6624b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (!interfaces.iface[i]) { 6634b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to initialize interface"); 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 6654b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt } 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 668cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* Allocate and parse configuration for per-BSS files */ 669cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (i = 0; i < num_bss_configs; i++) { 670cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface *iface; 671cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt char *fname; 672cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 673cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "BSS config: %s", bss_config[i]); 674cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt fname = os_strchr(bss_config[i], ':'); 675cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (fname == NULL) { 676cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, 677cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "Invalid BSS config identifier '%s'", 678cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt bss_config[i]); 679cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto out; 680cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 681cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt *fname++ = '\0'; 682cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface = hostapd_interface_init_bss(&interfaces, bss_config[i], 683cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt fname, debug); 684cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (iface == NULL) 685cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto out; 686cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (j = 0; j < interfaces.count; j++) { 687cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (interfaces.iface[j] == iface) 688cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt break; 689cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 690cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (j == interfaces.count) { 691cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface **tmp; 692cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt tmp = os_realloc_array(interfaces.iface, 693cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt interfaces.count + 1, 694cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt sizeof(struct hostapd_iface *)); 695cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (tmp == NULL) { 696cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_interface_deinit_free(iface); 697cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto out; 698cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 699cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt interfaces.iface = tmp; 700cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt interfaces.iface[interfaces.count++] = iface; 701cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 702cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 703cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 704cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* 705cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * Enable configured interfaces. Depending on channel configuration, 706cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * this may complete full initialization before returning or use a 707cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * callback mechanism to complete setup in case of operations like HT 708cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * co-ex scans, ACS, or DFS are needed to determine channel parameters. 709cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * In such case, the interface will be enabled from eloop context within 710cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_global_run(). 711cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 712b96dad47218788efffa3db0fe7f1b54a7d19e366Dmitry Shmidt interfaces.terminate_on_error = interfaces.count; 713cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (i = 0; i < interfaces.count; i++) { 714cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hostapd_driver_init(interfaces.iface[i]) || 715cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_setup_interface(interfaces.iface[i])) 716cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto out; 717cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 718cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 71961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_global_ctrl_iface_init(&interfaces); 72061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 7214b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (hostapd_global_run(&interfaces, daemonize, pid_file)) { 7224b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to start eloop"); 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 7244b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt } 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = 0; 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out: 72961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_global_ctrl_iface_deinit(&interfaces); 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Deinitialize all interfaces */ 731a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt for (i = 0; i < interfaces.count; i++) { 732818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (!interfaces.iface[i]) 733818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt continue; 734a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt interfaces.iface[i]->driver_ap_teardown = 735a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt !!(interfaces.iface[i]->drv_flags & 736a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT); 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_interface_deinit_free(interfaces.iface[i]); 738a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt } 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(interfaces.iface); 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_global_deinit(pid_file); 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(pid_file); 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (log_file) 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_debug_close_file(); 746cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_debug_close_linux_tracing(); 747cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 748cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_free(bss_config); 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_program_deinit(); 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 754