18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd / main() 3de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt * Copyright (c) 2002-2016, 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" 27d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#include "fst/fst.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "config_file.h" 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_register.h" 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ctrl_iface.h" 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstruct hapd_global { 341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt void **drv_priv; 351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t drv_count; 361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}; 371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic struct hapd_global global; 391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_HOSTAPD_LOGGER 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module, 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int level, const char *txt, size_t len) 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = ctx; 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *format, *module_str; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int maxlen; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int conf_syslog_level, conf_stdout_level; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int conf_syslog, conf_stdout; 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt maxlen = len + 100; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt format = os_malloc(maxlen); 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!format) 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd && hapd->conf) { 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf_syslog_level = hapd->conf->logger_syslog_level; 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf_stdout_level = hapd->conf->logger_stdout_level; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf_syslog = hapd->conf->logger_syslog; 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf_stdout = hapd->conf->logger_stdout; 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf_syslog_level = conf_stdout_level = 0; 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conf_syslog = conf_stdout = (unsigned int) -1; 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (module) { 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_MODULE_IEEE80211: 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str = "IEEE 802.11"; 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_MODULE_IEEE8021X: 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str = "IEEE 802.1X"; 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_MODULE_RADIUS: 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str = "RADIUS"; 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_MODULE_WPA: 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str = "WPA"; 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_MODULE_DRIVER: 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str = "DRIVER"; 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_MODULE_IAPP: 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str = "IAPP"; 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_MODULE_MLME: 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str = "MLME"; 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt module_str = NULL; 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd && hapd->conf && addr) 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(format, maxlen, "%s: STA " MACSTR "%s%s: %s", 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->iface, MAC2STR(addr), 9696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt module_str ? " " : "", module_str ? module_str : "", 9796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt txt); 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (hapd && hapd->conf) 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(format, maxlen, "%s:%s%s %s", 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->conf->iface, module_str ? " " : "", 101661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt module_str ? module_str : "", txt); 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (addr) 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(format, maxlen, "STA " MACSTR "%s%s: %s", 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(addr), module_str ? " " : "", 105661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt module_str ? module_str : "", txt); 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(format, maxlen, "%s%s%s", 108661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt module_str ? module_str : "", 109661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt module_str ? ": " : "", txt); 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((conf_stdout & module) && level >= conf_stdout_level) { 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_debug_print_timestamp(); 113cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "%s", format); 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((conf_syslog & module) && level >= conf_syslog_level) { 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int priority; 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (level) { 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_LEVEL_DEBUG_VERBOSE: 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_LEVEL_DEBUG: 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priority = LOG_DEBUG; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_LEVEL_INFO: 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priority = LOG_INFO; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_LEVEL_NOTICE: 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priority = LOG_NOTICE; 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case HOSTAPD_LEVEL_WARNING: 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priority = LOG_WARNING; 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priority = LOG_INFO; 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt syslog(priority, "%s", format); 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(format); 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_HOSTAPD_LOGGER */ 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 147cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_driver_init - Preparate driver interface 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_driver_init(struct hostapd_iface *iface) 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_init_params params; 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = iface->bss[0]; 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_bss_config *conf = hapd->conf; 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *b = conf->bssid; 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_capa capa; 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->driver == NULL || hapd->driver->hapd_init == NULL) { 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "No hostapd driver wrapper available"); 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Initialize the driver interface */ 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5])) 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b = NULL; 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 1681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (i = 0; wpa_drivers[i]; i++) { 1691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_drivers[i] != hapd->driver) 1701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 1711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (global.drv_priv[i] == NULL && 1731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_drivers[i]->global_init) { 174e4663044d3a689fb5458247e9bc0f8b58cf72fcaDmitry Shmidt global.drv_priv[i] = 175e4663044d3a689fb5458247e9bc0f8b58cf72fcaDmitry Shmidt wpa_drivers[i]->global_init(iface->interfaces); 1761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (global.drv_priv[i] == NULL) { 1771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_ERROR, "Failed to initialize " 1781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "driver '%s'", 1791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_drivers[i]->name); 1801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 1811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 1821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 1831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.global_priv = global.drv_priv[i]; 1851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 1861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.bssid = b; 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ifname = hapd->conf->iface; 189fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt params.driver_params = hapd->iconf->driver_params; 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.use_pae_group_addr = hapd->conf->use_pae_group_addr; 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.num_bridge = hapd->iface->num_bss; 19361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt params.bridge = os_calloc(hapd->iface->num_bss, sizeof(char *)); 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params.bridge == NULL) 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < hapd->iface->num_bss; i++) { 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *bss = hapd->iface->bss[i]; 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bss->conf->bridge[0]) 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.bridge[i] = bss->conf->bridge; 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.own_addr = hapd->own_addr; 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->drv_priv = hapd->driver->hapd_init(hapd, ¶ms); 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(params.bridge); 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->drv_priv == NULL) { 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "%s driver initialization failed.", 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->driver->name); 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hapd->driver = NULL; 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hapd->driver->get_capa && 2141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt hapd->driver->get_capa(hapd->drv_priv, &capa) == 0) { 2150207e233ee2e741f7b2c124c1366e905ebb634c8Dmitry Shmidt struct wowlan_triggers *triggs; 2160207e233ee2e741f7b2c124c1366e905ebb634c8Dmitry Shmidt 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->drv_flags = capa.flags; 218fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt iface->smps_modes = capa.smps_modes; 2191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt iface->probe_resp_offloads = capa.probe_resp_offloads; 220444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt iface->extended_capa = capa.extended_capa; 221444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt iface->extended_capa_mask = capa.extended_capa_mask; 222444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt iface->extended_capa_len = capa.extended_capa_len; 2238bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt iface->drv_max_acl_mac_addrs = capa.max_acl_mac_addrs; 2240207e233ee2e741f7b2c124c1366e905ebb634c8Dmitry Shmidt 2250207e233ee2e741f7b2c124c1366e905ebb634c8Dmitry Shmidt triggs = wpa_get_wowlan_triggers(conf->wowlan_triggers, &capa); 2260207e233ee2e741f7b2c124c1366e905ebb634c8Dmitry Shmidt if (triggs && hapd->driver->set_wowlan) { 2270207e233ee2e741f7b2c124c1366e905ebb634c8Dmitry Shmidt if (hapd->driver->set_wowlan(hapd->drv_priv, triggs)) 2280207e233ee2e741f7b2c124c1366e905ebb634c8Dmitry Shmidt wpa_printf(MSG_ERROR, "set_wowlan failed"); 2290207e233ee2e741f7b2c124c1366e905ebb634c8Dmitry Shmidt } 2300207e233ee2e741f7b2c124c1366e905ebb634c8Dmitry Shmidt os_free(triggs); 2311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 237cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt/** 238cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_interface_init - Read configuration file and init BSS data 239cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * 240cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * This function is used to parse configuration file for a full interface (one 241cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * or more BSSes sharing the same radio) and allocate memory for the BSS 242cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * interfaces. No actiual driver operations are started. 243cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct hostapd_iface * 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidthostapd_interface_init(struct hapd_interfaces *interfaces, 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *config_fname, int debug) 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_iface *iface; 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int k; 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Configuration file: %s", config_fname); 252cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface = hostapd_init(interfaces, config_fname); 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!iface) 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->interfaces = interfaces; 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (k = 0; k < debug; k++) { 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (iface->bss[0]->conf->logger_stdout_level > 0) 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface->bss[0]->conf->logger_stdout_level--; 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 262cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (iface->conf->bss[0]->iface[0] == '\0' && 2634b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt !hostapd_drv_none(iface->bss[0])) { 2644b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt wpa_printf(MSG_ERROR, "Interface name not specified in %s", 2654b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt config_fname); 2664b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt hostapd_interface_deinit_free(iface); 2674b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt return NULL; 2684b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt } 2694b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return iface; 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * handle_term - SIGINT and SIGTERM handler to terminate hostapd process 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_term(int sig, void *signal_ctx) 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Signal %d received - terminating", sig); 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_terminate(); 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int handle_reload_iface(struct hostapd_iface *iface, void *ctx) 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hostapd_reload_config(iface) < 0) { 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "Failed to read new configuration " 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "file - continuing with old."); 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * handle_reload - SIGHUP handler to reload configuration 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_reload(int sig, void *signal_ctx) 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hapd_interfaces *interfaces = signal_ctx; 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Signal %d received - reloading configuration", 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sig); 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_for_each_interface(interfaces, handle_reload_iface, NULL); 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_dump_state(int sig, void *signal_ctx) 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 310fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt /* Not used anymore - ignore signal */ 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenstatic int hostapd_global_init(struct hapd_interfaces *interfaces, 31675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen const char *entropy_file) 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int i; 3191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memset(&global, 0, sizeof(global)); 3211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_logger_register_cb(hostapd_logger_cb); 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_server_register_methods()) { 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to register EAP methods"); 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eloop_init()) { 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to initialize event loop"); 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 33475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen random_init(entropy_file); 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_signal(SIGHUP, handle_reload, interfaces); 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_signal(SIGUSR1, handle_dump_state, interfaces); 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_signal_terminate(handle_term, interfaces); 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt openlog("hostapd", 0, LOG_DAEMON); 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (i = 0; wpa_drivers[i]; i++) 3471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt global.drv_count++; 3481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (global.drv_count == 0) { 3491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_ERROR, "No drivers enabled"); 3501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 3511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 35261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt global.drv_priv = os_calloc(global.drv_count, sizeof(void *)); 3531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (global.drv_priv == NULL) 3541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 3551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_global_deinit(const char *pid_file) 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int i; 3631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (i = 0; wpa_drivers[i] && global.drv_priv; i++) { 3651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (!global.drv_priv[i]) 3661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 3671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_drivers[i]->global_deinit(global.drv_priv[i]); 3681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 3691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_free(global.drv_priv); 3701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt global.drv_priv = NULL; 3711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_SERVER_TNC 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tncs_global_deinit(); 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_SERVER_TNC */ 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt random_deinit(); 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_destroy(); 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt closelog(); 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_server_unregister_methods(); 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_daemonize_terminate(pid_file); 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_global_run(struct hapd_interfaces *ifaces, int daemonize, 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *pid_file) 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_SERVER_TNC 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int tnc = 0; 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, k; 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; !tnc && i < ifaces->count; i++) { 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (k = 0; k < ifaces->iface[i]->num_bss; k++) { 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ifaces->iface[i]->bss[0]->conf->tnc) { 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tnc++; 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tnc && tncs_global_init() < 0) { 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to initialize TNCS"); 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_SERVER_TNC */ 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 412b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (daemonize) { 413b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (os_daemonize(pid_file)) { 414b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt wpa_printf(MSG_ERROR, "daemon: %s", strerror(errno)); 415b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt return -1; 416b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt } 417b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt if (eloop_sock_requeue()) { 418b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt wpa_printf(MSG_ERROR, "eloop_sock_requeue: %s", 419b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt strerror(errno)); 420b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt return -1; 421b97e428f8acf1ecb93f38f8d0063d2f2fd0bc36eDmitry Shmidt } 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_run(); 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void show_version(void) 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fprintf(stderr, 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "hostapd v" VERSION_STR "\n" 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "User space daemon for IEEE 802.11 AP management,\n" 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator\n" 436de47be75037bccd4a11b62eedb3d4aed1b36fa67Dmitry Shmidt "Copyright (c) 2002-2016, Jouni Malinen <j@w1.fi> " 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "and contributors\n"); 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void usage(void) 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt show_version(); 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fprintf(stderr, 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "\n" 44675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen "usage: hostapd [-hdBKtv] [-P <PID file>] [-e <entropy file>] " 44761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt "\\\n" 4480ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt " [-g <global ctrl_iface>] [-G <group>] \\\n" 4490ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt " <configuration file(s)>\n" 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "\n" 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "options:\n" 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -h show this usage\n" 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -d show more debug messages (-dd for even more)\n" 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -B run daemon in the background\n" 45575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen " -e entropy file\n" 45661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt " -g global control interface path\n" 4570ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt " -G group for control interfaces\n" 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -P PID file\n" 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -K include key data in debug messages\n" 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_DEBUG_FILE 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -f log output to debug file instead of stdout\n" 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_DEBUG_FILE */ 463cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#ifdef CONFIG_DEBUG_LINUX_TRACING 464cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt " -T = record to Linux tracing in addition to logging\n" 465cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt " (records all messages regardless of debug verbosity)\n" 466cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#endif /* CONFIG_DEBUG_LINUX_TRACING */ 467d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt " -S start all the interfaces synchronously\n" 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -t include timestamps in some debug messages\n" 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " -v show hostapd version\n"); 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt exit(1); 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * hostapd_msg_ifname_cb(void *ctx) 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hostapd_data *hapd = ctx; 47831a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt if (hapd && hapd->conf) 47931a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt return hapd->conf->iface; 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 48461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int hostapd_get_global_ctrl_iface(struct hapd_interfaces *interfaces, 48561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const char *path) 48661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 48731a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt#ifndef CONFIG_CTRL_IFACE_UDP 48861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt char *pos; 48931a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt#endif /* !CONFIG_CTRL_IFACE_UDP */ 49031a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt 49161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(interfaces->global_iface_path); 49261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->global_iface_path = os_strdup(path); 49361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (interfaces->global_iface_path == NULL) 49461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 49531a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt 49631a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt#ifndef CONFIG_CTRL_IFACE_UDP 49761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos = os_strrchr(interfaces->global_iface_path, '/'); 49861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (pos == NULL) { 4991e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt wpa_printf(MSG_ERROR, "No '/' in the global control interface " 5001e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt "file"); 50161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_free(interfaces->global_iface_path); 50261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->global_iface_path = NULL; 50361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 50461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 50561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 50661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *pos = '\0'; 50761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces->global_iface_name = pos + 1; 50831a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt#endif /* !CONFIG_CTRL_IFACE_UDP */ 50961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 51061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 51161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 51261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 51361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 5140ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidtstatic int hostapd_get_ctrl_iface_group(struct hapd_interfaces *interfaces, 5150ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt const char *group) 5160ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt{ 5170ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS 5180ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt struct group *grp; 5190ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt grp = getgrnam(group); 5200ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt if (grp == NULL) { 5210ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt wpa_printf(MSG_ERROR, "Unknown group '%s'", group); 5220ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt return -1; 5230ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt } 5240ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt interfaces->ctrl_iface_group = grp->gr_gid; 5250ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */ 5260ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt return 0; 5270ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt} 5280ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt 5290ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt 53096be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt#ifdef CONFIG_WPS 53196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidtstatic int gen_uuid(const char *txt_addr) 53296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt{ 53396be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt u8 addr[ETH_ALEN]; 53496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt u8 uuid[UUID_LEN]; 53596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt char buf[100]; 53696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt 53796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt if (hwaddr_aton(txt_addr, addr) < 0) 53896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt return -1; 53996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt 54096be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt uuid_gen_mac_addr(addr, uuid); 54196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt if (uuid_bin2str(uuid, buf, sizeof(buf)) < 0) 54296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt return -1; 54396be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt 54496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt printf("%s\n", buf); 54596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt 54696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt return 0; 54796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt} 54896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt#endif /* CONFIG_WPS */ 54996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt 55096be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt 551d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#ifndef HOSTAPD_CLEANUP_INTERVAL 552d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#define HOSTAPD_CLEANUP_INTERVAL 10 553d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* HOSTAPD_CLEANUP_INTERVAL */ 554d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 555d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic int hostapd_periodic_call(struct hostapd_iface *iface, void *ctx) 556d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 557d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt hostapd_periodic_iface(iface); 558d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return 0; 559d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 560d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 561d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 562d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt/* Periodic cleanup tasks */ 563d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtstatic void hostapd_periodic(void *eloop_ctx, void *timeout_ctx) 564d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 565d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct hapd_interfaces *interfaces = eloop_ctx; 566d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 567d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt eloop_register_timeout(HOSTAPD_CLEANUP_INTERVAL, 0, 568d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt hostapd_periodic, interfaces, NULL); 569d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt hostapd_for_each_interface(interfaces, hostapd_periodic_call, NULL); 570d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 571d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 572d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint main(int argc, char *argv[]) 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct hapd_interfaces interfaces; 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 1; 577cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t i, j; 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int c, debug = 0, daemonize = 0; 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pid_file = NULL; 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *log_file = NULL; 58175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen const char *entropy_file = NULL; 582cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt char **bss_config = NULL, **tmp_bss; 583cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt size_t num_bss_configs = 0; 584cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#ifdef CONFIG_DEBUG_LINUX_TRACING 585cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt int enable_trace_dbg = 0; 586cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#endif /* CONFIG_DEBUG_LINUX_TRACING */ 587d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int start_ifaces_in_sync = 0; 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_program_init()) 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 59261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt os_memset(&interfaces, 0, sizeof(interfaces)); 59361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.reload_config = hostapd_reload_config; 59461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.config_read_cb = hostapd_config_read; 59561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.for_each_interface = hostapd_for_each_interface; 59661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.ctrl_iface_init = hostapd_ctrl_iface_init; 59761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.ctrl_iface_deinit = hostapd_ctrl_iface_deinit; 59861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.driver_init = hostapd_driver_init; 59961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.global_iface_path = NULL; 60061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.global_iface_name = NULL; 60161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt interfaces.global_ctrl_sock = -1; 60231a29cc7ed87b62465c7e01f03484f4643d12309Dmitry Shmidt dl_list_init(&interfaces.global_ctrl_dst); 60361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (;;) { 605d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt c = getopt(argc, argv, "b:Bde:f:hKP:STtu:vg:G:"); 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (c < 0) 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (c) { 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'h': 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usage(); 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'd': 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt debug++; 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_debug_level > 0) 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_debug_level--; 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'B': 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt daemonize++; 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 62075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen case 'e': 62175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen entropy_file = optarg; 62275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen break; 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'f': 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt log_file = optarg; 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'K': 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_debug_show_keys++; 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'P': 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(pid_file); 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pid_file = os_rel2abs_path(optarg); 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 't': 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_debug_timestamp++; 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 636cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#ifdef CONFIG_DEBUG_LINUX_TRACING 637cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case 'T': 638cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt enable_trace_dbg = 1; 639cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt break; 640cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#endif /* CONFIG_DEBUG_LINUX_TRACING */ 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 'v': 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt show_version(); 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt exit(1); 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 64561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case 'g': 6461e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt if (hostapd_get_global_ctrl_iface(&interfaces, optarg)) 6471e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt return -1; 64861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 6490ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt case 'G': 6501e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt if (hostapd_get_ctrl_iface_group(&interfaces, optarg)) 6511e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt return -1; 6520ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt break; 653cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt case 'b': 654cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt tmp_bss = os_realloc_array(bss_config, 655cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt num_bss_configs + 1, 656cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt sizeof(char *)); 657cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (tmp_bss == NULL) 658cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto out; 659cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt bss_config = tmp_bss; 660cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt bss_config[num_bss_configs++] = optarg; 661cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt break; 662d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt case 'S': 663d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt start_ifaces_in_sync = 1; 664d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt break; 66596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt#ifdef CONFIG_WPS 66696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt case 'u': 66796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt return gen_uuid(optarg); 66896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt#endif /* CONFIG_WPS */ 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usage(); 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 675cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (optind == argc && interfaces.global_iface_path == NULL && 676cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt num_bss_configs == 0) 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usage(); 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg_register_ifname_cb(hostapd_msg_ifname_cb); 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (log_file) 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_debug_open_file(log_file); 683fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt else 684fb45fd5cfed8bdccd0859c7fc05449fc187e2d06Dmitry Shmidt wpa_debug_setup_stdout(); 685cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#ifdef CONFIG_DEBUG_LINUX_TRACING 686cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (enable_trace_dbg) { 687cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt int tret = wpa_debug_open_linux_tracing(); 688cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (tret) { 689cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to enable trace logging"); 690cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt return -1; 691cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 692cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 693cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#endif /* CONFIG_DEBUG_LINUX_TRACING */ 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt interfaces.count = argc - optind; 696cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (interfaces.count || num_bss_configs) { 697cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt interfaces.iface = os_calloc(interfaces.count + num_bss_configs, 69861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sizeof(struct hostapd_iface *)); 69961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (interfaces.iface == NULL) { 70061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "malloc failed"); 70161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 70261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7054b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (hostapd_global_init(&interfaces, entropy_file)) { 7067a53dbb56693ee9f55c0cab1a8297436511e8613Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to initialize global context"); 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7084b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt } 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 710d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt eloop_register_timeout(HOSTAPD_CLEANUP_INTERVAL, 0, 711d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt hostapd_periodic, &interfaces, NULL); 712d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 713d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (fst_global_init()) { 714d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_ERROR, 715d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "Failed to initialize global FST context"); 716d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt goto out; 717d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 718d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 719d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#if defined(CONFIG_FST) && defined(CONFIG_CTRL_IFACE) 720d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (!fst_global_add_ctrl(fst_ctrl_cli)) 721d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpa_printf(MSG_WARNING, "Failed to add CLI FST ctrl"); 722d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt#endif /* CONFIG_FST && CONFIG_CTRL_IFACE */ 723d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 724cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* Allocate and parse configuration for full interface files */ 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < interfaces.count; i++) { 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt interfaces.iface[i] = hostapd_interface_init(&interfaces, 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt argv[optind + i], 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt debug); 7294b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (!interfaces.iface[i]) { 7304b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to initialize interface"); 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 7324b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt } 733d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (start_ifaces_in_sync) 734d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt interfaces.iface[i]->need_to_start_in_sync = 1; 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 737cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* Allocate and parse configuration for per-BSS files */ 738cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (i = 0; i < num_bss_configs; i++) { 739cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface *iface; 740cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt char *fname; 741cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 742cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_INFO, "BSS config: %s", bss_config[i]); 743cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt fname = os_strchr(bss_config[i], ':'); 744cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (fname == NULL) { 745cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_printf(MSG_ERROR, 746cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt "Invalid BSS config identifier '%s'", 747cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt bss_config[i]); 748cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto out; 749cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 750cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt *fname++ = '\0'; 751cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt iface = hostapd_interface_init_bss(&interfaces, bss_config[i], 752cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt fname, debug); 753cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (iface == NULL) 754cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto out; 755cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (j = 0; j < interfaces.count; j++) { 756cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (interfaces.iface[j] == iface) 757cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt break; 758cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 759cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (j == interfaces.count) { 760cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt struct hostapd_iface **tmp; 761cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt tmp = os_realloc_array(interfaces.iface, 762cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt interfaces.count + 1, 763cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt sizeof(struct hostapd_iface *)); 764cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (tmp == NULL) { 765cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_interface_deinit_free(iface); 766cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto out; 767cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 768cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt interfaces.iface = tmp; 769cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt interfaces.iface[interfaces.count++] = iface; 770cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 771cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 772cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 773cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt /* 774cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * Enable configured interfaces. Depending on channel configuration, 775cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * this may complete full initialization before returning or use a 776cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * callback mechanism to complete setup in case of operations like HT 777cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * co-ex scans, ACS, or DFS are needed to determine channel parameters. 778cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * In such case, the interface will be enabled from eloop context within 779cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_global_run(). 780cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */ 781b96dad47218788efffa3db0fe7f1b54a7d19e366Dmitry Shmidt interfaces.terminate_on_error = interfaces.count; 782cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt for (i = 0; i < interfaces.count; i++) { 783cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt if (hostapd_driver_init(interfaces.iface[i]) || 784cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt hostapd_setup_interface(interfaces.iface[i])) 785cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt goto out; 786cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt } 787cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 78861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_global_ctrl_iface_init(&interfaces); 78961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 7904b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (hostapd_global_run(&interfaces, daemonize, pid_file)) { 7914b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt wpa_printf(MSG_ERROR, "Failed to start eloop"); 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto out; 7934b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt } 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = 0; 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out: 79861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hostapd_global_ctrl_iface_deinit(&interfaces); 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Deinitialize all interfaces */ 800a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt for (i = 0; i < interfaces.count; i++) { 801818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt if (!interfaces.iface[i]) 802818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt continue; 803a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt interfaces.iface[i]->driver_ap_teardown = 804a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt !!(interfaces.iface[i]->drv_flags & 805a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT); 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_interface_deinit_free(interfaces.iface[i]); 807a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt } 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(interfaces.iface); 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 810d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt eloop_cancel_timeout(hostapd_periodic, &interfaces, NULL); 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hostapd_global_deinit(pid_file); 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(pid_file); 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (log_file) 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_debug_close_file(); 816cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt wpa_debug_close_linux_tracing(); 817cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt 818cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt os_free(bss_config); 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 820d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt fst_global_deinit(); 821d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_program_deinit(); 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 826