LCOV - code coverage report
Current view: top level - hostapd - main.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1401264779 Lines: 228 368 62.0 %
Date: 2014-05-28 Functions: 11 17 64.7 %

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

Generated by: LCOV version 1.10