static struct hostapd_iface * hostapd_interface_init(struct hapd_interfaces *interfaces, const char *config_fname, int debug) { struct hostapd_iface *iface; int k; wpa_printf(MSG_ERROR, "Configuration file: %s", config_fname); iface = hostapd_init(config_fname); if (!iface) return NULL; iface->interfaces = interfaces; for (k = 0; k < debug; k++) { if (iface->bss[0]->conf->logger_stdout_level > 0) iface->bss[0]->conf->logger_stdout_level--; } if (iface->conf->bss[0].iface[0] != 0 || hostapd_drv_none(iface->bss[0])) { if (hostapd_driver_init(iface) || hostapd_setup_interface(iface)) { hostapd_interface_deinit_free(iface); return NULL; } } return iface; }
static int hostapd_setup_interface(hostapd *hapd) { if (hostapd_driver_init(hapd)) { printf("Host AP driver initialization failed.\n"); return -1; } printf("Using interface %sap with hwaddr " MACSTR " and ssid '%s'\n", hapd->conf->iface, MAC2STR(hapd->own_addr), hapd->conf->ssid); /* Set SSID for the kernel driver (to be used in beacon and probe * response frames) */ if (hostap_ioctl_setiwessid(hapd->driver.data, hapd->conf->ssid, hapd->conf->ssid_len)) { printf("Could not set SSID for kernel driver\n"); return -1; } if (radius_client_init(hapd)) { printf("RADIUS client initialization failed.\n"); return -1; } if (hostapd_acl_init(hapd)) { printf("ACL initialization failed.\n"); return -1; } if (ieee802_1x_init(hapd)) { printf("IEEE 802.1X initialization failed.\n"); return -1; } if (hapd->conf->wpa && wpa_init(hapd)) { printf("WPA initialization failed.\n"); return -1; } if (accounting_init(hapd)) { printf("Accounting initialization failed.\n"); return -1; } if (hapd->conf->ieee802_11f && iapp_init(hapd)) { printf("IEEE 802.11f (IAPP) initialization failed.\n"); return -1; } if (hostapd_wireless_event_init(hapd->driver.data) < 0) return -1; if (hapd->default_wep_key && hostapd_setup_encryption(hapd)) return -1; if (hostapd_flush_old_stations(hapd)) return -1; return 0; }
int main(int argc, char *argv[]) { struct hapd_interfaces interfaces; int ret = 1; size_t i, j; int c, debug = 0; const char *log_file = NULL; const char *entropy_file = NULL; char **bss_config = NULL, **tmp_bss; size_t num_bss_configs = 0; #ifdef CONFIG_DEBUG_LINUX_TRACING int enable_trace_dbg = 0; #endif /* CONFIG_DEBUG_LINUX_TRACING */ if (os_program_init()) return -1; os_memset(&interfaces, 0, sizeof(interfaces)); interfaces.reload_config = hostapd_reload_config; interfaces.config_read_cb = hostapd_config_read; interfaces.for_each_interface = hostapd_for_each_interface; interfaces.ctrl_iface_init = hostapd_ctrl_iface_init; interfaces.ctrl_iface_deinit = hostapd_ctrl_iface_deinit; interfaces.driver_init = hostapd_driver_init; interfaces.global_iface_path = NULL; interfaces.global_iface_name = NULL; interfaces.global_ctrl_sock = -1; wpa_supplicant_event = hostapd_wpa_event; for (;;) { c = getopt(argc, argv, "b:Bde:f:hKP:Ttu:g:G:v::"); if (c < 0) break; switch (c) { case 'h': usage(); break; case 'd': debug++; if (wpa_debug_level > 0) wpa_debug_level--; break; case 'B': daemonize++; break; case 'e': entropy_file = optarg; break; case 'f': log_file = optarg; break; case 'K': wpa_debug_show_keys++; break; case 'P': os_free(pid_file); pid_file = os_rel2abs_path(optarg); break; case 't': wpa_debug_timestamp++; break; #ifdef CONFIG_DEBUG_LINUX_TRACING case 'T': enable_trace_dbg = 1; break; #endif /* CONFIG_DEBUG_LINUX_TRACING */ case 'v': if (optarg) exit(!has_feature(optarg)); show_version(); exit(1); break; case 'g': if (hostapd_get_global_ctrl_iface(&interfaces, optarg)) return -1; break; case 'G': if (hostapd_get_ctrl_iface_group(&interfaces, optarg)) return -1; break; case 'b': tmp_bss = os_realloc_array(bss_config, num_bss_configs + 1, sizeof(char *)); if (tmp_bss == NULL) goto out; bss_config = tmp_bss; bss_config[num_bss_configs++] = optarg; break; #ifdef CONFIG_WPS case 'u': return gen_uuid(optarg); #endif /* CONFIG_WPS */ default: usage(); break; } } if (optind == argc && interfaces.global_iface_path == NULL && num_bss_configs == 0) usage(); wpa_msg_register_ifname_cb(hostapd_msg_ifname_cb); if (log_file) wpa_debug_open_file(log_file); #ifdef CONFIG_DEBUG_LINUX_TRACING if (enable_trace_dbg) { int tret = wpa_debug_open_linux_tracing(); if (tret) { wpa_printf(MSG_ERROR, "Failed to enable trace logging"); return -1; } } #endif /* CONFIG_DEBUG_LINUX_TRACING */ interfaces.count = argc - optind; if (interfaces.count || num_bss_configs) { interfaces.iface = os_calloc(interfaces.count + num_bss_configs, sizeof(struct hostapd_iface *)); if (interfaces.iface == NULL) { wpa_printf(MSG_ERROR, "malloc failed"); return -1; } } if (hostapd_global_init(&interfaces, entropy_file)) { wpa_printf(MSG_ERROR, "Failed to initilize global context"); return -1; } /* Allocate and parse configuration for full interface files */ for (i = 0; i < interfaces.count; i++) { interfaces.iface[i] = hostapd_interface_init(&interfaces, argv[optind + i], debug); if (!interfaces.iface[i]) { wpa_printf(MSG_ERROR, "Failed to initialize interface"); goto out; } } /* Allocate and parse configuration for per-BSS files */ for (i = 0; i < num_bss_configs; i++) { struct hostapd_iface *iface; char *fname; wpa_printf(MSG_INFO, "BSS config: %s", bss_config[i]); fname = os_strchr(bss_config[i], ':'); if (fname == NULL) { wpa_printf(MSG_ERROR, "Invalid BSS config identifier '%s'", bss_config[i]); goto out; } *fname++ = '\0'; iface = hostapd_interface_init_bss(&interfaces, bss_config[i], fname, debug); if (iface == NULL) goto out; for (j = 0; j < interfaces.count; j++) { if (interfaces.iface[j] == iface) break; } if (j == interfaces.count) { struct hostapd_iface **tmp; tmp = os_realloc_array(interfaces.iface, interfaces.count + 1, sizeof(struct hostapd_iface *)); if (tmp == NULL) { hostapd_interface_deinit_free(iface); goto out; } interfaces.iface = tmp; interfaces.iface[interfaces.count++] = iface; } } /* * Enable configured interfaces. Depending on channel configuration, * this may complete full initialization before returning or use a * callback mechanism to complete setup in case of operations like HT * co-ex scans, ACS, or DFS are needed to determine channel parameters. * In such case, the interface will be enabled from eloop context within * hostapd_global_run(). */ interfaces.terminate_on_error = interfaces.count; for (i = 0; i < interfaces.count; i++) { if (hostapd_driver_init(interfaces.iface[i]) || hostapd_setup_interface(interfaces.iface[i])) goto out; } hostapd_global_ctrl_iface_init(&interfaces); if (hostapd_global_run(&interfaces, daemonize, pid_file)) { wpa_printf(MSG_ERROR, "Failed to start eloop"); goto out; } ret = 0; out: hostapd_global_ctrl_iface_deinit(&interfaces); /* Deinitialize all interfaces */ for (i = 0; i < interfaces.count; i++) { if (!interfaces.iface[i]) continue; interfaces.iface[i]->driver_ap_teardown = !!(interfaces.iface[i]->drv_flags & WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT); hostapd_interface_deinit_free(interfaces.iface[i]); } os_free(interfaces.iface); hostapd_global_deinit(pid_file); os_free(pid_file); if (log_file) wpa_debug_close_file(); wpa_debug_close_linux_tracing(); os_free(bss_config); os_program_deinit(); return ret; }
static int hostapd_setup_interface(struct hostapd_data *hapd) { struct hostapd_config *conf = hapd->conf; u8 ssid[HOSTAPD_SSID_LEN + 1]; int ssid_len, set_ssid; int ret = 0; if (hostapd_driver_init(hapd)) { printf("%s driver initialization failed.\n", hapd->driver ? hapd->driver->name : "Unknown"); hapd->driver = NULL; return -1; } /* * Fetch the SSID from the system and use it or, * if one was specified in the config file, verify they * match. */ ssid_len = hostapd_get_ssid(hapd, ssid, sizeof(ssid)); if (ssid_len < 0) { printf("Could not read SSID from system\n"); return -1; } if (conf->ssid_set) { /* * If SSID is specified in the config file and it differs * from what is being used then force installation of the * new SSID. */ set_ssid = (conf->ssid_len != ssid_len || memcmp(conf->ssid, ssid, ssid_len) != 0); } else { /* * No SSID in the config file; just use the one we got * from the system. */ set_ssid = 0; conf->ssid_len = ssid_len; memcpy(conf->ssid, ssid, conf->ssid_len); conf->ssid[conf->ssid_len] = '\0'; } printf("Using interface %s with hwaddr " MACSTR " and ssid '%s'\n", hapd->conf->iface, MAC2STR(hapd->own_addr), hapd->conf->ssid); if (hostapd_setup_wpa_psk(conf)) { printf("WPA-PSK setup failed.\n"); return -1; } /* Set SSID for the kernel driver (to be used in beacon and probe * response frames) */ if (set_ssid && hostapd_set_ssid(hapd, (u8 *) conf->ssid, conf->ssid_len)) { printf("Could not set SSID for kernel driver\n"); return -1; } if (HOSTAPD_DEBUG_COND(HOSTAPD_DEBUG_MSGDUMPS)) conf->radius->msg_dumps = 1; hapd->radius = radius_client_init(hapd, conf->radius); if (hapd->radius == NULL) { printf("RADIUS client initialization failed.\n"); return -1; } if (conf->radius_server_clients) { struct radius_server_conf srv; memset(&srv, 0, sizeof(srv)); srv.client_file = conf->radius_server_clients; srv.auth_port = conf->radius_server_auth_port; srv.hostapd_conf = conf; srv.eap_sim_db_priv = hapd->eap_sim_db_priv; srv.ssl_ctx = hapd->ssl_ctx; srv.ipv6 = conf->radius_server_ipv6; hapd->radius_srv = radius_server_init(&srv); if (hapd->radius_srv == NULL) { printf("RADIUS server initialization failed.\n"); return -1; } } if (hostapd_acl_init(hapd)) { printf("ACL initialization failed.\n"); return -1; } if (ieee802_1x_init(hapd)) { printf("IEEE 802.1X initialization failed.\n"); return -1; } if (hapd->conf->wpa && wpa_init(hapd)) { printf("WPA initialization failed.\n"); return -1; } #ifdef SIMPLE_CONFIG if (wsc_ie_init(hapd) < 0) { printf("WSC IE initialization failed.\n"); return -1; } #endif if (accounting_init(hapd)) { printf("Accounting initialization failed.\n"); return -1; } if (hapd->conf->ieee802_11f && (hapd->iapp = iapp_init(hapd, hapd->conf->iapp_iface)) == NULL) { printf("IEEE 802.11F (IAPP) initialization failed.\n"); return -1; } if (hostapd_wireless_event_init(hapd) < 0) return -1; if (hostapd_flush_old_stations(hapd)) return -1; if (hostapd_ctrl_iface_init(hapd)) { printf("Failed to setup control interface\n"); ret = -1; } return ret; }