Parcourir la source

Move main() and configuration file related functions into main.c

This makes it easier to share hostapd.c with wpa_supplicant
Jouni Malinen il y a 16 ans
Parent
commit
5c333467b3
4 fichiers modifiés avec 450 ajouts et 407 suppressions
  1. 1 1
      hostapd/Makefile
  2. 37 406
      hostapd/hostapd.c
  3. 6 0
      hostapd/hostapd.h
  4. 406 0
      hostapd/main.c

+ 1 - 1
hostapd/Makefile

@@ -38,7 +38,7 @@ CFLAGS += -DCONFIG_NATIVE_WINDOWS
 LIBS += -lws2_32
 endif
 
-OBJS =	hostapd.o ieee802_1x.o eapol_sm.o \
+OBJS =	hostapd.o main.o ieee802_1x.o eapol_sm.o \
 	config.o ieee802_11_auth.o \
 	sta_info.o wpa.o \
 	drivers.o preauth.o pmksa_cache.o \

+ 37 - 406
hostapd/hostapd.c

@@ -13,9 +13,6 @@
  */
 
 #include "includes.h"
-#ifndef CONFIG_NATIVE_WINDOWS
-#include <syslog.h>
-#endif /* CONFIG_NATIVE_WINDOWS */
 
 #include "eloop.h"
 #include "hostapd.h"
@@ -53,135 +50,7 @@ static int hostapd_flush_old_stations(struct hostapd_data *hapd);
 static int hostapd_setup_wpa(struct hostapd_data *hapd);
 static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd);
 
-struct hapd_interfaces {
-	size_t count;
-	struct hostapd_iface **iface;
-};
-
-
 extern int wpa_debug_level;
