main.c

Go to the documentation of this file.
00001 
00016 #include "includes.h"
00017 #ifndef CONFIG_NATIVE_WINDOWS
00018 #include <syslog.h>
00019 #endif /* CONFIG_NATIVE_WINDOWS */
00020 
00021 #include "eloop.h"
00022 #include "hostapd.h"
00023 #include "version.h"
00024 #include "config.h"
00025 #include "tls.h"
00026 #include "eap_server/eap.h"
00027 #include "eap_server/tncs.h"
00028 
00029 
00030 extern int wpa_debug_level;
00031 extern int wpa_debug_show_keys;
00032 extern int wpa_debug_timestamp;
00033 
00034 
00035 struct hapd_interfaces {
00036         size_t count;
00037         struct hostapd_iface **iface;
00038 };
00039 
00040 
00041 int hostapd_for_each_interface(int (*cb)(struct hostapd_iface *iface,
00042                                          void *ctx), void *ctx)
00043 {
00044         struct hapd_interfaces *interfaces = eloop_get_user_data();
00045         size_t i;
00046         int ret;
00047 
00048         for (i = 0; i < interfaces->count; i++) {
00049                 ret = cb(interfaces->iface[i], ctx);
00050                 if (ret)
00051                         return ret;
00052         }
00053 
00054         return 0;
00055 }
00056 
00057 
00058 #ifndef CONFIG_NO_HOSTAPD_LOGGER
00059 static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module,
00060                               int level, const char *txt, size_t len)
00061 {
00062         struct hostapd_data *hapd = ctx;
00063         char *format, *module_str;
00064         int maxlen;
00065         int conf_syslog_level, conf_stdout_level;
00066         unsigned int conf_syslog, conf_stdout;
00067 
00068         maxlen = len + 100;
00069         format = os_malloc(maxlen);
00070         if (!format)
00071                 return;
00072 
00073         if (hapd && hapd->conf) {
00074                 conf_syslog_level = hapd->conf->logger_syslog_level;
00075                 conf_stdout_level = hapd->conf->logger_stdout_level;
00076                 conf_syslog = hapd->conf->logger_syslog;
00077                 conf_stdout = hapd->conf->logger_stdout;
00078         } else {
00079                 conf_syslog_level = conf_stdout_level = 0;
00080                 conf_syslog = conf_stdout = (unsigned int) -1;
00081         }
00082 
00083         switch (module) {
00084         case HOSTAPD_MODULE_IEEE80211:
00085                 module_str = "IEEE 802.11";
00086                 break;
00087         case HOSTAPD_MODULE_IEEE8021X:
00088                 module_str = "IEEE 802.1X";
00089                 break;
00090         case HOSTAPD_MODULE_RADIUS:
00091                 module_str = "RADIUS";
00092                 break;
00093         case HOSTAPD_MODULE_WPA:
00094                 module_str = "WPA";
00095                 break;
00096         case HOSTAPD_MODULE_DRIVER:
00097                 module_str = "DRIVER";
00098                 break;
00099         case HOSTAPD_MODULE_IAPP:
00100                 module_str = "IAPP";
00101                 break;
00102         case HOSTAPD_MODULE_MLME:
00103                 module_str = "MLME";
00104                 break;
00105         default:
00106                 module_str = NULL;
00107                 break;
00108         }
00109 
00110         if (hapd && hapd->conf && addr)
00111                 os_snprintf(format, maxlen, "%s: STA " MACSTR "%s%s: %s",
00112                             hapd->conf->iface, MAC2STR(addr),
00113                             module_str ? " " : "", module_str, txt);
00114         else if (hapd && hapd->conf)
00115                 os_snprintf(format, maxlen, "%s:%s%s %s",
00116                             hapd->conf->iface, module_str ? " " : "",
00117                             module_str, txt);
00118         else if (addr)
00119                 os_snprintf(format, maxlen, "STA " MACSTR "%s%s: %s",
00120                             MAC2STR(addr), module_str ? " " : "",
00121                             module_str, txt);
00122         else
00123                 os_snprintf(format, maxlen, "%s%s%s",
00124                             module_str, module_str ? ": " : "", txt);
00125 
00126         if ((conf_stdout & module) && level >= conf_stdout_level) {
00127                 wpa_debug_print_timestamp();
00128                 printf("%s\n", format);
00129         }
00130 
00131 #ifndef CONFIG_NATIVE_WINDOWS
00132         if ((conf_syslog & module) && level >= conf_syslog_level) {
00133                 int priority;
00134                 switch (level) {
00135                 case HOSTAPD_LEVEL_DEBUG_VERBOSE:
00136                 case HOSTAPD_LEVEL_DEBUG:
00137                         priority = LOG_DEBUG;
00138                         break;
00139                 case HOSTAPD_LEVEL_INFO:
00140                         priority = LOG_INFO;
00141                         break;
00142                 case HOSTAPD_LEVEL_NOTICE:
00143                         priority = LOG_NOTICE;
00144                         break;
00145                 case HOSTAPD_LEVEL_WARNING:
00146                         priority = LOG_WARNING;
00147                         break;
00148                 default:
00149                         priority = LOG_INFO;
00150                         break;
00151                 }
00152                 syslog(priority, "%s", format);
00153         }
00154 #endif /* CONFIG_NATIVE_WINDOWS */
00155 
00156         os_free(format);
00157 }
00158 #endif /* CONFIG_NO_HOSTAPD_LOGGER */
00159 
00160 
00171 static struct hostapd_iface * hostapd_init(const char *config_file)
00172 {
00173         struct hostapd_iface *hapd_iface = NULL;
00174         struct hostapd_config *conf = NULL;
00175         struct hostapd_data *hapd;
00176         size_t i;
00177 
00178         hapd_iface = os_zalloc(sizeof(*hapd_iface));
00179         if (hapd_iface == NULL)
00180                 goto fail;
00181 
00182         hapd_iface->config_fname = os_strdup(config_file);
00183         if (hapd_iface->config_fname == NULL)
00184                 goto fail;
00185 
00186         conf = hostapd_config_read(hapd_iface->config_fname);
00187         if (conf == NULL)
00188                 goto fail;
00189         hapd_iface->conf = conf;
00190 
00191         hapd_iface->num_bss = conf->num_bss;
00192         hapd_iface->bss = os_zalloc(conf->num_bss *
00193                                     sizeof(struct hostapd_data *));
00194         if (hapd_iface->bss == NULL)
00195                 goto fail;
00196 
00197         for (i = 0; i < conf->num_bss; i++) {
00198                 hapd = hapd_iface->bss[i] =
00199                         hostapd_alloc_bss_data(hapd_iface, conf,
00200                                                &conf->bss[i]);
00201                 if (hapd == NULL)
00202                         goto fail;
00203         }
00204 
00205         return hapd_iface;
00206 
00207 fail:
00208         if (conf)
00209                 hostapd_config_free(conf);
00210         if (hapd_iface) {
00211                 for (i = 0; hapd_iface->bss && i < hapd_iface->num_bss; i++) {
00212                         hapd = hapd_iface->bss[i];
00213                         if (hapd && hapd->ssl_ctx)
00214                                 tls_deinit(hapd->ssl_ctx);
00215                 }
00216 
00217                 os_free(hapd_iface->config_fname);
00218                 os_free(hapd_iface->bss);
00219                 os_free(hapd_iface);
00220         }
00221         return NULL;
00222 }
00223 
00224 
00225 static struct hostapd_iface * hostapd_interface_init(const char *config_fname,
00226                                                      int debug)
00227 {
00228         struct hostapd_iface *iface;
00229         int k;
00230 
00231         wpa_printf(MSG_ERROR, "Configuration file: %s", config_fname);
00232         iface = hostapd_init(config_fname);
00233         if (!iface)
00234                 return NULL;
00235 
00236         for (k = 0; k < debug; k++) {
00237                 if (iface->bss[0]->conf->logger_stdout_level > 0)
00238                         iface->bss[0]->conf->logger_stdout_level--;
00239         }
00240 
00241         if (hostapd_setup_interface(iface)) {
00242                 hostapd_interface_deinit(iface);
00243                 return NULL;
00244         }
00245 
00246         return iface;
00247 }
00248 
00249 
00254 static void handle_term(int sig, void *eloop_ctx, void *signal_ctx)
00255 {
00256         wpa_printf(MSG_DEBUG, "Signal %d received - terminating", sig);
00257         eloop_terminate();
00258 }
00259 
00260 
00261 #ifndef CONFIG_NATIVE_WINDOWS
00262 
00266 static void handle_reload(int sig, void *eloop_ctx, void *signal_ctx)
00267 {
00268         wpa_printf(MSG_DEBUG, "Signal %d received - reloading configuration",
00269                    sig);
00270         hostapd_for_each_interface(handle_reload_iface, NULL);
00271 }
00272 
00273 
00274 static void handle_dump_state(int sig, void *eloop_ctx, void *signal_ctx)
00275 {
00276 #ifdef HOSTAPD_DUMP_STATE
00277         hostapd_for_each_interface(handle_dump_state_iface, NULL);
00278 #endif /* HOSTAPD_DUMP_STATE */
00279 }
00280 #endif /* CONFIG_NATIVE_WINDOWS */
00281 
00282 
00283 static int hostapd_global_init(struct hapd_interfaces *interfaces)
00284 {
00285         hostapd_logger_register_cb(hostapd_logger_cb);
00286 
00287         if (eap_server_register_methods()) {
00288                 wpa_printf(MSG_ERROR, "Failed to register EAP methods");
00289                 return -1;
00290         }
00291 
00292         if (eloop_init(interfaces)) {
00293                 wpa_printf(MSG_ERROR, "Failed to initialize event loop");
00294                 return -1;
00295         }
00296 
00297 #ifndef CONFIG_NATIVE_WINDOWS
00298         eloop_register_signal(SIGHUP, handle_reload, NULL);
00299         eloop_register_signal(SIGUSR1, handle_dump_state, NULL);
00300 #endif /* CONFIG_NATIVE_WINDOWS */
00301         eloop_register_signal_terminate(handle_term, NULL);
00302 
00303 #ifndef CONFIG_NATIVE_WINDOWS
00304         openlog("hostapd", 0, LOG_DAEMON);
00305 #endif /* CONFIG_NATIVE_WINDOWS */
00306 
00307         return 0;
00308 }
00309 
00310 
00311 static void hostapd_global_deinit(const char *pid_file)
00312 {
00313 #ifdef EAP_SERVER_TNC
00314         tncs_global_deinit();
00315 #endif /* EAP_SERVER_TNC */
00316 
00317         eloop_destroy();
00318 
00319 #ifndef CONFIG_NATIVE_WINDOWS
00320         closelog();
00321 #endif /* CONFIG_NATIVE_WINDOWS */
00322 
00323         eap_server_unregister_methods();
00324 
00325         os_daemonize_terminate(pid_file);
00326 }
00327 
00328 
00329 static int hostapd_global_run(struct hapd_interfaces *ifaces, int daemonize,
00330                               const char *pid_file)
00331 {
00332 #ifdef EAP_SERVER_TNC
00333         int tnc = 0;
00334         size_t i, k;
00335 
00336         for (i = 0; !tnc && i < ifaces->count; i++) {
00337                 for (k = 0; k < ifaces->iface[i]->num_bss; k++) {
00338                         if (ifaces->iface[i]->bss[0]->conf->tnc) {
00339                                 tnc++;
00340                                 break;
00341                         }
00342                 }
00343         }
00344 
00345         if (tnc && tncs_global_init() < 0) {
00346                 wpa_printf(MSG_ERROR, "Failed to initialize TNCS");
00347                 return -1;
00348         }
00349 #endif /* EAP_SERVER_TNC */
00350 
00351         if (daemonize && os_daemonize(pid_file)) {
00352                 perror("daemon");
00353                 return -1;
00354         }
00355 
00356         eloop_run();
00357 
00358         return 0;
00359 }
00360 
00361 
00362 static void show_version(void)
00363 {
00364         fprintf(stderr,
00365                 "hostapd v" VERSION_STR "\n"
00366                 "User space daemon for IEEE 802.11 AP management,\n"
00367                 "IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator\n"
00368                 "Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi> "
00369                 "and contributors\n");
00370 }
00371 
00372 
00373 static void usage(void)
00374 {
00375         show_version();
00376         fprintf(stderr,
00377                 "\n"
00378                 "usage: hostapd [-hdBKtv] [-P <PID file>] "
00379                 "<configuration file(s)>\n"
00380                 "\n"
00381                 "options:\n"
00382                 "   -h   show this usage\n"
00383                 "   -d   show more debug messages (-dd for even more)\n"
00384                 "   -B   run daemon in the background\n"
00385                 "   -P   PID file\n"
00386                 "   -K   include key data in debug messages\n"
00387                 "   -t   include timestamps in some debug messages\n"
00388                 "   -v   show hostapd version\n");
00389 
00390         exit(1);
00391 }
00392 
00393 
00394 int main(int argc, char *argv[])
00395 {
00396         struct hapd_interfaces interfaces;
00397         int ret = 1;
00398         size_t i;
00399         int c, debug = 0, daemonize = 0;
00400         char *pid_file = NULL;
00401 
00402         for (;;) {
00403                 c = getopt(argc, argv, "BdhKP:tv");
00404                 if (c < 0)
00405                         break;
00406                 switch (c) {
00407                 case 'h':
00408                         usage();
00409                         break;
00410                 case 'd':
00411                         debug++;
00412                         if (wpa_debug_level > 0)
00413                                 wpa_debug_level--;
00414                         break;
00415                 case 'B':
00416                         daemonize++;
00417                         break;
00418                 case 'K':
00419                         wpa_debug_show_keys++;
00420                         break;
00421                 case 'P':
00422                         os_free(pid_file);
00423                         pid_file = os_rel2abs_path(optarg);
00424                         break;
00425                 case 't':
00426                         wpa_debug_timestamp++;
00427                         break;
00428                 case 'v':
00429                         show_version();
00430                         exit(1);
00431                         break;
00432 
00433                 default:
00434                         usage();
00435                         break;
00436                 }
00437         }
00438 
00439         if (optind == argc)
00440                 usage();
00441 
00442         interfaces.count = argc - optind;
00443         interfaces.iface = os_malloc(interfaces.count *
00444                                      sizeof(struct hostapd_iface *));
00445         if (interfaces.iface == NULL) {
00446                 wpa_printf(MSG_ERROR, "malloc failed\n");
00447                 return -1;
00448         }
00449 
00450         if (hostapd_global_init(&interfaces))
00451                 return -1;
00452 
00453         /* Initialize interfaces */
00454         for (i = 0; i < interfaces.count; i++) {
00455                 interfaces.iface[i] = hostapd_interface_init(argv[optind + i],
00456                                                              debug);
00457                 if (!interfaces.iface[i])
00458                         goto out;
00459         }
00460 
00461         if (hostapd_global_run(&interfaces, daemonize, pid_file))
00462                 goto out;
00463 
00464         ret = 0;
00465 
00466  out:
00467         /* Deinitialize all interfaces */
00468         for (i = 0; i < interfaces.count; i++)
00469                 hostapd_interface_deinit(interfaces.iface[i]);
00470         os_free(interfaces.iface);
00471 
00472         hostapd_global_deinit(pid_file);
00473         os_free(pid_file);
00474 
00475         return ret;
00476 }
00477 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on Sat Nov 21 23:16:48 2009 for hostapd by  doxygen 1.6.1