LCOV - code coverage report
Current view: top level - tmp/logs/alt-hostapd/hostapd - main.c (source / functions) Hit Total Coverage
Test: hostapd hwsim test run 1412854115 Lines: 206 368 56.0 %
Date: 2014-10-09 Functions: 10 17 58.8 %

          Line data    Source code
       1             : /*
       2             :  * hostapd / main()
       3             :  * Copyright (c) 2002-2011, Jouni Malinen <j@w1.fi>
       4             :  *
       5             :  * This software may be distributed under the terms of the BSD license.
       6             :  * See README for more details.
       7             :  */
       8             : 
       9             : #include "utils/includes.h"
      10             : #ifndef CONFIG_NATIVE_WINDOWS
      11             : #include <syslog.h>
      12             : #include <grp.h>
      13             : #endif /* CONFIG_NATIVE_WINDOWS */
      14             : 
      15             : #include "utils/common.h"
      16             : #include "utils/eloop.h"
      17             : #include "utils/uuid.h"
      18             : #include "crypto/random.h"
      19             : #include "crypto/tls.h"
      20             : #include "common/version.h"
      21             : #include "drivers/driver.h"
      22             : #include "eap_server/eap.h"
      23             : #include "eap_server/tncs.h"
      24             : #include "ap/hostapd.h"
      25             : #include "ap/ap_config.h"
      26             : #include "ap/ap_drv_ops.h"
      27             : #include "config_file.h"
      28             : #include "eap_register.h"
      29             : #include "ctrl_iface.h"
      30             : 
      31             : 
      32             : struct hapd_global {
      33             :         void **drv_priv;
      34             :         size_t drv_count;
      35             : };
      36             : 
      37             : static struct hapd_global global;
      38             : 
      39             : 
      40             : #ifndef CONFIG_NO_HOSTAPD_LOGGER
      41       47145 : static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module,
      42             :                               int level, const char *txt, size_t len)
      43             : {
      44       47145 :         struct hostapd_data *hapd = ctx;
      45             :         char *format, *module_str;
      46             :         int maxlen;
      47             :         int conf_syslog_level, conf_stdout_level;
      48             :         unsigned int conf_syslog, conf_stdout;
      49             : 
      50       47145 :         maxlen = len + 100;
      51       47145 :         format = os_malloc(maxlen);
      52       47145 :         if (!format)
      53       47145 :                 return;
      54             : 
      55       47145 :         if (hapd && hapd->conf) {
      56       47145 :                 conf_syslog_level = hapd->conf->logger_syslog_level;
      57       47145 :                 conf_stdout_level = hapd->conf->logger_stdout_level;
      58       47145 :                 conf_syslog = hapd->conf->logger_syslog;
      59       47145 :                 conf_stdout = hapd->conf->logger_stdout;
      60             :         } else {
      61           0 :                 conf_syslog_level = conf_stdout_level = 0;
      62           0 :                 conf_syslog = conf_stdout = (unsigned int) -1;
      63             :         }
      64             : 
      65       47145 :         switch (module) {
      66             :         case HOSTAPD_MODULE_IEEE80211:
      67        5941 :                 module_str = "IEEE 802.11";
      68        5941 :                 break;
      69             :         case HOSTAPD_MODULE_IEEE8021X:
      70       12428 :                 module_str = "IEEE 802.1X";
      71       12428 :                 break;
      72             :         case HOSTAPD_MODULE_RADIUS:
      73       15813 :                 module_str = "RADIUS";
      74       15813 :                 break;
      75             :         case HOSTAPD_MODULE_WPA:
      76        6172 :                 module_str = "WPA";
      77        6172 :                 break;
      78             :         case HOSTAPD_MODULE_DRIVER:
      79           0 :                 module_str = "DRIVER";
      80           0 :                 break;
      81             :         case HOSTAPD_MODULE_IAPP:
      82           0 :                 module_str = "IAPP";
      83           0 :                 break;
      84             :         case HOSTAPD_MODULE_MLME:
      85        6791 :                 module_str = "MLME";
      86        6791 :                 break;
      87             :         default:
      88           0 :                 module_str = NULL;
      89           0 :                 break;
      90             :         }
      91             : 
      92       47145 :         if (hapd && hapd->conf && addr)
      93      282032 :                 os_snprintf(format, maxlen, "%s: STA " MACSTR "%s%s: %s",
      94      246778 :                             hapd->conf->iface, MAC2STR(addr),
      95             :                             module_str ? " " : "", module_str ? module_str : "",
      96             :                             txt);
      97       11891 :         else if (hapd && hapd->conf)
      98       23782 :                 os_snprintf(format, maxlen, "%s:%s%s %s",
      99       11891 :                             hapd->conf->iface, module_str ? " " : "",
     100             :                             module_str ? module_str : "", txt);
     101           0 :         else if (addr)
     102           0 :                 os_snprintf(format, maxlen, "STA " MACSTR "%s%s: %s",
     103           0 :                             MAC2STR(addr), module_str ? " " : "",
     104             :                             module_str ? module_str : "", txt);
     105             :         else
     106           0 :                 os_snprintf(format, maxlen, "%s%s%s",
     107             :                             module_str ? module_str : "",
     108             :                             module_str ? ": " : "", txt);
     109             : 
     110       47145 :         if ((conf_stdout & module) && level >= conf_stdout_level) {
     111       46620 :                 wpa_debug_print_timestamp();
     112       46620 :                 wpa_printf(MSG_INFO, "%s", format);
     113             :         }
     114             : 
     115             : #ifndef CONFIG_NATIVE_WINDOWS
     116       47145 :         if ((conf_syslog & module) && level >= conf_syslog_level) {
     117             :                 int priority;
     118        6428 :                 switch (level) {
     119             :                 case HOSTAPD_LEVEL_DEBUG_VERBOSE:
     120             :                 case HOSTAPD_LEVEL_DEBUG:
     121           0 :                         priority = LOG_DEBUG;
     122           0 :                         break;
     123             :                 case HOSTAPD_LEVEL_INFO:
     124        6242 :                         priority = LOG_INFO;
     125        6242 :                         break;
     126             :                 case HOSTAPD_LEVEL_NOTICE:
     127           2 :                         priority = LOG_NOTICE;
     128           2 :                         break;
     129             :                 case HOSTAPD_LEVEL_WARNING:
     130         184 :                         priority = LOG_WARNING;
     131         184 :                         break;
     132             :                 default:
     133           0 :                         priority = LOG_INFO;
     134           0 :                         break;
     135             :                 }
     136        6428 :                 syslog(priority, "%s", format);
     137             :         }
     138             : #endif /* CONFIG_NATIVE_WINDOWS */
     139             : 
     140       47145 :         os_free(format);
     141             : }
     142             : #endif /* CONFIG_NO_HOSTAPD_LOGGER */
     143             : 
     144             : 
     145             : /**
     146             :  * hostapd_driver_init - Preparate driver interface
     147             :  */
     148         631 : static int hostapd_driver_init(struct hostapd_iface *iface)
     149             : {
     150             :         struct wpa_init_params params;
     151             :         size_t i;
     152         631 :         struct hostapd_data *hapd = iface->bss[0];
     153         631 :         struct hostapd_bss_config *conf = hapd->conf;
     154         631 :         u8 *b = conf->bssid;
     155             :         struct wpa_driver_capa capa;
     156             : 
     157         631 :         if (hapd->driver == NULL || hapd->driver->hapd_init == NULL) {
     158           0 :                 wpa_printf(MSG_ERROR, "No hostapd driver wrapper available");
     159           0 :                 return -1;
     160             :         }
     161             : 
     162             :         /* Initialize the driver interface */
     163         631 :         if (!(b[0] | b[1] | b[2] | b[3] | b[4] | b[5]))
     164         623 :                 b = NULL;
     165             : 
     166         631 :         os_memset(&params, 0, sizeof(params));
     167        1262 :         for (i = 0; wpa_drivers[i]; i++) {
     168         631 :                 if (wpa_drivers[i] != hapd->driver)
     169           0 :                         continue;
     170             : 
     171         632 :                 if (global.drv_priv[i] == NULL &&
     172           1 :                     wpa_drivers[i]->global_init) {
     173           1 :                         global.drv_priv[i] = wpa_drivers[i]->global_init();
     174           1 :                         if (global.drv_priv[i] == NULL) {
     175           0 :                                 wpa_printf(MSG_ERROR, "Failed to initialize "
     176             :                                            "driver '%s'",
     177           0 :                                            wpa_drivers[i]->name);
     178           0 :                                 return -1;
     179             :                         }
     180             :                 }
     181             : 
     182         631 :                 params.global_priv = global.drv_priv[i];
     183         631 :                 break;
     184             :         }
     185         631 :         params.bssid = b;
     186         631 :         params.ifname = hapd->conf->iface;
     187         631 :         params.ssid = hapd->conf->ssid.ssid;
     188         631 :         params.ssid_len = hapd->conf->ssid.ssid_len;
     189         631 :         params.test_socket = hapd->conf->test_socket;
     190         631 :         params.use_pae_group_addr = hapd->conf->use_pae_group_addr;
     191             : 
     192         631 :         params.num_bridge = hapd->iface->num_bss;
     193         631 :         params.bridge = os_calloc(hapd->iface->num_bss, sizeof(char *));
     194         631 :         if (params.bridge == NULL)
     195           0 :                 return -1;
     196        1269 :         for (i = 0; i < hapd->iface->num_bss; i++) {
     197         638 :                 struct hostapd_data *bss = hapd->iface->bss[i];
     198         638 :                 if (bss->conf->bridge[0])
     199           5 :                         params.bridge[i] = bss->conf->bridge;
     200             :         }
     201             : 
     202         631 :         params.own_addr = hapd->own_addr;
     203             : 
     204         631 :         hapd->drv_priv = hapd->driver->hapd_init(hapd, &params);
     205         631 :         os_free(params.bridge);
     206         631 :         if (hapd->drv_priv == NULL) {
     207           0 :                 wpa_printf(MSG_ERROR, "%s driver initialization failed.",
     208           0 :                            hapd->driver->name);
     209           0 :                 hapd->driver = NULL;
     210           0 :                 return -1;
     211             :         }
     212             : 
     213        1262 :         if (hapd->driver->get_capa &&
     214         631 :             hapd->driver->get_capa(hapd->drv_priv, &capa) == 0) {
     215         631 :                 iface->drv_flags = capa.flags;
     216         631 :                 iface->probe_resp_offloads = capa.probe_resp_offloads;
     217         631 :                 iface->extended_capa = capa.extended_capa;
     218         631 :                 iface->extended_capa_mask = capa.extended_capa_mask;
     219         631 :                 iface->extended_capa_len = capa.extended_capa_len;
     220         631 :                 iface->drv_max_acl_mac_addrs = capa.max_acl_mac_addrs;
     221             :         }
     222             : 
     223         631 :         return 0;
     224             : }
     225             : 
     226             : 
     227             : /**
     228             :  * hostapd_interface_init - Read configuration file and init BSS data
     229             :  *
     230             :  * This function is used to parse configuration file for a full interface (one
     231             :  * or more BSSes sharing the same radio) and allocate memory for the BSS
     232             :  * interfaces. No actiual driver operations are started.
     233             :  */
     234             : static struct hostapd_iface *
     235           0 : hostapd_interface_init(struct hapd_interfaces *interfaces,
     236             :                        const char *config_fname, int debug)
     237             : {
     238             :         struct hostapd_iface *iface;
     239             :         int k;
     240             : 
     241           0 :         wpa_printf(MSG_ERROR, "Configuration file: %s", config_fname);
     242           0 :         iface = hostapd_init(interfaces, config_fname);
     243           0 :         if (!iface)
     244           0 :                 return NULL;
     245           0 :         iface->interfaces = interfaces;
     246             : 
     247           0 :         for (k = 0; k < debug; k++) {
     248           0 :                 if (iface->bss[0]->conf->logger_stdout_level > 0)
     249           0 :                         iface->bss[0]->conf->logger_stdout_level--;
     250             :         }
     251             : 
     252           0 :         if (iface->conf->bss[0]->iface[0] == '\0' &&
     253           0 :             !hostapd_drv_none(iface->bss[0])) {
     254           0 :                 wpa_printf(MSG_ERROR, "Interface name not specified in %s",
     255             :                            config_fname);
     256           0 :                 hostapd_interface_deinit_free(iface);
     257           0 :                 return NULL;
     258             :         }
     259             : 
     260           0 :         return iface;
     261             : }
     262             : 
     263             : 
     264             : /**
     265             :  * handle_term - SIGINT and SIGTERM handler to terminate hostapd process
     266             :  */
     267           1 : static void handle_term(int sig, void *signal_ctx)
     268             : {
     269           1 :         wpa_printf(MSG_DEBUG, "Signal %d received - terminating", sig);
     270           1 :         eloop_terminate();
     271           1 : }
     272             : 
     273             : 
     274             : #ifndef CONFIG_NATIVE_WINDOWS
     275             : 
     276           0 : static int handle_reload_iface(struct hostapd_iface *iface, void *ctx)
     277             : {
     278           0 :         if (hostapd_reload_config(iface) < 0) {
     279           0 :                 wpa_printf(MSG_WARNING, "Failed to read new configuration "
     280             :                            "file - continuing with old.");
     281             :         }
     282           0 :         return 0;
     283             : }
     284             : 
     285             : 
     286             : /**
     287             :  * handle_reload - SIGHUP handler to reload configuration
     288             :  */
     289           0 : static void handle_reload(int sig, void *signal_ctx)
     290             : {
     291           0 :         struct hapd_interfaces *interfaces = signal_ctx;
     292           0 :         wpa_printf(MSG_DEBUG, "Signal %d received - reloading configuration",
     293             :                    sig);
     294           0 :         hostapd_for_each_interface(interfaces, handle_reload_iface, NULL);
     295           0 : }
     296             : 
     297             : 
     298           0 : static void handle_dump_state(int sig, void *signal_ctx)
     299             : {
     300             :         /* Not used anymore - ignore signal */
     301           0 : }
     302             : #endif /* CONFIG_NATIVE_WINDOWS */
     303             : 
     304             : 
     305           1 : static int hostapd_global_init(struct hapd_interfaces *interfaces,
     306             :                                const char *entropy_file)
     307             : {
     308             :         int i;
     309             : 
     310           1 :         os_memset(&global, 0, sizeof(global));
     311             : 
     312           1 :         hostapd_logger_register_cb(hostapd_logger_cb);
     313             : 
     314           1 :         if (eap_server_register_methods()) {
     315           0 :                 wpa_printf(MSG_ERROR, "Failed to register EAP methods");
     316           0 :                 return -1;
     317             :         }
     318             : 
     319           1 :         if (eloop_init()) {
     320           0 :                 wpa_printf(MSG_ERROR, "Failed to initialize event loop");
     321           0 :                 return -1;
     322             :         }
     323             : 
     324             :         random_init(entropy_file);
     325             : 
     326             : #ifndef CONFIG_NATIVE_WINDOWS
     327           1 :         eloop_register_signal(SIGHUP, handle_reload, interfaces);
     328           1 :         eloop_register_signal(SIGUSR1, handle_dump_state, interfaces);
     329             : #endif /* CONFIG_NATIVE_WINDOWS */
     330           1 :         eloop_register_signal_terminate(handle_term, interfaces);
     331             : 
     332             : #ifndef CONFIG_NATIVE_WINDOWS
     333           1 :         openlog("hostapd", 0, LOG_DAEMON);
     334             : #endif /* CONFIG_NATIVE_WINDOWS */
     335             : 
     336           3 :         for (i = 0; wpa_drivers[i]; i++)
     337           2 :                 global.drv_count++;
     338           1 :         if (global.drv_count == 0) {
     339           0 :                 wpa_printf(MSG_ERROR, "No drivers enabled");
     340           0 :                 return -1;
     341             :         }
     342           1 :         global.drv_priv = os_calloc(global.drv_count, sizeof(void *));
     343           1 :         if (global.drv_priv == NULL)
     344           0 :                 return -1;
     345             : 
     346           1 :         return 0;
     347             : }
     348             : 
     349             : 
     350           1 : static void hostapd_global_deinit(const char *pid_file)
     351             : {
     352             :         int i;
     353             : 
     354           3 :         for (i = 0; wpa_drivers[i] && global.drv_priv; i++) {
     355           2 :                 if (!global.drv_priv[i])
     356           1 :                         continue;
     357           1 :                 wpa_drivers[i]->global_deinit(global.drv_priv[i]);
     358             :         }
     359           1 :         os_free(global.drv_priv);
     360           1 :         global.drv_priv = NULL;
     361             : 
     362             : #ifdef EAP_SERVER_TNC
     363           1 :         tncs_global_deinit();
     364             : #endif /* EAP_SERVER_TNC */
     365             : 
     366             :         random_deinit();
     367             : 
     368           1 :         eloop_destroy();
     369             : 
     370             : #ifndef CONFIG_NATIVE_WINDOWS
     371           1 :         closelog();
     372             : #endif /* CONFIG_NATIVE_WINDOWS */
     373             : 
     374           1 :         eap_server_unregister_methods();
     375             : 
     376           1 :         os_daemonize_terminate(pid_file);
     377           1 : }
     378             : 
     379             : 
     380           1 : static int hostapd_global_run(struct hapd_interfaces *ifaces, int daemonize,
     381             :                               const char *pid_file)
     382             : {
     383             : #ifdef EAP_SERVER_TNC
     384           1 :         int tnc = 0;
     385             :         size_t i, k;
     386             : 
     387           1 :         for (i = 0; !tnc && i < ifaces->count; i++) {
     388           0 :                 for (k = 0; k < ifaces->iface[i]->num_bss; k++) {
     389           0 :                         if (ifaces->iface[i]->bss[0]->conf->tnc) {
     390           0 :                                 tnc++;
     391           0 :                                 break;
     392             :                         }
     393             :                 }
     394             :         }
     395             : 
     396           1 :         if (tnc && tncs_global_init() < 0) {
     397           0 :                 wpa_printf(MSG_ERROR, "Failed to initialize TNCS");
     398           0 :                 return -1;
     399             :         }
     400             : #endif /* EAP_SERVER_TNC */
     401             : 
     402           1 :         if (daemonize && os_daemonize(pid_file)) {
     403           0 :                 perror("daemon");
     404           0 :                 return -1;
     405             :         }
     406             : 
     407           1 :         eloop_run();
     408             : 
     409           1 :         return 0;
     410             : }
     411             : 
     412             : 
     413           0 : static void show_version(void)
     414             : {
     415           0 :         fprintf(stderr,
     416             :                 "hostapd v" VERSION_STR "\n"
     417             :                 "User space daemon for IEEE 802.11 AP management,\n"
     418             :                 "IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator\n"
     419             :                 "Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi> "
     420             :                 "and contributors\n");
     421           0 : }
     422             : 
     423             : 
     424           0 : static void usage(void)
     425             : {
     426           0 :         show_version();
     427           0 :         fprintf(stderr,
     428             :                 "\n"
     429             :                 "usage: hostapd [-hdBKtv] [-P <PID file>] [-e <entropy file>] "
     430             :                 "\\\n"
     431             :                 "         [-g <global ctrl_iface>] [-G <group>] \\\n"
     432             :                 "         <configuration file(s)>\n"
     433             :                 "\n"
     434             :                 "options:\n"
     435             :                 "   -h   show this usage\n"
     436             :                 "   -d   show more debug messages (-dd for even more)\n"
     437             :                 "   -B   run daemon in the background\n"
     438             :                 "   -e   entropy file\n"
     439             :                 "   -g   global control interface path\n"
     440             :                 "   -G   group for control interfaces\n"
     441             :                 "   -P   PID file\n"
     442             :                 "   -K   include key data in debug messages\n"
     443             : #ifdef CONFIG_DEBUG_FILE
     444             :                 "   -f   log output to debug file instead of stdout\n"
     445             : #endif /* CONFIG_DEBUG_FILE */
     446             : #ifdef CONFIG_DEBUG_LINUX_TRACING
     447             :                 "   -T = record to Linux tracing in addition to logging\n"
     448             :                 "        (records all messages regardless of debug verbosity)\n"
     449             : #endif /* CONFIG_DEBUG_LINUX_TRACING */
     450             :                 "   -t   include timestamps in some debug messages\n"
     451             :                 "   -v   show hostapd version\n");
     452             : 
     453           0 :         exit(1);
     454             : }
     455             : 
     456             : 
     457       31215 : static const char * hostapd_msg_ifname_cb(void *ctx)
     458             : {
     459       31215 :         struct hostapd_data *hapd = ctx;
     460       62430 :         if (hapd && hapd->iconf && hapd->iconf->bss &&
     461       62430 :             hapd->iconf->num_bss > 0 && hapd->iconf->bss[0])
     462       31215 :                 return hapd->iconf->bss[0]->iface;
     463           0 :         return NULL;
     464             : }
     465             : 
     466             : 
     467           1 : static int hostapd_get_global_ctrl_iface(struct hapd_interfaces *interfaces,
     468             :                                          const char *path)
     469             : {
     470             :         char *pos;
     471           1 :         os_free(interfaces->global_iface_path);
     472           1 :         interfaces->global_iface_path = os_strdup(path);
     473           1 :         if (interfaces->global_iface_path == NULL)
     474           0 :                 return -1;
     475           1 :         pos = os_strrchr(interfaces->global_iface_path, '/');
     476           1 :         if (pos == NULL) {
     477           0 :                 wpa_printf(MSG_ERROR, "No '/' in the global control interface "
     478             :                            "file");
     479           0 :                 os_free(interfaces->global_iface_path);
     480           0 :                 interfaces->global_iface_path = NULL;
     481           0 :                 return -1;
     482             :         }
     483             : 
     484           1 :         *pos = '\0';
     485           1 :         interfaces->global_iface_name = pos + 1;
     486             : 
     487           1 :         return 0;
     488             : }
     489             : 
     490             : 
     491           1 : static int hostapd_get_ctrl_iface_group(struct hapd_interfaces *interfaces,
     492             :                                         const char *group)
     493             : {
     494             : #ifndef CONFIG_NATIVE_WINDOWS
     495             :         struct group *grp;
     496           1 :         grp = getgrnam(group);
     497           1 :         if (grp == NULL) {
     498           0 :                 wpa_printf(MSG_ERROR, "Unknown group '%s'", group);
     499           0 :                 return -1;
     500             :         }
     501           1 :         interfaces->ctrl_iface_group = grp->gr_gid;
     502             : #endif /* CONFIG_NATIVE_WINDOWS */
     503           1 :         return 0;
     504             : }
     505             : 
     506             : 
     507             : #ifdef CONFIG_WPS
     508           0 : static int gen_uuid(const char *txt_addr)
     509             : {
     510             :         u8 addr[ETH_ALEN];
     511             :         u8 uuid[UUID_LEN];
     512             :         char buf[100];
     513             : 
     514           0 :         if (hwaddr_aton(txt_addr, addr) < 0)
     515           0 :                 return -1;
     516             : 
     517           0 :         uuid_gen_mac_addr(addr, uuid);
     518           0 :         if (uuid_bin2str(uuid, buf, sizeof(buf)) < 0)
     519           0 :                 return -1;
     520             : 
     521           0 :         printf("%s\n", buf);
     522             : 
     523           0 :         return 0;
     524             : }
     525             : #endif /* CONFIG_WPS */
     526             : 
     527             : 
     528           1 : int main(int argc, char *argv[])
     529             : {
     530             :         struct hapd_interfaces interfaces;
     531           1 :         int ret = 1;
     532             :         size_t i, j;
     533           1 :         int c, debug = 0, daemonize = 0;
     534           1 :         char *pid_file = NULL;
     535           1 :         const char *log_file = NULL;
     536           1 :         const char *entropy_file = NULL;
     537           1 :         char **bss_config = NULL, **tmp_bss;
     538           1 :         size_t num_bss_configs = 0;
     539             : #ifdef CONFIG_DEBUG_LINUX_TRACING
     540           1 :         int enable_trace_dbg = 0;
     541             : #endif /* CONFIG_DEBUG_LINUX_TRACING */
     542             : 
     543           1 :         if (os_program_init())
     544           0 :                 return -1;
     545             : 
     546           1 :         os_memset(&interfaces, 0, sizeof(interfaces));
     547           1 :         interfaces.reload_config = hostapd_reload_config;
     548           1 :         interfaces.config_read_cb = hostapd_config_read;
     549           1 :         interfaces.for_each_interface = hostapd_for_each_interface;
     550           1 :         interfaces.ctrl_iface_init = hostapd_ctrl_iface_init;
     551           1 :         interfaces.ctrl_iface_deinit = hostapd_ctrl_iface_deinit;
     552           1 :         interfaces.driver_init = hostapd_driver_init;
     553           1 :         interfaces.global_iface_path = NULL;
     554           1 :         interfaces.global_iface_name = NULL;
     555           1 :         interfaces.global_ctrl_sock = -1;
     556             : 
     557             :         for (;;) {
     558          12 :                 c = getopt(argc, argv, "b:Bde:f:hKP:Ttu:vg:G:");
     559          12 :                 if (c < 0)
     560           1 :                         break;
     561          11 :                 switch (c) {
     562             :                 case 'h':
     563           0 :                         usage();
     564           0 :                         break;
     565             :                 case 'd':
     566           4 :                         debug++;
     567           4 :                         if (wpa_debug_level > 0)
     568           3 :                                 wpa_debug_level--;
     569           4 :                         break;
     570             :                 case 'B':
     571           0 :                         daemonize++;
     572           0 :                         break;
     573             :                 case 'e':
     574           0 :                         entropy_file = optarg;
     575           0 :                         break;
     576             :                 case 'f':
     577           1 :                         log_file = optarg;
     578           1 :                         break;
     579             :                 case 'K':
     580           2 :                         wpa_debug_show_keys++;
     581           2 :                         break;
     582             :                 case 'P':
     583           0 :                         os_free(pid_file);
     584           0 :                         pid_file = os_rel2abs_path(optarg);
     585           0 :                         break;
     586             :                 case 't':
     587           2 :                         wpa_debug_timestamp++;
     588           2 :                         break;
     589             : #ifdef CONFIG_DEBUG_LINUX_TRACING
     590             :                 case 'T':
     591           0 :                         enable_trace_dbg = 1;
     592           0 :                         break;
     593             : #endif /* CONFIG_DEBUG_LINUX_TRACING */
     594             :                 case 'v':
     595           0 :                         show_version();
     596           0 :                         exit(1);
     597             :                         break;
     598             :                 case 'g':
     599           1 :                         if (hostapd_get_global_ctrl_iface(&interfaces, optarg))
     600           0 :                                 return -1;
     601           1 :                         break;
     602             :                 case 'G':
     603           1 :                         if (hostapd_get_ctrl_iface_group(&interfaces, optarg))
     604           0 :                                 return -1;
     605           1 :                         break;
     606             :                 case 'b':
     607           0 :                         tmp_bss = os_realloc_array(bss_config,
     608             :                                                    num_bss_configs + 1,
     609             :                                                    sizeof(char *));
     610           0 :                         if (tmp_bss == NULL)
     611           0 :                                 goto out;
     612           0 :                         bss_config = tmp_bss;
     613           0 :                         bss_config[num_bss_configs++] = optarg;
     614           0 :                         break;
     615             : #ifdef CONFIG_WPS
     616             :                 case 'u':
     617           0 :                         return gen_uuid(optarg);
     618             : #endif /* CONFIG_WPS */
     619             :                 default:
     620           0 :                         usage();
     621           0 :                         break;
     622             :                 }
     623          11 :         }
     624             : 
     625           1 :         if (optind == argc && interfaces.global_iface_path == NULL &&
     626             :             num_bss_configs == 0)
     627           0 :                 usage();
     628             : 
     629           1 :         wpa_msg_register_ifname_cb(hostapd_msg_ifname_cb);
     630             : 
     631           1 :         if (log_file)
     632           1 :                 wpa_debug_open_file(log_file);
     633             : #ifdef CONFIG_DEBUG_LINUX_TRACING
     634           1 :         if (enable_trace_dbg) {
     635           0 :                 int tret = wpa_debug_open_linux_tracing();
     636           0 :                 if (tret) {
     637           0 :                         wpa_printf(MSG_ERROR, "Failed to enable trace logging");
     638           0 :                         return -1;
     639             :                 }
     640             :         }
     641             : #endif /* CONFIG_DEBUG_LINUX_TRACING */
     642             : 
     643           1 :         interfaces.count = argc - optind;
     644           1 :         if (interfaces.count || num_bss_configs) {
     645           0 :                 interfaces.iface = os_calloc(interfaces.count + num_bss_configs,
     646             :                                              sizeof(struct hostapd_iface *));
     647           0 :                 if (interfaces.iface == NULL) {
     648           0 :                         wpa_printf(MSG_ERROR, "malloc failed");
     649           0 :                         return -1;
     650             :                 }
     651             :         }
     652             : 
     653           1 :         if (hostapd_global_init(&interfaces, entropy_file)) {
     654           0 :                 wpa_printf(MSG_ERROR, "Failed to initilize global context");
     655           0 :                 return -1;
     656             :         }
     657             : 
     658             :         /* Allocate and parse configuration for full interface files */
     659           1 :         for (i = 0; i < interfaces.count; i++) {
     660           0 :                 interfaces.iface[i] = hostapd_interface_init(&interfaces,
     661           0 :                                                              argv[optind + i],
     662             :                                                              debug);
     663           0 :                 if (!interfaces.iface[i]) {
     664           0 :                         wpa_printf(MSG_ERROR, "Failed to initialize interface");
     665           0 :                         goto out;
     666             :                 }
     667             :         }
     668             : 
     669             :         /* Allocate and parse configuration for per-BSS files */
     670           1 :         for (i = 0; i < num_bss_configs; i++) {
     671             :                 struct hostapd_iface *iface;
     672             :                 char *fname;
     673             : 
     674           0 :                 wpa_printf(MSG_INFO, "BSS config: %s", bss_config[i]);
     675           0 :                 fname = os_strchr(bss_config[i], ':');
     676           0 :                 if (fname == NULL) {
     677           0 :                         wpa_printf(MSG_ERROR,
     678             :                                    "Invalid BSS config identifier '%s'",
     679           0 :                                    bss_config[i]);
     680           0 :                         goto out;
     681             :                 }
     682           0 :                 *fname++ = '\0';
     683           0 :                 iface = hostapd_interface_init_bss(&interfaces, bss_config[i],
     684             :                                                    fname, debug);
     685           0 :                 if (iface == NULL)
     686           0 :                         goto out;
     687           0 :                 for (j = 0; j < interfaces.count; j++) {
     688           0 :                         if (interfaces.iface[j] == iface)
     689           0 :                                 break;
     690             :                 }
     691           0 :                 if (j == interfaces.count) {
     692             :                         struct hostapd_iface **tmp;
     693           0 :                         tmp = os_realloc_array(interfaces.iface,
     694           0 :                                                interfaces.count + 1,
     695             :                                                sizeof(struct hostapd_iface *));
     696           0 :                         if (tmp == NULL) {
     697           0 :                                 hostapd_interface_deinit_free(iface);
     698           0 :                                 goto out;
     699             :                         }
     700           0 :                         interfaces.iface = tmp;
     701           0 :                         interfaces.iface[interfaces.count++] = iface;
     702             :                 }
     703             :         }
     704             : 
     705             :         /*
     706             :          * Enable configured interfaces. Depending on channel configuration,
     707             :          * this may complete full initialization before returning or use a
     708             :          * callback mechanism to complete setup in case of operations like HT
     709             :          * co-ex scans, ACS, or DFS are needed to determine channel parameters.
     710             :          * In such case, the interface will be enabled from eloop context within
     711             :          * hostapd_global_run().
     712             :          */
     713           1 :         interfaces.terminate_on_error = interfaces.count;
     714           1 :         for (i = 0; i < interfaces.count; i++) {
     715           0 :                 if (hostapd_driver_init(interfaces.iface[i]) ||
     716           0 :                     hostapd_setup_interface(interfaces.iface[i]))
     717             :                         goto out;
     718             :         }
     719             : 
     720           1 :         hostapd_global_ctrl_iface_init(&interfaces);
     721             : 
     722           1 :         if (hostapd_global_run(&interfaces, daemonize, pid_file)) {
     723           0 :                 wpa_printf(MSG_ERROR, "Failed to start eloop");
     724           0 :                 goto out;
     725             :         }
     726             : 
     727           1 :         ret = 0;
     728             : 
     729             :  out:
     730           1 :         hostapd_global_ctrl_iface_deinit(&interfaces);
     731             :         /* Deinitialize all interfaces */
     732           1 :         for (i = 0; i < interfaces.count; i++) {
     733           0 :                 if (!interfaces.iface[i])
     734           0 :                         continue;
     735           0 :                 interfaces.iface[i]->driver_ap_teardown =
     736           0 :                         !!(interfaces.iface[i]->drv_flags &
     737             :                            WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
     738           0 :                 hostapd_interface_deinit_free(interfaces.iface[i]);
     739             :         }
     740           1 :         os_free(interfaces.iface);
     741             : 
     742           1 :         hostapd_global_deinit(pid_file);
     743           1 :         os_free(pid_file);
     744             : 
     745           1 :         if (log_file)
     746           1 :                 wpa_debug_close_file();
     747           1 :         wpa_debug_close_linux_tracing();
     748             : 
     749           1 :         os_free(bss_config);
     750             : 
     751           1 :         os_program_deinit();
     752             : 
     753           1 :         return ret;
     754             : }

Generated by: LCOV version 1.10