-extern int wpa_debug_show_keys;
-extern int wpa_debug_timestamp;
-
-
-int hostapd_for_each_interface(int (*cb)(struct hostapd_iface *iface,
-					 void *ctx), void *ctx)
-{
-	struct hapd_interfaces *interfaces = eloop_get_user_data();
-	size_t i;
-	int ret;
-
-	for (i = 0; i < interfaces->count; i++) {
-		ret = cb(interfaces->iface[i], ctx);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
-
-
-#ifndef CONFIG_NO_HOSTAPD_LOGGER
-static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module,
-			      int level, const char *txt, size_t len)
-{
-	struct hostapd_data *hapd = ctx;
-	char *format, *module_str;
-	int maxlen;
-	int conf_syslog_level, conf_stdout_level;
-	unsigned int conf_syslog, conf_stdout;
-
-	maxlen = len + 100;
-	format = os_malloc(maxlen);
-	if (!format)
-		return;
-
-	if (hapd && hapd->conf) {
-		conf_syslog_level = hapd->conf->logger_syslog_level;
-		conf_stdout_level = hapd->conf->logger_stdout_level;
-		conf_syslog = hapd->conf->logger_syslog;
-		conf_stdout = hapd->conf->logger_stdout;
-	} else {
-		conf_syslog_level = conf_stdout_level = 0;
-		conf_syslog = conf_stdout = (unsigned int) -1;
-	}
-
-	switch (module) {
-	case HOSTAPD_MODULE_IEEE80211:
-		module_str = "IEEE 802.11";
-		break;
-	case HOSTAPD_MODULE_IEEE8021X:
-		module_str = "IEEE 802.1X";
-		break;
-	case HOSTAPD_MODULE_RADIUS:
-		module_str = "RADIUS";
-		break;
-	case HOSTAPD_MODULE_WPA:
-		module_str = "WPA";
-		break;
-	case HOSTAPD_MODULE_DRIVER:
-		module_str = "DRIVER";
-		break;
-	case HOSTAPD_MODULE_IAPP:
-		module_str = "IAPP";
-		break;
-	case HOSTAPD_MODULE_MLME:
-		module_str = "MLME";
-		break;
-	default:
-		module_str = NULL;
-		break;
-	}
-
-	if (hapd && hapd->conf && addr)
-		os_snprintf(format, maxlen, "%s: STA " MACSTR "%s%s: %s",
-			    hapd->conf->iface, MAC2STR(addr),
-			    module_str ? " " : "", module_str, txt);
-	else if (hapd && hapd->conf)
-		os_snprintf(format, maxlen, "%s:%s%s %s",
-			    hapd->conf->iface, module_str ? " " : "",
-			    module_str, txt);
-	else if (addr)
-		os_snprintf(format, maxlen, "STA " MACSTR "%s%s: %s",
-			    MAC2STR(addr), module_str ? " " : "",
-			    module_str, txt);
-	else
-		os_snprintf(format, maxlen, "%s%s%s",
-			    module_str, module_str ? ": " : "", txt);
-
-	if ((conf_stdout & module) && level >= conf_stdout_level) {
-		wpa_debug_print_timestamp();
-		printf("%s\n", format);
-	}
-
-#ifndef CONFIG_NATIVE_WINDOWS
-	if ((conf_syslog & module) && level >= conf_syslog_level) {
-		int priority;
-		switch (level) {
-		case HOSTAPD_LEVEL_DEBUG_VERBOSE:
-		case HOSTAPD_LEVEL_DEBUG:
-			priority = LOG_DEBUG;
-			break;
-		case HOSTAPD_LEVEL_INFO:
-			priority = LOG_INFO;
-			break;
-		case HOSTAPD_LEVEL_NOTICE:
-			priority = LOG_NOTICE;
-			break;
-		case HOSTAPD_LEVEL_WARNING:
-			priority = LOG_WARNING;
-			break;
-		default:
-			priority = LOG_INFO;
-			break;
-		}
-		syslog(priority, "%s", format);
-	}
-#endif /* CONFIG_NATIVE_WINDOWS */
-
-	os_free(format);
-}
-#endif /* CONFIG_NO_HOSTAPD_LOGGER */
 
 
 #ifdef EAP_SERVER
@@ -203,16 +72,6 @@ static void hostapd_sim_db_cb(void *ctx, void *session_ctx)
 #endif /* EAP_SERVER */
 
 
-/**
- * handle_term - SIGINT and SIGTERM handler to terminate hostapd process
- */
-static void handle_term(int sig, void *eloop_ctx, void *signal_ctx)
-{
-	wpa_printf(MSG_DEBUG, "Signal %d received - terminating", sig);
-	eloop_terminate();
-}
-
-
 static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
 				  struct wpa_auth_config *wconf)
 {
@@ -308,26 +167,13 @@ int hostapd_reload_config(struct hostapd_iface *iface)
 }
 
 
-#ifndef CONFIG_NATIVE_WINDOWS
-/**
- * handle_reload - SIGHUP handler to reload configuration
- */
-static void handle_reload(int sig, void *eloop_ctx, void *signal_ctx)
+int handle_reload_iface(struct hostapd_iface *iface, void *ctx)
 {
-	struct hapd_interfaces *hapds = (struct hapd_interfaces *) eloop_ctx;
-	size_t i;
-
-	wpa_printf(MSG_DEBUG, "Signal %d received - reloading configuration",
-		   sig);
-
-	for (i = 0; i < hapds->count; i++) {
-		if (hostapd_reload_config(hapds->iface[i]) < 0) {
-			wpa_printf(MSG_WARNING, "Failed to read new "
-				   "configuration file - continuing with "
-				   "old.");
-			continue;
-		}
+	if (hostapd_reload_config(iface) < 0) {
+		wpa_printf(MSG_WARNING, "Failed to read new configuration "
+			   "file - continuing with old.");
 	}
+	return 0;
 }
 
 
@@ -430,23 +276,19 @@ static void hostapd_dump_state(struct hostapd_data *hapd)
 	}
 	fclose(f);
 }
