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 1422976643 Lines: 280 373 75.1 %
Date: 2015-02-03 Functions: 14 17 82.4 %

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

Generated by: LCOV version 1.10