/*
* hostapd / main()
- * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2002-2010, 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
* See README and COPYING for more details.
*/
-#include "includes.h"
+#include "utils/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 "tls.h"
+#include "utils/common.h"
+#include "utils/eloop.h"
+#include "crypto/tls.h"
+#include "common/version.h"
+#include "drivers/driver.h"
#include "eap_server/eap.h"
#include "eap_server/tncs.h"
+#include "ap/hostapd.h"
+#include "ap/ap_config.h"
+#include "config_file.h"
+#include "eap_register.h"
+#include "dump_state.h"
+#include "ctrl_iface.h"
extern int wpa_debug_level;
};
-int hostapd_for_each_interface(int (*cb)(struct hostapd_iface *iface,
- void *ctx), void *ctx)
+static int hostapd_for_each_interface(struct hapd_interfaces *interfaces,
+ int (*cb)(struct hostapd_iface *iface,
+ void *ctx), void *ctx)
{
- struct hapd_interfaces *interfaces = eloop_get_user_data();
size_t i;
int ret;
if (hapd_iface == NULL)
goto fail;
+ hapd_iface->reload_config = hostapd_reload_config;
+ hapd_iface->config_read_cb = hostapd_config_read;
hapd_iface->config_fname = os_strdup(config_file);
if (hapd_iface->config_fname == NULL)
goto fail;
+ hapd_iface->ctrl_iface_init = hostapd_ctrl_iface_init;
+ hapd_iface->ctrl_iface_deinit = hostapd_ctrl_iface_deinit;
+ hapd_iface->for_each_interface = hostapd_for_each_interface;
conf = hostapd_config_read(hapd_iface->config_fname);
if (conf == NULL)
&conf->bss[i]);
if (hapd == NULL)
goto fail;
+ hapd->msg_ctx = hapd;
}
return hapd_iface;
if (conf)
hostapd_config_free(conf);
if (hapd_iface) {
- for (i = 0; hapd_iface->bss && i < hapd_iface->num_bss; i++) {
- hapd = hapd_iface->bss[i];
- if (hapd && hapd->ssl_ctx)
- tls_deinit(hapd->ssl_ctx);
- }
-
os_free(hapd_iface->config_fname);
os_free(hapd_iface->bss);
os_free(hapd_iface);
}
-static struct hostapd_iface * hostapd_interface_init(const char *config_fname,
- int debug)
+static int hostapd_driver_init(struct hostapd_iface *iface)
+{
+ struct wpa_init_params params;
+ size_t i;
+ struct hostapd_data *hapd = iface->bss[0];
+ struct hostapd_bss_config *conf = hapd->conf;
+ u8 *b = conf->bssid;
+
+ if (hapd->driver == NULL || hapd->driver->hapd_init == NULL) {
+ wpa_printf(MSG_ERROR, "No hostapd driver wrapper available");
+ return -1;
+ }
+
+ /* Initialize the driver interface */
+ if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5]))
+ b = NULL;
+
+ os_memset(¶ms, 0, sizeof(params));
+ params.bssid = b;
+ params.ifname = hapd->conf->iface;
+ params.ssid = (const u8 *) hapd->conf->ssid.ssid;
+ params.ssid_len = hapd->conf->ssid.ssid_len;
+ params.test_socket = hapd->conf->test_socket;
+ params.use_pae_group_addr = hapd->conf->use_pae_group_addr;
+
+ params.num_bridge = hapd->iface->num_bss;
+ params.bridge = os_zalloc(hapd->iface->num_bss * sizeof(char *));
+ if (params.bridge == NULL)
+ return -1;
+ for (i = 0; i < hapd->iface->num_bss; i++) {
+ struct hostapd_data *bss = hapd->iface->bss[i];
+ if (bss->conf->bridge[0])
+ params.bridge[i] = bss->conf->bridge;
+ }
+
+ params.own_addr = hapd->own_addr;
+
+ hapd->drv_priv = hapd->driver->hapd_init(hapd, ¶ms);
+ os_free(params.bridge);
+ if (hapd->drv_priv == NULL) {
+ wpa_printf(MSG_ERROR, "%s driver initialization failed.",
+ hapd->driver->name);
+ hapd->driver = NULL;
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static void hostapd_interface_deinit_free(struct hostapd_iface *iface)
+{
+ const struct wpa_driver_ops *driver;
+ void *drv_priv;
+ if (iface == NULL)
+ return;
+ driver = iface->bss[0]->driver;
+ drv_priv = iface->bss[0]->drv_priv;
+ hostapd_interface_deinit(iface);
+ if (driver && driver->hapd_deinit)
+ driver->hapd_deinit(drv_priv);
+ hostapd_interface_free(iface);
+}
+
+
+static struct hostapd_iface *
+hostapd_interface_init(struct hapd_interfaces *interfaces,
+ const char *config_fname, int debug)
{
struct hostapd_iface *iface;
int k;
iface = hostapd_init(config_fname);
if (!iface)
return NULL;
+ iface->interfaces = interfaces;
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);
+ if (hostapd_driver_init(iface) ||
+ hostapd_setup_interface(iface)) {
+ hostapd_interface_deinit_free(iface);
return NULL;
}
/**
* handle_term - SIGINT and SIGTERM handler to terminate hostapd process
*/
-static void handle_term(int sig, void *eloop_ctx, void *signal_ctx)
+static void handle_term(int sig, void *signal_ctx)
{
wpa_printf(MSG_DEBUG, "Signal %d received - terminating", sig);
eloop_terminate();
#ifndef CONFIG_NATIVE_WINDOWS
+
+static int handle_reload_iface(struct hostapd_iface *iface, void *ctx)
+{
+ if (hostapd_reload_config(iface) < 0) {
+ wpa_printf(MSG_WARNING, "Failed to read new configuration "
+ "file - continuing with old.");
+ }
+ return 0;
+}
+
+
/**
* handle_reload - SIGHUP handler to reload configuration
*/
-static void handle_reload(int sig, void *eloop_ctx, void *signal_ctx)
+static void handle_reload(int sig, void *signal_ctx)
{
+ struct hapd_interfaces *interfaces = signal_ctx;
wpa_printf(MSG_DEBUG, "Signal %d received - reloading configuration",
sig);
- hostapd_for_each_interface(handle_reload_iface, NULL);
+ hostapd_for_each_interface(interfaces, handle_reload_iface, NULL);
}
-static void handle_dump_state(int sig, void *eloop_ctx, void *signal_ctx)
+static void handle_dump_state(int sig, void *signal_ctx)
{
#ifdef HOSTAPD_DUMP_STATE
- hostapd_for_each_interface(handle_dump_state_iface, NULL);
+ struct hapd_interfaces *interfaces = signal_ctx;
+ hostapd_for_each_interface(interfaces, handle_dump_state_iface, NULL);
#endif /* HOSTAPD_DUMP_STATE */
}
#endif /* CONFIG_NATIVE_WINDOWS */
return -1;
}
- if (eloop_init(interfaces)) {
+ if (eloop_init()) {
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);
+ eloop_register_signal(SIGHUP, handle_reload, interfaces);
+ eloop_register_signal(SIGUSR1, handle_dump_state, interfaces);
#endif /* CONFIG_NATIVE_WINDOWS */
- eloop_register_signal_terminate(handle_term, NULL);
+ eloop_register_signal_terminate(handle_term, interfaces);
#ifndef CONFIG_NATIVE_WINDOWS
openlog("hostapd", 0, LOG_DAEMON);
"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> "
+ "Copyright (c) 2002-2010, Jouni Malinen <j@w1.fi> "
"and contributors\n");
}
int c, debug = 0, daemonize = 0;
char *pid_file = NULL;
+ if (os_program_init())
+ return -1;
+
for (;;) {
c = getopt(argc, argv, "BdhKP:tv");
if (c < 0)
/* Initialize interfaces */
for (i = 0; i < interfaces.count; i++) {
- interfaces.iface[i] = hostapd_interface_init(argv[optind + i],
+ interfaces.iface[i] = hostapd_interface_init(&interfaces,
+ argv[optind + i],
debug);
if (!interfaces.iface[i])
goto out;
out:
/* Deinitialize all interfaces */
for (i = 0; i < interfaces.count; i++)
- hostapd_interface_deinit(interfaces.iface[i]);
+ hostapd_interface_deinit_free(interfaces.iface[i]);
os_free(interfaces.iface);
hostapd_global_deinit(pid_file);
os_free(pid_file);
+ os_program_deinit();
+
return ret;
}