-#endif /* HOSTAPD_DUMP_STATE */
 
 
-static void handle_dump_state(int sig, void *eloop_ctx, void *signal_ctx)
+int handle_dump_state_iface(struct hostapd_iface *iface, void *ctx)
 {
-#ifdef HOSTAPD_DUMP_STATE
-	struct hapd_interfaces *hapds = (struct hapd_interfaces *) eloop_ctx;
-	size_t i, j;
+	size_t i;
 
-	for (i = 0; i < hapds->count; i++) {
-		struct hostapd_iface *hapd_iface = hapds->iface[i];
-		for (j = 0; j < hapd_iface->num_bss; j++)
-			hostapd_dump_state(hapd_iface->bss[j]);
-	}
-#endif /* HOSTAPD_DUMP_STATE */
+	for (i = 0; i < iface->num_bss; i++)
+		hostapd_dump_state(iface->bss[i]);
+
+	return 0;
 }
-#endif /* CONFIG_NATIVE_WINDOWS */
+#endif /* HOSTAPD_DUMP_STATE */
+
 
 static void hostapd_broadcast_key_clear_iface(struct hostapd_data *hapd,
 					      char *ifname)
@@ -895,23 +737,31 @@ static int hostapd_wpa_auth_for_each_sta(
 }
 
 
+struct wpa_auth_iface_iter_data {
+	int (*cb)(struct wpa_authenticator *sm, void *ctx);
+	void *cb_ctx;
+};
+
+static int wpa_auth_iface_iter(struct hostapd_iface *iface, void *ctx)
+{
+	struct wpa_auth_iface_iter_data *data = ctx;
+	size_t i;
+	for (i = 0; i < iface->num_bss; i++) {
+		if (data->cb(iface->bss[i]->wpa_auth, data->cb_ctx))
+			return 1;
+	}
+	return 0;
+}
+
+
 static int hostapd_wpa_auth_for_each_auth(
 	void *ctx, int (*cb)(struct wpa_authenticator *sm, void *ctx),
 	void *cb_ctx)
 {
-	struct hostapd_data *ohapd;
-	size_t i, j;
-	struct hapd_interfaces *interfaces = eloop_get_user_data();
-
-	for (i = 0; i < interfaces->count; i++) {
-		for (j = 0; j < interfaces->iface[i]->num_bss; j++) {
-			ohapd = interfaces->iface[i]->bss[j];
-			if (cb(ohapd->wpa_auth, cb_ctx))
-				return 1;
-		}
-	}
-
-	return 0;
+	struct wpa_auth_iface_iter_data data;
+	data.cb = cb;
+	data.cb_ctx = cb_ctx;
+	return hostapd_for_each_interface(wpa_auth_iface_iter, &data);
 }
 
 
@@ -1597,7 +1447,7 @@ static int setup_interface(struct hostapd_iface *iface)
  * Flushes old stations, sets the channel, encryption,
  * beacons, and WDS links based on the configuration.
  */
-static int hostapd_setup_interface(struct hostapd_iface *iface)
+int hostapd_setup_interface(struct hostapd_iface *iface)
 {
 	int ret;
 
@@ -1616,38 +1466,6 @@ static int hostapd_setup_interface(struct hostapd_iface *iface)
 }
 
 
