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 */
22 #include "crypto/tls.h"
23 #include "common/version.h"
24 #include "eap_server/eap.h"
25 #include "eap_server/tncs.h"
28 #include "config_file.h"
31 extern int wpa_debug_level;
32 extern int wpa_debug_show_keys;
33 extern int wpa_debug_timestamp;
36 struct hapd_interfaces {
38 struct hostapd_iface **iface;
42 int hostapd_for_each_interface(struct hapd_interfaces *interfaces,
43 int (*cb)(struct hostapd_iface *iface,
44 void *ctx), void *ctx)
49 for (i = 0; i < interfaces->count; i++) {
50 ret = cb(interfaces->iface[i], ctx);
59 #ifndef CONFIG_NO_HOSTAPD_LOGGER
60 static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module,
61 int level, const char *txt, size_t len)
63 struct hostapd_data *hapd = ctx;
64 char *format, *module_str;
66 int conf_syslog_level, conf_stdout_level;
67 unsigned int conf_syslog, conf_stdout;
70 format = os_malloc(maxlen);
74 if (hapd && hapd->conf) {
75 conf_syslog_level = hapd->conf->logger_syslog_level;
76 conf_stdout_level = hapd->conf->logger_stdout_level;
77 conf_syslog = hapd->conf->logger_syslog;
78 conf_stdout = hapd->conf->logger_stdout;
80 conf_syslog_level = conf_stdout_level = 0;
81 conf_syslog = conf_stdout = (unsigned int) -1;
85 case HOSTAPD_MODULE_IEEE80211:
86 module_str = "IEEE 802.11";
88 case HOSTAPD_MODULE_IEEE8021X:
89 module_str = "IEEE 802.1X";
91 case HOSTAPD_MODULE_RADIUS:
92 module_str = "RADIUS";
94 case HOSTAPD_MODULE_WPA:
97 case HOSTAPD_MODULE_DRIVER:
98 module_str = "DRIVER";
100 case HOSTAPD_MODULE_IAPP:
103 case HOSTAPD_MODULE_MLME:
111 if (hapd && hapd->conf && addr)
112 os_snprintf(format, maxlen, "%s: STA " MACSTR "%s%s: %s",
113 hapd->conf->iface, MAC2STR(addr),
114 module_str ? " " : "", module_str, txt);
115 else if (hapd && hapd->conf)
116 os_snprintf(format, maxlen, "%s:%s%s %s",
117 hapd->conf->iface, module_str ? " " : "",
120 os_snprintf(format, maxlen, "STA " MACSTR "%s%s: %s",
121 MAC2STR(addr), module_str ? " " : "",
124 os_snprintf(format, maxlen, "%s%s%s",
125 module_str, module_str ? ": " : "", txt);
127 if ((conf_stdout & module) && level >= conf_stdout_level) {
128 wpa_debug_print_timestamp();
129 printf("%s\n", format);
132 #ifndef CONFIG_NATIVE_WINDOWS
133 if ((conf_syslog & module) && level >= conf_syslog_level) {
136 case HOSTAPD_LEVEL_DEBUG_VERBOSE:
137 case HOSTAPD_LEVEL_DEBUG:
138 priority = LOG_DEBUG;
140 case HOSTAPD_LEVEL_INFO:
143 case HOSTAPD_LEVEL_NOTICE:
144 priority = LOG_NOTICE;
146 case HOSTAPD_LEVEL_WARNING:
147 priority = LOG_WARNING;
153 syslog(priority, "%s", format);
155 #endif /* CONFIG_NATIVE_WINDOWS */
159 #endif /* CONFIG_NO_HOSTAPD_LOGGER */
163 * hostapd_init - Allocate and initialize per-interface data
164 * @config_file: Path to the configuration file
165 * Returns: Pointer to the allocated interface data or %NULL on failure
167 * This function is used to allocate main data structures for per-interface
168 * data. The allocated data buffer will be freed by calling
169 * hostapd_cleanup_iface().
171 static struct hostapd_iface * hostapd_init(const char *config_file)
173 struct hostapd_iface *hapd_iface = NULL;
174 struct hostapd_config *conf = NULL;
175 struct hostapd_data *hapd;
178 hapd_iface = os_zalloc(sizeof(*hapd_iface));
179 if (hapd_iface == NULL)
182 hapd_iface->config_read_cb = hostapd_config_read;
183 hapd_iface->config_fname = os_strdup(config_file);
184 if (hapd_iface->config_fname == NULL)
187 conf = hostapd_config_read(hapd_iface->config_fname);
190 hapd_iface->conf = conf;
192 hapd_iface->num_bss = conf->num_bss;
193 hapd_iface->bss = os_zalloc(conf->num_bss *
194 sizeof(struct hostapd_data *));
195 if (hapd_iface->bss == NULL)
198 for (i = 0; i < conf->num_bss; i++) {
199 hapd = hapd_iface->bss[i] =
200 hostapd_alloc_bss_data(hapd_iface, conf,
210 hostapd_config_free(conf);
212 for (i = 0; hapd_iface->bss && i < hapd_iface->num_bss; i++) {
213 hapd = hapd_iface->bss[i];
214 if (hapd && hapd->ssl_ctx)
215 tls_deinit(hapd->ssl_ctx);
218 os_free(hapd_iface->config_fname);
219 os_free(hapd_iface->bss);
226 static struct hostapd_iface *
227 hostapd_interface_init(struct hapd_interfaces *interfaces,
228 const char *config_fname, int debug)
230 struct hostapd_iface *iface;
233 wpa_printf(MSG_ERROR, "Configuration file: %s", config_fname);
234 iface = hostapd_init(config_fname);
237 iface->interfaces = interfaces;
239 for (k = 0; k < debug; k++) {
240 if (iface->bss[0]->conf->logger_stdout_level > 0)
241 iface->bss[0]->conf->logger_stdout_level--;
244 if (hostapd_setup_interface(iface)) {
245 hostapd_interface_deinit(iface);
254 * handle_term - SIGINT and SIGTERM handler to terminate hostapd process
256 static void handle_term(int sig, void *signal_ctx)
258 wpa_printf(MSG_DEBUG, "Signal %d received - terminating", sig);
263 #ifndef CONFIG_NATIVE_WINDOWS
265 * handle_reload - SIGHUP handler to reload configuration
267 static void handle_reload(int sig, void *signal_ctx)
269 struct hapd_interfaces *interfaces = signal_ctx;
270 wpa_printf(MSG_DEBUG, "Signal %d received - reloading configuration",
272 hostapd_for_each_interface(interfaces, handle_reload_iface, NULL);
276 static void handle_dump_state(int sig, void *signal_ctx)
278 #ifdef HOSTAPD_DUMP_STATE
279 struct hapd_interfaces *interfaces = signal_ctx;
280 hostapd_for_each_interface(interfaces, handle_dump_state_iface, NULL);
281 #endif /* HOSTAPD_DUMP_STATE */
283 #endif /* CONFIG_NATIVE_WINDOWS */
286 static int hostapd_global_init(struct hapd_interfaces *interfaces)
288 hostapd_logger_register_cb(hostapd_logger_cb);
290 if (eap_server_register_methods()) {
291 wpa_printf(MSG_ERROR, "Failed to register EAP methods");
296 wpa_printf(MSG_ERROR, "Failed to initialize event loop");
300 #ifndef CONFIG_NATIVE_WINDOWS
301 eloop_register_signal(SIGHUP, handle_reload, interfaces);
302 eloop_register_signal(SIGUSR1, handle_dump_state, interfaces);
303 #endif /* CONFIG_NATIVE_WINDOWS */
304 eloop_register_signal_terminate(handle_term, interfaces);
306 #ifndef CONFIG_NATIVE_WINDOWS
307 openlog("hostapd", 0, LOG_DAEMON);
308 #endif /* CONFIG_NATIVE_WINDOWS */
314 static void hostapd_global_deinit(const char *pid_file)
316 #ifdef EAP_SERVER_TNC
317 tncs_global_deinit();
318 #endif /* EAP_SERVER_TNC */
322 #ifndef CONFIG_NATIVE_WINDOWS
324 #endif /* CONFIG_NATIVE_WINDOWS */
326 eap_server_unregister_methods();
328 os_daemonize_terminate(pid_file);
332 static int hostapd_global_run(struct hapd_interfaces *ifaces, int daemonize,
333 const char *pid_file)
335 #ifdef EAP_SERVER_TNC
339 for (i = 0; !tnc && i < ifaces->count; i++) {
340 for (k = 0; k < ifaces->iface[i]->num_bss; k++) {
341 if (ifaces->iface[i]->bss[0]->conf->tnc) {
348 if (tnc && tncs_global_init() < 0) {
349 wpa_printf(MSG_ERROR, "Failed to initialize TNCS");
352 #endif /* EAP_SERVER_TNC */
354 if (daemonize && os_daemonize(pid_file)) {
365 static void show_version(void)
368 "hostapd v" VERSION_STR "\n"
369 "User space daemon for IEEE 802.11 AP management,\n"
370 "IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator\n"
371 "Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi> "
372 "and contributors\n");
376 static void usage(void)
381 "usage: hostapd [-hdBKtv] [-P <PID file>] "
382 "<configuration file(s)>\n"
385 " -h show this usage\n"
386 " -d show more debug messages (-dd for even more)\n"
387 " -B run daemon in the background\n"
389 " -K include key data in debug messages\n"
390 " -t include timestamps in some debug messages\n"
391 " -v show hostapd version\n");
397 int main(int argc, char *argv[])
399 struct hapd_interfaces interfaces;
402 int c, debug = 0, daemonize = 0;
403 char *pid_file = NULL;
405 if (os_program_init())
409 c = getopt(argc, argv, "BdhKP:tv");
418 if (wpa_debug_level > 0)
425 wpa_debug_show_keys++;
429 pid_file = os_rel2abs_path(optarg);
432 wpa_debug_timestamp++;
448 interfaces.count = argc - optind;
449 interfaces.iface = os_malloc(interfaces.count *
450 sizeof(struct hostapd_iface *));
451 if (interfaces.iface == NULL) {
452 wpa_printf(MSG_ERROR, "malloc failed\n");
456 if (hostapd_global_init(&interfaces))
459 /* Initialize interfaces */
460 for (i = 0; i < interfaces.count; i++) {
461 interfaces.iface[i] = hostapd_interface_init(&interfaces,
464 if (!interfaces.iface[i])
468 if (hostapd_global_run(&interfaces, daemonize, pid_file))
474 /* Deinitialize all interfaces */
475 for (i = 0; i < interfaces.count; i++)
476 hostapd_interface_deinit(interfaces.iface[i]);
477 os_free(interfaces.iface);
479 hostapd_global_deinit(pid_file);