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
310207e233ee2e741f7b2c124c1366e905ebb634c8Dmitry Shmidtstruct wowlan_triggers *wpa_get_wowlan_triggers(const char *wowlan_triggers,
320207e233ee2e741f7b2c124c1366e905ebb634c8Dmitry Shmidt						struct wpa_driver_capa *capa);
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstruct hapd_global {
351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	void **drv_priv;
361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	size_t drv_count;
371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt};
381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic struct hapd_global global;
401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_HOSTAPD_LOGGER
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module,
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      int level, const char *txt, size_t len)
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_data *hapd = ctx;
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *format, *module_str;
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int maxlen;
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int conf_syslog_level, conf_stdout_level;
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	unsigned int conf_syslog, conf_stdout;
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	maxlen = len + 100;
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	format = os_malloc(maxlen);
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!format)
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd && hapd->conf) {
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf_syslog_level = hapd->conf->logger_syslog_level;
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf_stdout_level = hapd->conf->logger_stdout_level;
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf_syslog = hapd->conf->logger_syslog;
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf_stdout = hapd->conf->logger_stdout;
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf_syslog_level = conf_stdout_level = 0;
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf_syslog = conf_stdout = (unsigned int) -1;
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (module) {
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case HOSTAPD_MODULE_IEEE80211:
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		module_str = "IEEE 802.11";
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case HOSTAPD_MODULE_IEEE8021X:
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		module_str = "IEEE 802.1X";
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case HOSTAPD_MODULE_RADIUS:
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		module_str = "RADIUS";
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case HOSTAPD_MODULE_WPA:
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		module_str = "WPA";
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case HOSTAPD_MODULE_DRIVER:
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		module_str = "DRIVER";
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case HOSTAPD_MODULE_IAPP:
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		module_str = "IAPP";
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case HOSTAPD_MODULE_MLME:
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		module_str = "MLME";
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	default:
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		module_str = NULL;
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd && hapd->conf && addr)
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_snprintf(format, maxlen, "%s: STA " MACSTR "%s%s: %s",
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    hapd->conf->iface, MAC2STR(addr),
9796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt			    module_str ? " " : "", module_str ? module_str : "",
9896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt			    txt);
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (hapd && hapd->conf)
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_snprintf(format, maxlen, "%s:%s%s %s",
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    hapd->conf->iface, module_str ? " " : "",
102661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt			    module_str ? module_str : "", txt);
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (addr)
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_snprintf(format, maxlen, "STA " MACSTR "%s%s: %s",
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    MAC2STR(addr), module_str ? " " : "",
106661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt			    module_str ? module_str : "", txt);
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_snprintf(format, maxlen, "%s%s%s",
109661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt			    module_str ? module_str : "",
110661b4f78e48c697429dc46154a4125892c001718Dmitry Shmidt			    module_str ? ": " : "", txt);
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((conf_stdout & module) && level >= conf_stdout_level) {
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_debug_print_timestamp();
114cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		wpa_printf(MSG_INFO, "%s", format);
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((conf_syslog & module) && level >= conf_syslog_level) {
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int priority;
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		switch (level) {
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case HOSTAPD_LEVEL_DEBUG_VERBOSE:
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case HOSTAPD_LEVEL_DEBUG:
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			priority = LOG_DEBUG;
1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case HOSTAPD_LEVEL_INFO:
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			priority = LOG_INFO;
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case HOSTAPD_LEVEL_NOTICE:
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			priority = LOG_NOTICE;
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case HOSTAPD_LEVEL_WARNING:
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			priority = LOG_WARNING;
1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		default:
1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			priority = LOG_INFO;
1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		syslog(priority, "%s", format);
1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */
1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(format);
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_HOSTAPD_LOGGER */
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
148cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_driver_init - Preparate driver interface
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_driver_init(struct hostapd_iface *iface)
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_init_params params;
1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t i;
1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_data *hapd = iface->bss[0];
1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_bss_config *conf = hapd->conf;
1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 *b = conf->bssid;
1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_driver_capa capa;
1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->hapd_init == NULL) {
1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "No hostapd driver wrapper available");
1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Initialize the driver interface */
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5]))
1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		b = NULL;
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(&params, 0, sizeof(params));
1691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	for (i = 0; wpa_drivers[i]; i++) {
1701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpa_drivers[i] != hapd->driver)
1711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			continue;
1721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
1731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (global.drv_priv[i] == NULL &&
1741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    wpa_drivers[i]->global_init) {
1751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			global.drv_priv[i] = wpa_drivers[i]->global_init();
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;
18961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	params.ssid = hapd->conf->ssid.ssid;
1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.ssid_len = hapd->conf->ssid.ssid_len;
1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.test_socket = hapd->conf->test_socket;
1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.use_pae_group_addr = hapd->conf->use_pae_group_addr;
1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.num_bridge = hapd->iface->num_bss;
19561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	params.bridge = os_calloc(hapd->iface->num_bss, sizeof(char *));
1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (params.bridge == NULL)
1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < hapd->iface->num_bss; i++) {
1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct hostapd_data *bss = hapd->iface->bss[i];
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (bss->conf->bridge[0])
2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			params.bridge[i] = bss->conf->bridge;
2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.own_addr = hapd->own_addr;
2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hapd->drv_priv = hapd->driver->hapd_init(hapd, &params);
2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(params.bridge);
2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->drv_priv == NULL) {
2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "%s driver initialization failed.",
2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   hapd->driver->name);
2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hapd->driver = NULL;
2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver->get_capa &&
2161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    hapd->driver->get_capa(hapd->drv_priv, &capa) == 0) {
2170207e233ee2e741f7b2c124c1366e905ebb634c8Dmitry Shmidt		struct wowlan_triggers *triggs;
2180207e233ee2e741f7b2c124c1366e905ebb634c8Dmitry Shmidt
2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		iface->drv_flags = capa.flags;
2201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		iface->probe_resp_offloads = capa.probe_resp_offloads;
221444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt		iface->extended_capa = capa.extended_capa;
222444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt		iface->extended_capa_mask = capa.extended_capa_mask;
223444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt		iface->extended_capa_len = capa.extended_capa_len;
2248bae4138a0356709720a96f3e50b4d734e532c12Dmitry Shmidt		iface->drv_max_acl_mac_addrs = capa.max_acl_mac_addrs;
2250207e233ee2e741f7b2c124c1366e905ebb634c8Dmitry Shmidt
2260207e233ee2e741f7b2c124c1366e905ebb634c8Dmitry Shmidt		triggs = wpa_get_wowlan_triggers(conf->wowlan_triggers, &capa);
2270207e233ee2e741f7b2c124c1366e905ebb634c8Dmitry Shmidt		if (triggs && hapd->driver->set_wowlan) {
2280207e233ee2e741f7b2c124c1366e905ebb634c8Dmitry Shmidt			if (hapd->driver->set_wowlan(hapd->drv_priv, triggs))
2290207e233ee2e741f7b2c124c1366e905ebb634c8Dmitry Shmidt				wpa_printf(MSG_ERROR, "set_wowlan failed");
2300207e233ee2e741f7b2c124c1366e905ebb634c8Dmitry Shmidt		}
2310207e233ee2e741f7b2c124c1366e905ebb634c8Dmitry Shmidt		os_free(triggs);
2321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
238cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt/**
239cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * hostapd_interface_init - Read configuration file and init BSS data
240cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt *
241cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * This function is used to parse configuration file for a full interface (one
242cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * or more BSSes sharing the same radio) and allocate memory for the BSS
243cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt * interfaces. No actiual driver operations are started.
244cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt */
2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct hostapd_iface *
2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidthostapd_interface_init(struct hapd_interfaces *interfaces,
2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		       const char *config_fname, int debug)
2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_iface *iface;
2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int k;
2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_ERROR, "Configuration file: %s", config_fname);
253cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	iface = hostapd_init(interfaces, config_fname);
2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!iface)
2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	iface->interfaces = interfaces;
2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (k = 0; k < debug; k++) {
2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (iface->bss[0]->conf->logger_stdout_level > 0)
2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			iface->bss[0]->conf->logger_stdout_level--;
2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
263cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	if (iface->conf->bss[0]->iface[0] == '\0' &&
2644b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt	    !hostapd_drv_none(iface->bss[0])) {
2654b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt		wpa_printf(MSG_ERROR, "Interface name not specified in %s",
2664b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt			   config_fname);
2674b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt		hostapd_interface_deinit_free(iface);
2684b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt		return NULL;
2694b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt	}
2704b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt
2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return iface;
2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * handle_term - SIGINT and SIGTERM handler to terminate hostapd process
2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_term(int sig, void *signal_ctx)
2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "Signal %d received - terminating", sig);
2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_terminate();
2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS
2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int handle_reload_iface(struct hostapd_iface *iface, void *ctx)
2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hostapd_reload_config(iface) < 0) {
2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_WARNING, "Failed to read new configuration "
2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "file - continuing with old.");
2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * handle_reload - SIGHUP handler to reload configuration
2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_reload(int sig, void *signal_ctx)
3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hapd_interfaces *interfaces = signal_ctx;
3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "Signal %d received - reloading configuration",
3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   sig);
3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hostapd_for_each_interface(interfaces, handle_reload_iface, NULL);
3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void handle_dump_state(int sig, void *signal_ctx)
3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
311fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	/* Not used anymore - ignore signal */
3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */
3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinenstatic int hostapd_global_init(struct hapd_interfaces *interfaces,
31775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			       const char *entropy_file)
3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	int i;
3201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	os_memset(&global, 0, sizeof(global));
3221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hostapd_logger_register_cb(hostapd_logger_cb);
3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (eap_server_register_methods()) {
3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Failed to register EAP methods");
3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (eloop_init()) {
3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Failed to initialize event loop");
3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	random_init(entropy_file);
3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS
3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_register_signal(SIGHUP, handle_reload, interfaces);
3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_register_signal(SIGUSR1, handle_dump_state, interfaces);
3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */
3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_register_signal_terminate(handle_term, interfaces);
3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS
3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	openlog("hostapd", 0, LOG_DAEMON);
3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */
3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	for (i = 0; wpa_drivers[i]; i++)
3481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		global.drv_count++;
3491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (global.drv_count == 0) {
3501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_printf(MSG_ERROR, "No drivers enabled");
3511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
3521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
35361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	global.drv_priv = os_calloc(global.drv_count, sizeof(void *));
3541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (global.drv_priv == NULL)
3551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
3561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void hostapd_global_deinit(const char *pid_file)
3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	int i;
3641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	for (i = 0; wpa_drivers[i] && global.drv_priv; i++) {
3661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (!global.drv_priv[i])
3671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			continue;
3681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_drivers[i]->global_deinit(global.drv_priv[i]);
3691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
3701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	os_free(global.drv_priv);
3711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	global.drv_priv = NULL;
3721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_SERVER_TNC
3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	tncs_global_deinit();
3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_SERVER_TNC */
3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	random_deinit();
3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_destroy();
3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS
3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	closelog();
3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */
3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eap_server_unregister_methods();
3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_daemonize_terminate(pid_file);
3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int hostapd_global_run(struct hapd_interfaces *ifaces, int daemonize,
3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      const char *pid_file)
3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_SERVER_TNC
3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int tnc = 0;
3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t i, k;
3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; !tnc && i < ifaces->count; i++) {
3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		for (k = 0; k < ifaces->iface[i]->num_bss; k++) {
4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (ifaces->iface[i]->bss[0]->conf->tnc) {
4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				tnc++;
4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break;
4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			}
4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (tnc && tncs_global_init() < 0) {
4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Failed to initialize TNCS");
4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_SERVER_TNC */
4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (daemonize && os_daemonize(pid_file)) {
4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		perror("daemon");
4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_run();
4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void show_version(void)
4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	fprintf(stderr,
4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"hostapd v" VERSION_STR "\n"
4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"User space daemon for IEEE 802.11 AP management,\n"
4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator\n"
430fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		"Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi> "
4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"and contributors\n");
4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void usage(void)
4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	show_version();
4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	fprintf(stderr,
4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"\n"
44075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		"usage: hostapd [-hdBKtv] [-P <PID file>] [-e <entropy file>] "
44161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		"\\\n"
4420ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt		"         [-g <global ctrl_iface>] [-G <group>] \\\n"
4430ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt		"         <configuration file(s)>\n"
4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"\n"
4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"options:\n"
4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"   -h   show this usage\n"
4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"   -d   show more debug messages (-dd for even more)\n"
4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"   -B   run daemon in the background\n"
44975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		"   -e   entropy file\n"
45061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		"   -g   global control interface path\n"
4510ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt		"   -G   group for control interfaces\n"
4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"   -P   PID file\n"
4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"   -K   include key data in debug messages\n"
4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_DEBUG_FILE
4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"   -f   log output to debug file instead of stdout\n"
4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_DEBUG_FILE */
457cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#ifdef CONFIG_DEBUG_LINUX_TRACING
458cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		"   -T = record to Linux tracing in addition to logging\n"
459cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		"        (records all messages regardless of debug verbosity)\n"
460cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#endif /* CONFIG_DEBUG_LINUX_TRACING */
4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"   -t   include timestamps in some debug messages\n"
4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"   -v   show hostapd version\n");
4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	exit(1);
4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * hostapd_msg_ifname_cb(void *ctx)
4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_data *hapd = ctx;
471cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	if (hapd && hapd->iconf && hapd->iconf->bss &&
472cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	    hapd->iconf->num_bss > 0 && hapd->iconf->bss[0])
473cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		return hapd->iconf->bss[0]->iface;
4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return NULL;
4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
47861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic int hostapd_get_global_ctrl_iface(struct hapd_interfaces *interfaces,
47961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					 const char *path)
48061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{
48161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	char *pos;
48261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	os_free(interfaces->global_iface_path);
48361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	interfaces->global_iface_path = os_strdup(path);
48461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (interfaces->global_iface_path == NULL)
48561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
48661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos = os_strrchr(interfaces->global_iface_path, '/');
48761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (pos == NULL) {
4881e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt		wpa_printf(MSG_ERROR, "No '/' in the global control interface "
4891e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt			   "file");
49061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		os_free(interfaces->global_iface_path);
49161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		interfaces->global_iface_path = NULL;
49261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
49361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
49461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
49561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	*pos = '\0';
49661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	interfaces->global_iface_name = pos + 1;
49761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
49861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	return 0;
49961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}
50061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
50161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
5020ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidtstatic int hostapd_get_ctrl_iface_group(struct hapd_interfaces *interfaces,
5030ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt					const char *group)
5040ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt{
5050ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt#ifndef CONFIG_NATIVE_WINDOWS
5060ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt	struct group *grp;
5070ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt	grp = getgrnam(group);
5080ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt	if (grp == NULL) {
5090ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt		wpa_printf(MSG_ERROR, "Unknown group '%s'", group);
5100ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt		return -1;
5110ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt	}
5120ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt	interfaces->ctrl_iface_group = grp->gr_gid;
5130ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS */
5140ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt	return 0;
5150ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt}
5160ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt
5170ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt
51896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt#ifdef CONFIG_WPS
51996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidtstatic int gen_uuid(const char *txt_addr)
52096be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt{
52196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt	u8 addr[ETH_ALEN];
52296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt	u8 uuid[UUID_LEN];
52396be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt	char buf[100];
52496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt
52596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt	if (hwaddr_aton(txt_addr, addr) < 0)
52696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt		return -1;
52796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt
52896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt	uuid_gen_mac_addr(addr, uuid);
52996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt	if (uuid_bin2str(uuid, buf, sizeof(buf)) < 0)
53096be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt		return -1;
53196be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt
53296be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt	printf("%s\n", buf);
53396be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt
53496be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt	return 0;
53596be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt}
53696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt#endif /* CONFIG_WPS */
53796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt
53896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt
5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint main(int argc, char *argv[])
5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hapd_interfaces interfaces;
5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret = 1;
543cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	size_t i, j;
5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int c, debug = 0, daemonize = 0;
5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pid_file = NULL;
5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *log_file = NULL;
54775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	const char *entropy_file = NULL;
548cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	char **bss_config = NULL, **tmp_bss;
549cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	size_t num_bss_configs = 0;
550cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#ifdef CONFIG_DEBUG_LINUX_TRACING
551cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	int enable_trace_dbg = 0;
552cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#endif /* CONFIG_DEBUG_LINUX_TRACING */
5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_program_init())
5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
55761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	os_memset(&interfaces, 0, sizeof(interfaces));
55861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	interfaces.reload_config = hostapd_reload_config;
55961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	interfaces.config_read_cb = hostapd_config_read;
56061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	interfaces.for_each_interface = hostapd_for_each_interface;
56161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	interfaces.ctrl_iface_init = hostapd_ctrl_iface_init;
56261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	interfaces.ctrl_iface_deinit = hostapd_ctrl_iface_deinit;
56361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	interfaces.driver_init = hostapd_driver_init;
56461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	interfaces.global_iface_path = NULL;
56561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	interfaces.global_iface_name = NULL;
56661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	interfaces.global_ctrl_sock = -1;
56761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (;;) {
56996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt		c = getopt(argc, argv, "b:Bde:f:hKP:Ttu:vg:G:");
5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (c < 0)
5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		switch (c) {
5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'h':
5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			usage();
5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'd':
5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			debug++;
5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (wpa_debug_level > 0)
5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_debug_level--;
5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'B':
5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			daemonize++;
5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
58475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		case 'e':
58575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			entropy_file = optarg;
58675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			break;
5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'f':
5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			log_file = optarg;
5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'K':
5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_debug_show_keys++;
5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'P':
5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(pid_file);
5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pid_file = os_rel2abs_path(optarg);
5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 't':
5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_debug_timestamp++;
5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
600cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#ifdef CONFIG_DEBUG_LINUX_TRACING
601cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		case 'T':
602cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			enable_trace_dbg = 1;
603cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			break;
604cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#endif /* CONFIG_DEBUG_LINUX_TRACING */
6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		case 'v':
6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			show_version();
6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			exit(1);
6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
60961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		case 'g':
6101e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt			if (hostapd_get_global_ctrl_iface(&interfaces, optarg))
6111e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt				return -1;
61261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			break;
6130ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt		case 'G':
6141e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt			if (hostapd_get_ctrl_iface_group(&interfaces, optarg))
6151e78e76961664775f58b139f8c6388cfa0485f3dDmitry Shmidt				return -1;
6160ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt			break;
617cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		case 'b':
618cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			tmp_bss = os_realloc_array(bss_config,
619cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt						   num_bss_configs + 1,
620cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt						   sizeof(char *));
621cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			if (tmp_bss == NULL)
622cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt				goto out;
623cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			bss_config = tmp_bss;
624cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			bss_config[num_bss_configs++] = optarg;
625cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			break;
62696be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt#ifdef CONFIG_WPS
62796be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt		case 'u':
62896be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt			return gen_uuid(optarg);
62996be6222df414a7dde5c5b1b72df22e67b1a77fcDmitry Shmidt#endif /* CONFIG_WPS */
6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		default:
6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			usage();
6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
636cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	if (optind == argc && interfaces.global_iface_path == NULL &&
637cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	    num_bss_configs == 0)
6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		usage();
6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_msg_register_ifname_cb(hostapd_msg_ifname_cb);
6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (log_file)
6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_debug_open_file(log_file);
644cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#ifdef CONFIG_DEBUG_LINUX_TRACING
645cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	if (enable_trace_dbg) {
646cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		int tret = wpa_debug_open_linux_tracing();
647cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		if (tret) {
648cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			wpa_printf(MSG_ERROR, "Failed to enable trace logging");
649cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			return -1;
650cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		}
651cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	}
652cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt#endif /* CONFIG_DEBUG_LINUX_TRACING */
6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	interfaces.count = argc - optind;
655cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	if (interfaces.count || num_bss_configs) {
656cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		interfaces.iface = os_calloc(interfaces.count + num_bss_configs,
65761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					     sizeof(struct hostapd_iface *));
65861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (interfaces.iface == NULL) {
65961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			wpa_printf(MSG_ERROR, "malloc failed");
66061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			return -1;
66161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		}
6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6644b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt	if (hostapd_global_init(&interfaces, entropy_file)) {
6654b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt		wpa_printf(MSG_ERROR, "Failed to initilize global context");
6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
6674b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt	}
6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
669cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	/* Allocate and parse configuration for full interface files */
6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < interfaces.count; i++) {
6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		interfaces.iface[i] = hostapd_interface_init(&interfaces,
6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							     argv[optind + i],
6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							     debug);
6744b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt		if (!interfaces.iface[i]) {
6754b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt			wpa_printf(MSG_ERROR, "Failed to initialize interface");
6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto out;
6774b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt		}
6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
680cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	/* Allocate and parse configuration for per-BSS files */
681cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	for (i = 0; i < num_bss_configs; i++) {
682cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		struct hostapd_iface *iface;
683cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		char *fname;
684cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt
685cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		wpa_printf(MSG_INFO, "BSS config: %s", bss_config[i]);
686cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		fname = os_strchr(bss_config[i], ':');
687cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		if (fname == NULL) {
688cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			wpa_printf(MSG_ERROR,
689cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt				   "Invalid BSS config identifier '%s'",
690cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt				   bss_config[i]);
691cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			goto out;
692cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		}
693cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		*fname++ = '\0';
694cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		iface = hostapd_interface_init_bss(&interfaces, bss_config[i],
695cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt						   fname, debug);
696cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		if (iface == NULL)
697cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			goto out;
698cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		for (j = 0; j < interfaces.count; j++) {
699cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			if (interfaces.iface[j] == iface)
700cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt				break;
701cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		}
702cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		if (j == interfaces.count) {
703cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			struct hostapd_iface **tmp;
704cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			tmp = os_realloc_array(interfaces.iface,
705cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt					       interfaces.count + 1,
706cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt					       sizeof(struct hostapd_iface *));
707cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			if (tmp == NULL) {
708cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt				hostapd_interface_deinit_free(iface);
709cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt				goto out;
710cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			}
711cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			interfaces.iface = tmp;
712cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			interfaces.iface[interfaces.count++] = iface;
713cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		}
714cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	}
715cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt
716cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	/*
717cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	 * Enable configured interfaces. Depending on channel configuration,
718cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	 * this may complete full initialization before returning or use a
719cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	 * callback mechanism to complete setup in case of operations like HT
720cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	 * co-ex scans, ACS, or DFS are needed to determine channel parameters.
721cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	 * In such case, the interface will be enabled from eloop context within
722cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	 * hostapd_global_run().
723cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	 */
724b96dad47218788efffa3db0fe7f1b54a7d19e366Dmitry Shmidt	interfaces.terminate_on_error = interfaces.count;
725cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	for (i = 0; i < interfaces.count; i++) {
726cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		if (hostapd_driver_init(interfaces.iface[i]) ||
727cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		    hostapd_setup_interface(interfaces.iface[i]))
728cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			goto out;
729cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	}
730cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt
73161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	hostapd_global_ctrl_iface_init(&interfaces);
73261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
7334b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt	if (hostapd_global_run(&interfaces, daemonize, pid_file)) {
7344b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt		wpa_printf(MSG_ERROR, "Failed to start eloop");
7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		goto out;
7364b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt	}
7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = 0;
7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out:
74161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	hostapd_global_ctrl_iface_deinit(&interfaces);
7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Deinitialize all interfaces */
743a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt	for (i = 0; i < interfaces.count; i++) {
744818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt		if (!interfaces.iface[i])
745818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt			continue;
746a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt		interfaces.iface[i]->driver_ap_teardown =
747a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt			!!(interfaces.iface[i]->drv_flags &
748a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt			   WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hostapd_interface_deinit_free(interfaces.iface[i]);
750a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt	}
7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(interfaces.iface);
7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hostapd_global_deinit(pid_file);
7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(pid_file);
7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (log_file)
7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_debug_close_file();
758cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	wpa_debug_close_linux_tracing();
759cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt
760cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	os_free(bss_config);
7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_program_deinit();
7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return ret;
7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
766