-static void show_version(void)
-{
-	fprintf(stderr,
-		"hostapd v" VERSION_STR "\n"
-		"User space daemon for IEEE 802.11 AP management,\n"
-		"IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator\n"
-		"Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi> "
-		"and contributors\n");
-}
-
-
-static void usage(void)
-{
-	show_version();
-	fprintf(stderr,
-		"\n"
-		"usage: hostapd [-hdBKtv] [-P <PID file>] "
-		"<configuration file(s)>\n"
-		"\n"
-		"options:\n"
-		"   -h   show this usage\n"
-		"   -d   show more debug messages (-dd for even more)\n"
-		"   -B   run daemon in the background\n"
-		"   -P   PID file\n"
-		"   -K   include key data in debug messages\n"
-		"   -t   include timestamps in some debug messages\n"
-		"   -v   show hostapd version\n");
-
-	exit(1);
-}
-
-
 /**
  * hostapd_alloc_bss_data - Allocate and initialize per-BSS data
  * @hapd_iface: Pointer to interface data
@@ -1746,7 +1564,7 @@ fail:
  * data. The allocated data buffer will be freed by calling
  * hostapd_cleanup_iface().
  */
-static struct hostapd_iface * hostapd_init(const char *config_file)
+struct hostapd_iface * hostapd_init(const char *config_file)
 {
 	struct hostapd_iface *hapd_iface = NULL;
 	struct hostapd_config *conf = NULL;
@@ -1800,53 +1618,7 @@ fail:
 }
 
 
-static int hostapd_global_init(struct hapd_interfaces *interfaces)
-{
-	hostapd_logger_register_cb(hostapd_logger_cb);
-
-	if (eap_server_register_methods()) {
-		wpa_printf(MSG_ERROR, "Failed to register EAP methods");
-		return -1;
-	}
-
-	if (eloop_init(interfaces)) {
-		wpa_printf(MSG_ERROR, "Failed to initialize event loop");
-		return -1;
-	}
-
-#ifndef CONFIG_NATIVE_WINDOWS
-	eloop_register_signal(SIGHUP, handle_reload, NULL);
-	eloop_register_signal(SIGUSR1, handle_dump_state, NULL);
-#endif /* CONFIG_NATIVE_WINDOWS */
-	eloop_register_signal_terminate(handle_term, NULL);
-
-#ifndef CONFIG_NATIVE_WINDOWS
-	openlog("hostapd", 0, LOG_DAEMON);
-#endif /* CONFIG_NATIVE_WINDOWS */
-
-	return 0;
-}
-
-
-static void hostapd_global_deinit(const char *pid_file)
-{
-#ifdef EAP_SERVER_TNC
-	tncs_global_deinit();
-#endif /* EAP_SERVER_TNC */
-
-	eloop_destroy();
-
-#ifndef CONFIG_NATIVE_WINDOWS
-	closelog();
-#endif /* CONFIG_NATIVE_WINDOWS */
-
-	eap_server_unregister_methods();
-
-	os_daemonize_terminate(pid_file);
-}
-
-
-static void hostapd_interface_deinit(struct hostapd_iface *iface)
+void hostapd_interface_deinit(struct hostapd_iface *iface)
 {
 	size_t j;
 
@@ -1866,144 +1638,3 @@ static void hostapd_interface_deinit(struct hostapd_iface *iface)
 		os_free(iface->bss[j]);
 	hostapd_cleanup_iface(iface);
 }
