int main(int argc, char *argv[]) { struct hapd_interfaces interfaces; int ret = 1; size_t i, j; int c, debug = 0, daemonize = 0; char *pid_file = NULL; 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; for (;;) { c = getopt(argc, argv, "b:Bde:f:hKP:Ttu:vg:G:"); 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': 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); else wpa_debug_setup_stdout(); #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; }
int main(int argc, char *argv[]) { int c; const char *read_file = NULL; const char *read_wired_file = NULL; const char *ifname = NULL; const char *ifname_wired = NULL; const char *logfile = NULL; struct wlantest wt; int ctrl_iface = 0; wpa_debug_level = MSG_INFO; wpa_debug_show_keys = 1; if (os_program_init()) return -1; wlantest_init(&wt); for (;;) { c = getopt(argc, argv, "cdf:Fhi:I:L:n:p:P:qr:R:tT:w:W:"); if (c < 0) break; switch (c) { case 'c': ctrl_iface = 1; break; case 'd': if (wpa_debug_level > 0) wpa_debug_level--; break; case 'f': if (add_pmk_file(&wt, optarg) < 0) return -1; break; case 'F': wt.assume_fcs = 1; break; case 'h': usage(); return 0; case 'i': ifname = optarg; break; case 'I': ifname_wired = optarg; break; case 'L': logfile = optarg; break; case 'n': wt.pcapng_file = optarg; break; case 'p': add_passphrase(&wt, optarg); break; case 'P': add_secret(&wt, optarg); break; case 'q': wpa_debug_level++; break; case 'r': read_file = optarg; break; case 'R': read_wired_file = optarg; break; case 't': wpa_debug_timestamp = 1; break; case 'T': if (add_ptk_file(&wt, optarg) < 0) return -1; break; case 'w': wt.write_file = optarg; break; case 'W': if (add_wep(&wt, optarg) < 0) return -1; break; default: usage(); return -1; } } if (ifname == NULL && ifname_wired == NULL && read_file == NULL && read_wired_file == NULL) { usage(); return 0; } if (eloop_init()) return -1; if (logfile) wpa_debug_open_file(logfile); if (wt.write_file && write_pcap_init(&wt, wt.write_file) < 0) return -1; if (wt.pcapng_file && write_pcapng_init(&wt, wt.pcapng_file) < 0) return -1; if (read_wired_file && read_wired_cap_file(&wt, read_wired_file) < 0) return -1; if (read_file && read_cap_file(&wt, read_file) < 0) return -1; if (ifname && monitor_init(&wt, ifname) < 0) return -1; if (ifname_wired && monitor_init_wired(&wt, ifname_wired) < 0) return -1; if (ctrl_iface && ctrl_init(&wt) < 0) return -1; eloop_register_signal_terminate(wlantest_terminate, &wt); eloop_run(); wpa_printf(MSG_INFO, "Processed: rx_mgmt=%u rx_ctrl=%u rx_data=%u " "fcs_error=%u", wt.rx_mgmt, wt.rx_ctrl, wt.rx_data, wt.fcs_error); wlantest_deinit(&wt); wpa_debug_close_file(); eloop_destroy(); os_program_deinit(); return 0; }