3 * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
16 #ifndef CONFIG_NATIVE_WINDOWS
18 #endif /* CONFIG_NATIVE_WINDOWS */
24 #include "eap_server/eap.h"
25 #include "eap_server/tncs.h"
28 extern int wpa_debug_level;
29 extern int wpa_debug_show_keys;
30 extern int wpa_debug_timestamp;
33 struct hapd_interfaces {
35 struct hostapd_iface **iface;
39 int hostapd_for_each_interface(int (*cb)(struct hostapd_iface *iface,
40 void *ctx), void *ctx)
42 struct hapd_interfaces *interfaces = eloop_get_user_data();
46 for (i = 0; i < interfaces->count; i++) {
47 ret = cb(interfaces->iface[i], ctx);
56 #ifndef CONFIG_NO_HOSTAPD_LOGGER
57 static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module,
58 int level, const char *txt, size_t len)
60 struct hostapd_data *hapd = ctx;
61 char *format, *module_str;
63 int conf_syslog_level, conf_stdout_level;
64 unsigned int conf_syslog, conf_stdout;
67 format = os_malloc(maxlen);
71 if (hapd && hapd->conf) {
72 conf_syslog_level = hapd->conf->logger_syslog_level;
73 conf_stdout_level = hapd->conf->logger_stdout_level;
74 conf_syslog = hapd->conf->logger_syslog;
75 conf_stdout = hapd->conf->logger_stdout;
77 conf_syslog_level = conf_stdout_level = 0;
78 conf_syslog = conf_stdout = (unsigned int) -1;
82 case HOSTAPD_MODULE_IEEE80211:
83 module_str = "IEEE 802.11";
85 case HOSTAPD_MODULE_IEEE8021X:
86 module_str = "IEEE 802.1X";
88 case HOSTAPD_MODULE_RADIUS:
89 module_str = "RADIUS";
91 case HOSTAPD_MODULE_WPA:
94 case HOSTAPD_MODULE_DRIVER:
95 module_str = "DRIVER";
97 case HOSTAPD_MODULE_IAPP:
100 case HOSTAPD_MODULE_MLME:
108 if (hapd && hapd->conf && addr)
109 os_snprintf(format, maxlen, "%s: STA " MACSTR "%s%s: %s",
110 hapd->conf->iface, MAC2STR(addr),
111 module_str ? " " : "", module_str, txt);
112 else if (hapd && hapd->conf)
113 os_snprintf(format, maxlen, "%s:%s%s %s",
114 hapd->conf->iface, module_str ? " " : "",
117 os_snprintf(format, maxlen, "STA " MACSTR "%s%s: %s",
118 MAC2STR(addr), module_str ? " " : "",
121 os_snprintf(format, maxlen, "%s%s%s",
122 module_str, module_str ? ": " : "", txt);
124 if ((conf_stdout & module) && level >= conf_stdout_level) {
125 wpa_debug_print_timestamp();
126 printf("%s\n", format);
129 #ifndef CONFIG_NATIVE_WINDOWS
130 if ((conf_syslog & module) && level >= conf_syslog_level) {
133 case HOSTAPD_LEVEL_DEBUG_VERBOSE:
134 case HOSTAPD_LEVEL_DEBUG:
135 priority = LOG_DEBUG;
137 case HOSTAPD_LEVEL_INFO:
140 case HOSTAPD_LEVEL_NOTICE:
141 priority = LOG_NOTICE;
143 case HOSTAPD_LEVEL_WARNING:
144 priority = LOG_WARNING;
150 syslog(priority, "%s", format);
152 #endif /* CONFIG_NATIVE_WINDOWS */
156 #endif /* CONFIG_NO_HOSTAPD_LOGGER */
159 static struct hostapd_iface * hostapd_interface_init(const char *config_fname,
162 struct hostapd_iface *iface;
165 wpa_printf(MSG_ERROR, "Configuration file: %s", config_fname);
166 iface = hostapd_init(config_fname);
170 for (k = 0; k < debug; k++) {
171 if (iface->bss[0]->conf->logger_stdout_level > 0)
172 iface->bss[0]->conf->logger_stdout_level--;
175 if (hostapd_setup_interface(iface)) {
176 hostapd_interface_deinit(iface);
185 * handle_term - SIGINT and SIGTERM handler to terminate hostapd process
187 static void handle_term(int sig, void *eloop_ctx, void *signal_ctx)
189 wpa_printf(MSG_DEBUG, "Signal %d received - terminating", sig);
194 #ifndef CONFIG_NATIVE_WINDOWS
196 * handle_reload - SIGHUP handler to reload configuration
198 static void handle_reload(int sig, void *eloop_ctx, void *signal_ctx)
200 wpa_printf(MSG_DEBUG, "Signal %d received - reloading configuration",
202 hostapd_for_each_interface(handle_reload_iface, NULL);
206 static void handle_dump_state(int sig, void *eloop_ctx, void *signal_ctx)
208 #ifdef HOSTAPD_DUMP_STATE
209 hostapd_for_each_interface(handle_dump_state_iface, NULL);
210 #endif /* HOSTAPD_DUMP_STATE */
212 #endif /* CONFIG_NATIVE_WINDOWS */
215 static int hostapd_global_init(struct hapd_interfaces *interfaces)
217 hostapd_logger_register_cb(hostapd_logger_cb);
219 if (eap_server_register_methods()) {
220 wpa_printf(MSG_ERROR, "Failed to register EAP methods");
224 if (eloop_init(interfaces)) {
225 wpa_printf(MSG_ERROR, "Failed to initialize event loop");
229 #ifndef CONFIG_NATIVE_WINDOWS
230 eloop_register_signal(SIGHUP, handle_reload, NULL);
231 eloop_register_signal(SIGUSR1, handle_dump_state, NULL);
232 #endif /* CONFIG_NATIVE_WINDOWS */
233 eloop_register_signal_terminate(handle_term, NULL);
235 #ifndef CONFIG_NATIVE_WINDOWS
236 openlog("hostapd", 0, LOG_DAEMON);
237 #endif /* CONFIG_NATIVE_WINDOWS */
243 static void hostapd_global_deinit(const char *pid_file)
245 #ifdef EAP_SERVER_TNC
246 tncs_global_deinit();
247 #endif /* EAP_SERVER_TNC */
251 #ifndef CONFIG_NATIVE_WINDOWS
253 #endif /* CONFIG_NATIVE_WINDOWS */
255 eap_server_unregister_methods();
257 os_daemonize_terminate(pid_file);
261 static int hostapd_global_run(struct hapd_interfaces *ifaces, int daemonize,
262 const char *pid_file)
264 #ifdef EAP_SERVER_TNC
268 for (i = 0; !tnc && i < ifaces->count; i++) {
269 for (k = 0; k < ifaces->iface[i]->num_bss; k++) {
270 if (ifaces->iface[i]->bss[0]->conf->tnc) {
277 if (tnc && tncs_global_init() < 0) {
278 wpa_printf(MSG_ERROR, "Failed to initialize TNCS");
281 #endif /* EAP_SERVER_TNC */
283 if (daemonize && os_daemonize(pid_file)) {
294 static void show_version(void)
297 "hostapd v" VERSION_STR "\n"
298 "User space daemon for IEEE 802.11 AP management,\n"
299 "IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator\n"
300 "Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi> "
301 "and contributors\n");
305 static void usage(void)
310 "usage: hostapd [-hdBKtv] [-P <PID file>] "
311 "<configuration file(s)>\n"
314 " -h show this usage\n"
315 " -d show more debug messages (-dd for even more)\n"
316 " -B run daemon in the background\n"
318 " -K include key data in debug messages\n"
319 " -t include timestamps in some debug messages\n"
320 " -v show hostapd version\n");
326 int main(int argc, char *argv[])
328 struct hapd_interfaces interfaces;
331 int c, debug = 0, daemonize = 0;
332 const char *pid_file = NULL;
335 c = getopt(argc, argv, "BdhKP:tv");
344 if (wpa_debug_level > 0)
351 wpa_debug_show_keys++;
357 wpa_debug_timestamp++;
373 interfaces.count = argc - optind;
374 interfaces.iface = os_malloc(interfaces.count *
375 sizeof(struct hostapd_iface *));
376 if (interfaces.iface == NULL) {
377 wpa_printf(MSG_ERROR, "malloc failed\n");
381 if (hostapd_global_init(&interfaces))
384 /* Initialize interfaces */
385 for (i = 0; i < interfaces.count; i++) {
386 interfaces.iface[i] = hostapd_interface_init(argv[optind + i],
388 if (!interfaces.iface[i])
392 if (hostapd_global_run(&interfaces, daemonize, pid_file))
398 /* Deinitialize all interfaces */
399 for (i = 0; i < interfaces.count; i++)
400 hostapd_interface_deinit(interfaces.iface[i]);
401 os_free(interfaces.iface);
403 hostapd_global_deinit(pid_file);