-
-
-static struct hostapd_iface * hostapd_interface_init(const char *config_fname,
-						     int debug)
-{
-	struct hostapd_iface *iface;
-	int k;
-
-	wpa_printf(MSG_ERROR, "Configuration file: %s", config_fname);
-	iface = hostapd_init(config_fname);
-	if (!iface)
-		return NULL;
-
-	for (k = 0; k < debug; k++) {
-		if (iface->bss[0]->conf->logger_stdout_level > 0)
-			iface->bss[0]->conf->logger_stdout_level--;
-	}
-
-	if (hostapd_setup_interface(iface)) {
-		hostapd_interface_deinit(iface);
-		return NULL;
-	}
-
-	return iface;
-}
-
-
-static int hostapd_global_run(struct hapd_interfaces *ifaces, int daemonize,
-			      const char *pid_file)
-{
-#ifdef EAP_SERVER_TNC
-	int tnc = 0;
-	size_t i, k;
-
-	for (i = 0; !tnc && i < ifaces->count; i++) {
-		for (k = 0; k < ifaces->iface[i]->num_bss; k++) {
-			if (ifaces->iface[i]->bss[0]->conf->tnc) {
-				tnc++;
-				break;
-			}
-		}
-	}
-
-	if (tnc && tncs_global_init() < 0) {
-		wpa_printf(MSG_ERROR, "Failed to initialize TNCS");
-		return -1;
-	}
-#endif /* EAP_SERVER_TNC */
-
-	if (daemonize && os_daemonize(pid_file)) {
-		perror("daemon");
-		return -1;
-	}
-
-	eloop_run();
-
-	return 0;
-}
-
-
-int main(int argc, char *argv[])
-{
-	struct hapd_interfaces interfaces;
-	int ret = 1;
-	size_t i;
-	int c, debug = 0, daemonize = 0;
-	const char *pid_file = NULL;
-
-	for (;;) {
-		c = getopt(argc, argv, "BdhKP:tv");
-		if (c < 0)
-			break;
-		switch (c) {
-		case 'h':
-			usage();
-			break;
-		case 'd':
-			debug++;
-			if (wpa_debug_level > 0)
-				wpa_debug_level--;
-			break;
-		case 'B':
-			daemonize++;
-			break;
-		case 'K':
-			wpa_debug_show_keys++;
-			break;
-		case 'P':
-			pid_file = optarg;
-			break;
-		case 't':
-			wpa_debug_timestamp++;
-			break;
-		case 'v':
-			show_version();
-			exit(1);
-			break;
-
-		default:
-			usage();
-			break;
-		}
-	}
-
-	if (optind == argc)
-		usage();
-
-	interfaces.count = argc - optind;
-	interfaces.iface = os_malloc(interfaces.count *
-				     sizeof(struct hostapd_iface *));
-	if (interfaces.iface == NULL) {
-		wpa_printf(MSG_ERROR, "malloc failed\n");
-		return -1;
-	}
-
-	if (hostapd_global_init(&interfaces))
-		return -1;
-
-	/* Initialize interfaces */
-	for (i = 0; i < interfaces.count; i++) {
-		interfaces.iface[i] = hostapd_interface_init(argv[optind + i],
-							     debug);
-		if (!interfaces.iface[i])
-			goto out;
-	}
-
-	if (hostapd_global_run(&interfaces, daemonize, pid_file))
-		goto out;
-
-	ret = 0;
-
- out:
-	/* Deinitialize all interfaces */
-	for (i = 0; i < interfaces.count; i++)
-		hostapd_interface_deinit(interfaces.iface[i]);
-	os_free(interfaces.iface);
-
-	hostapd_global_deinit(pid_file);
-
-	return ret;
-}

+ 6 - 0
hostapd/hostapd.h

@@ -159,6 +159,12 @@ struct hostapd_iface {
 };
 
 int hostapd_reload_config(struct hostapd_iface *iface);
+struct hostapd_iface * hostapd_init(const char *config_file);
+int hostapd_setup_interface(struct hostapd_iface *iface);
+void hostapd_interface_deinit(struct hostapd_iface *iface);
+int handle_reload_iface(struct hostapd_iface *iface, void *ctx);
+int handle_dump_state_iface(struct hostapd_iface *iface, void *ctx);
+
 int hostapd_for_each_interface(int (*cb)(struct hostapd_iface *iface,
 					 void *ctx), void *ctx);
 

+ 406 - 0
hostapd/main.c

@@ -0,0 +1,406 @@
+/*
+ * hostapd / main()
+ * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+#ifndef CONFIG_NATIVE_WINDOWS
+#include <syslog.h>
+#endif /* CONFIG_NATIVE_WINDOWS */
+
+#include "eloop.h"
+#include "hostapd.h"
+#include "version.h"
+#include "config.h"
+#include "eap_server/eap.h"
+#include "eap_server/tncs.h"
+
+
+extern int wpa_debug_level;
+extern int wpa_debug_show_keys;
+extern int wpa_debug_timestamp;
+
+
+struct hapd_interfaces {
+	size_t count;
+	struct hostapd_iface **iface;
+};
+
+
+int hostapd_for_each_interface(int (*cb)(struct hostapd_iface *iface,
+					 void *ctx), void *ctx)
+{
+	struct hapd_interfaces *interfaces = eloop_get_user_data();
+	size_t i;
+	int ret;
+
+	for (i = 0; i < interfaces->count; i++) {
+		ret = cb(interfaces->iface[i], ctx);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+
+#ifndef CONFIG_NO_HOSTAPD_LOGGER
+static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module,
+			      int level, const char *txt, size_t len)
+{
+	struct hostapd_data *hapd = ctx;
+	char *format, *module_str;
+	int maxlen;
+	int conf_syslog_level, conf_stdout_level;
+	unsigned int conf_syslog, conf_stdout;
+
+	maxlen = len + 100;
+	format = os_malloc(maxlen);
+	if (!format)
+		return;
+
+	if (hapd && hapd->conf) {
+		conf_syslog_level = hapd->conf->logger_syslog_level;
+		conf_stdout_level = hapd->conf->logger_stdout_level;
+		conf_syslog = hapd->conf->logger_syslog;
+		conf_stdout = hapd->conf->logger_stdout;
+	} else {
+		conf_syslog_level = conf_stdout_level = 0;
+		conf_syslog = conf_stdout = (unsigned int) -1;
+	}
+
+	switch (module) {
+	case HOSTAPD_MODULE_IEEE80211:
+		module_str = "IEEE 802.11";
+		break;
+	case HOSTAPD_MODULE_IEEE8021X:
+		module_str = "IEEE 802.1X";
+		break;
+	case HOSTAPD_MODULE_RADIUS:
+		module_str = "RADIUS";
+		break;
+	case HOSTAPD_MODULE_WPA:
+		module_str = "WPA";
+		break;
+	case HOSTAPD_MODULE_DRIVER:
+		module_str = "DRIVER";
+		break;
+	case HOSTAPD_MODULE_IAPP:
+		module_str = "IAPP";
+		break;
+	case HOSTAPD_MODULE_MLME:
+		module_str = "MLME";
+		break;
+	default:
+		module_str = NULL;
+		break;
+	}
+
+	if (hapd && hapd->conf && addr)
+		os_snprintf(format, maxlen, "%s: STA " MACSTR "%s%s: %s",
+			    hapd->conf->iface, MAC2STR(addr),
+			    module_str ? " " : "", module_str, txt);
+	else if (hapd && hapd->conf)
+		os_snprintf(format, maxlen, "%s:%s%s %s",
+			    hapd->conf->iface, module_str ? " " : "",
+			    module_str, txt);
+	else if (addr)
+		os_snprintf(format, maxlen, "STA " MACSTR "%s%s: %s",
+			    MAC2STR(addr), module_str ? " " : "",
+			    module_str, txt);
+	else
+		os_snprintf(format, maxlen, "%s%s%s",
+			    module_str, module_str ? ": " : "", txt);
+
+	if ((conf_stdout & module) && level >= conf_stdout_level) {
+		wpa_debug_print_timestamp();
+		printf("%s\n", format);
+	}
+
+#ifndef CONFIG_NATIVE_WINDOWS
+	if ((conf_syslog & module) && level >= conf_syslog_level) {
+		int priority;
+		switch (level) {
+		case HOSTAPD_LEVEL_DEBUG_VERBOSE:
+		case HOSTAPD_LEVEL_DEBUG:
+			priority = LOG_DEBUG;
+			break;
+		case HOSTAPD_LEVEL_INFO:
+			priority = LOG_INFO;
+			break;
+		case HOSTAPD_LEVEL_NOTICE:
+			priority = LOG_NOTICE;
+			break;
+		case HOSTAPD_LEVEL_WARNING:
+			priority = LOG_WARNING;
+			break;
+		default:
+			priority = LOG_INFO;
+			break;
+		}
+		syslog(priority, "%s", format);
+	}
+#endif /* CONFIG_NATIVE_WINDOWS */
+
+	os_free(format);
+}
+#endif /* CONFIG_NO_HOSTAPD_LOGGER */
+
+
+static struct hostapd_iface * hostapd_interface_init(const char *config_fname,
+						     int debug)
+{
+	struct hostapd_iface *iface;
+	int k;
+
+	wpa_printf(MSG_ERROR, "Configuration file: %s", config_fname);
+	iface = hostapd_init(config_fname);
+	if (!iface)
+		return NULL;
+
+	for (k = 0; k < debug; k++) {
+		if (iface->bss[0]->conf->logger_stdout_level > 0)
+			iface->bss[0]->conf->logger_stdout_level--;
+	}
+
+	if (hostapd_setup_interface(iface)) {
+		hostapd_interface_deinit(iface);
+		return NULL;
+	}
+
+	return iface;
+}
+
+
+/**
+ * handle_term - SIGINT and SIGTERM handler to terminate hostapd process
+ */
+static void handle_term(int sig, void *eloop_ctx, void *signal_ctx)
+{
+	wpa_printf(MSG_DEBUG, "Signal %d received - terminating", sig);
+	eloop_terminate();
+}
+
+
+#ifndef CONFIG_NATIVE_WINDOWS
+/**
+ * handle_reload - SIGHUP handler to reload configuration
+ */
+static void handle_reload(int sig, void *eloop_ctx, void *signal_ctx)
+{
+	wpa_printf(MSG_DEBUG, "Signal %d received - reloading configuration",
+		   sig);
+	hostapd_for_each_interface(handle_reload_iface, NULL);
+}
+
+
+static void handle_dump_state(int sig, void *eloop_ctx, void *signal_ctx)
+{
+#ifdef HOSTAPD_DUMP_STATE
+	hostapd_for_each_interface(handle_dump_state_iface, NULL);
+#endif /* HOSTAPD_DUMP_STATE */
+}
+#endif /* CONFIG_NATIVE_WINDOWS */
+
+
+static int hostapd_global_init(struct hapd_interfaces *interfaces)
+{
+	hostapd_logger_register_cb(hostapd_logger_cb);
+
+	if (eap_server_register_methods()) {
+		wpa_printf(MSG_ERROR, "Failed to register EAP methods");
+		return -1;
+	}
+
+	if (eloop_init(interfaces)) {
+		wpa_printf(MSG_ERROR, "Failed to initialize event loop");
+		return -1;
+	}
+
+#ifndef CONFIG_NATIVE_WINDOWS
+	eloop_register_signal(SIGHUP, handle_reload, NULL);
+	eloop_register_signal(SIGUSR1, handle_dump_state, NULL);
+#endif /* CONFIG_NATIVE_WINDOWS */
+	eloop_register_signal_terminate(handle_term, NULL);
+
+#ifndef CONFIG_NATIVE_WINDOWS
+	openlog("hostapd", 0, LOG_DAEMON);
+#endif /* CONFIG_NATIVE_WINDOWS */
+
+	return 0;
+}
+
+
+static void hostapd_global_deinit(const char *pid_file)
+{
+#ifdef EAP_SERVER_TNC
+	tncs_global_deinit();
+#endif /* EAP_SERVER_TNC */
+
+	eloop_destroy();
+
+#ifndef CONFIG_NATIVE_WINDOWS
+	closelog();
+#endif /* CONFIG_NATIVE_WINDOWS */
+
+	eap_server_unregister_methods();
+
+	os_daemonize_terminate(pid_file);
+}
+
+
+static int hostapd_global_run(struct hapd_interfaces *ifaces, int daemonize,
+			      const char *pid_file)
+{
+#ifdef EAP_SERVER_TNC
+	int tnc = 0;
+	size_t i, k;
+
+	for (i = 0; !tnc && i < ifaces->count; i++) {
+		for (k = 0; k < ifaces->iface[i]->num_bss; k++) {
+			if (ifaces->iface[i]->bss[0]->conf->tnc) {
+				tnc++;
+				break;
+			}
+		}
+	}
+
+	if (tnc && tncs_global_init() < 0) {
+		wpa_printf(MSG_ERROR, "Failed to initialize TNCS");
+		return -1;
+	}
+#endif /* EAP_SERVER_TNC */
+
+	if (daemonize && os_daemonize(pid_file)) {
+		perror("daemon");
+		return -1;
+	}
+
+	eloop_run();
+
+	return 0;
+}
+
+
+static void show_version(void)
+{
+	fprintf(stderr,
+		"hostapd v" VERSION_STR "\n"
+		"User space daemon for IEEE 802.11 AP management,\n"
+		"IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator\n"
+		"Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi> "
+		"and contributors\n");
+}
+
+
+static void usage(void)
+{
+	show_version();
+	fprintf(stderr,
+		"\n"
+		"usage: hostapd [-hdBKtv] [-P <PID file>] "
+		"<configuration file(s)>\n"
+		"\n"
+		"options:\n"
+		"   -h   show this usage\n"
+		"   -d   show more debug messages (-dd for even more)\n"
+		"   -B   run daemon in the background\n"
+		"   -P   PID file\n"
+		"   -K   include key data in debug messages\n"
+		"   -t   include timestamps in some debug messages\n"
+		"   -v   show hostapd version\n");
+
+	exit(1);
+}
+
+
+int main(int argc, char *argv[])
+{
+	struct hapd_interfaces interfaces;
+	int ret = 1;
+	size_t i;
+	int c, debug = 0, daemonize = 0;
+	const char *pid_file = NULL;
+
+	for (;;) {
+		c = getopt(argc, argv, "BdhKP:tv");
+		if (c < 0)
+			break;
+		switch (c) {
+		case 'h':
+			usage();
+			break;
+		case 'd':
+			debug++;
+			if (wpa_debug_level > 0)
+				wpa_debug_level--;
+			break;
+		case 'B':
+			daemonize++;
+			break;
+		case 'K':
+			wpa_debug_show_keys++;
+			break;
+		case 'P':
+			pid_file = optarg;
+			break;
+		case 't':
+			wpa_debug_timestamp++;
+			break;
+		case 'v':
+			show_version();
+			exit(1);
+			break;
+
+		default:
+			usage();
+			break;
+		}
+	}
+
+	if (optind == argc)
+		usage();
+
+	interfaces.count = argc - optind;
+	interfaces.iface = os_malloc(interfaces.count *
+				     sizeof(struct hostapd_iface *));
+	if (interfaces.iface == NULL) {
+		wpa_printf(MSG_ERROR, "malloc failed\n");
+		return -1;
+	}
+
+	if (hostapd_global_init(&interfaces))
+		return -1;
+
+	/* Initialize interfaces */
+	for (i = 0; i < interfaces.count; i++) {
+		interfaces.iface[i] = hostapd_interface_init(argv[optind + i],
+							     debug);
+		if (!interfaces.iface[i])
+			goto out;
+	}
+
+	if (hostapd_global_run(&interfaces, daemonize, pid_file))
+		goto out;
+
+	ret = 0;
+
+ out:
+	/* Deinitialize all interfaces */
+	for (i = 0; i < interfaces.count; i++)
+		hostapd_interface_deinit(interfaces.iface[i]);
+	os_free(interfaces.iface);
+
+	hostapd_global_deinit(pid_file);
+
+	return ret;
+}