hostapd.c
来自「最新的Host AP 新添加了许多pcmcia 的驱动」· C语言 代码 · 共 2,028 行 · 第 1/4 页
C
2,028 行
} else { hapd->drv_priv = hostapd_driver_init(hapd); } if (hapd->drv_priv == NULL) { wpa_printf(MSG_ERROR, "%s driver initialization failed.", hapd->driver ? hapd->driver->name : "Unknown"); hapd->driver = NULL; return -1; } for (i = 0; i < iface->num_bss; i++) { iface->bss[i]->driver = hapd->driver; iface->bss[i]->drv_priv = hapd->drv_priv; } if (hostapd_validate_bssid_configuration(iface)) return -1;#ifdef CONFIG_IEEE80211N SET_2BIT_LE16(&iface->ht_op_mode, HT_INFO_OPERATION_MODE_OP_MODE_OFFSET, OP_MODE_PURE);#endif /* CONFIG_IEEE80211N */ if (hapd->iconf->country[0] && hapd->iconf->country[1]) { os_memcpy(country, hapd->iconf->country, 3); country[3] = '\0'; if (hostapd_set_country(hapd, country) < 0) { wpa_printf(MSG_ERROR, "Failed to set country code"); return -1; } } if (hapd->iconf->ieee80211d && hostapd_set_ieee80211d(hapd, 1) < 0) { wpa_printf(MSG_ERROR, "Failed to set ieee80211d (%d)", hapd->iconf->ieee80211d); return -1; } if (hapd->iconf->bridge_packets != INTERNAL_BRIDGE_DO_NOT_CONTROL && hostapd_set_internal_bridge(hapd, hapd->iconf->bridge_packets)) { wpa_printf(MSG_ERROR, "Failed to set bridge_packets for " "kernel driver"); return -1; } /* TODO: merge with hostapd_driver_init() ? */ if (hostapd_wireless_event_init(hapd) < 0) return -1; if (hostapd_get_hw_features(iface)) { /* Not all drivers support this yet, so continue without hw * feature data. */ } else { int ret = hostapd_select_hw_mode(iface); if (ret < 0) { wpa_printf(MSG_ERROR, "Could not select hw_mode and " "channel. (%d)", ret); return -1; } } hostapd_flush_old_stations(hapd); hostapd_set_privacy(hapd, 0); if (hapd->iconf->channel) { freq = hostapd_hw_get_freq(hapd, hapd->iconf->channel); wpa_printf(MSG_DEBUG, "Mode: %s Channel: %d " "Frequency: %d MHz", hostapd_hw_mode_txt(hapd->iconf->hw_mode), hapd->iconf->channel, freq); if (hostapd_set_freq(hapd, hapd->iconf->hw_mode, freq, hapd->iconf->ieee80211n, hapd->iconf->secondary_channel)) { wpa_printf(MSG_ERROR, "Could not set channel for " "kernel driver"); return -1; } } hostapd_broadcast_wep_clear(hapd); if (hostapd_setup_encryption(hapd->conf->iface, hapd)) return -1; hostapd_set_beacon_int(hapd, hapd->iconf->beacon_int); ieee802_11_set_beacon(hapd); if (hapd->iconf->rts_threshold > -1 && hostapd_set_rts(hapd, hapd->iconf->rts_threshold)) { wpa_printf(MSG_ERROR, "Could not set RTS threshold for " "kernel driver"); return -1; } if (hapd->iconf->fragm_threshold > -1 && hostapd_set_frag(hapd, hapd->iconf->fragm_threshold)) { wpa_printf(MSG_ERROR, "Could not set fragmentation threshold " "for kernel driver"); return -1; } prev_addr = hapd->own_addr; for (j = 0; j < iface->num_bss; j++) { hapd = iface->bss[j]; if (j) os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN); if (hostapd_setup_bss(hapd, j == 0)) return -1; if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0) prev_addr = hapd->own_addr; } hostapd_tx_queue_params(iface); ap_list_init(iface); if (hostapd_driver_commit(hapd) < 0) { wpa_printf(MSG_ERROR, "%s: Failed to commit driver " "configuration", __func__); return -1; } return ret;}/** * hostapd_setup_interface - Setup of an interface * @iface: Pointer to interface data. * Returns: 0 on success, -1 on failure * * Initializes the driver interface, validates the configuration, * and sets driver parameters based on the configuration. * Flushes old stations, sets the channel, encryption, * beacons, and WDS links based on the configuration. */static int hostapd_setup_interface(struct hostapd_iface *iface){ int ret; ret = setup_interface(iface); if (ret) { wpa_printf(MSG_DEBUG, "%s: Unable to setup interface.", iface->bss[0]->conf->iface); eloop_terminate(); return -1; } else if (!hostapd_drv_none(iface->bss[0])) { wpa_printf(MSG_DEBUG, "%s: Setup of interface done.", iface->bss[0]->conf->iface); } return 0;}static void show_version(void){ fprintf(stderr, "hostapd v" VERSION_STR "\n" "User space daemon for IEEE 802.11 AP management,\n" "IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator\n" "Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi> " "and contributors\n");}static void usage(void){ show_version(); fprintf(stderr, "\n" "usage: hostapd [-hdBKtv] [-P <PID file>] " "<configuration file(s)>\n" "\n" "options:\n" " -h show this usage\n" " -d show more debug messages (-dd for even more)\n" " -B run daemon in the background\n" " -P PID file\n" " -K include key data in debug messages\n" " -t include timestamps in some debug messages\n" " -v show hostapd version\n"); exit(1);}/** * hostapd_alloc_bss_data - Allocate and initialize per-BSS data * @hapd_iface: Pointer to interface data * @conf: Pointer to per-interface configuration * @bss: Pointer to per-BSS configuration for this BSS * Returns: Pointer to allocated BSS data * * This function is used to allocate per-BSS data structure. This data will be * freed after hostapd_cleanup() is called for it during interface * deinitialization. */static struct hostapd_data *hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface, struct hostapd_config *conf, struct hostapd_bss_config *bss){ struct hostapd_data *hapd; hapd = os_zalloc(sizeof(*hapd)); if (hapd == NULL) return NULL; hapd->iconf = conf; hapd->conf = bss; hapd->iface = hapd_iface; if (hapd->conf->individual_wep_key_len > 0) { /* use key0 in individual key and key1 in broadcast key */ hapd->default_wep_key_idx = 1; }#ifdef EAP_TLS_FUNCS if (hapd->conf->eap_server && (hapd->conf->ca_cert || hapd->conf->server_cert || hapd->conf->dh_file)) { struct tls_connection_params params; hapd->ssl_ctx = tls_init(NULL); if (hapd->ssl_ctx == NULL) { wpa_printf(MSG_ERROR, "Failed to initialize TLS"); goto fail; } os_memset(¶ms, 0, sizeof(params)); params.ca_cert = hapd->conf->ca_cert; params.client_cert = hapd->conf->server_cert; params.private_key = hapd->conf->private_key; params.private_key_passwd = hapd->conf->private_key_passwd; params.dh_file = hapd->conf->dh_file; if (tls_global_set_params(hapd->ssl_ctx, ¶ms)) { wpa_printf(MSG_ERROR, "Failed to set TLS parameters"); goto fail; } if (tls_global_set_verify(hapd->ssl_ctx, hapd->conf->check_crl)) { wpa_printf(MSG_ERROR, "Failed to enable check_crl"); goto fail; } }#endif /* EAP_TLS_FUNCS */#ifdef EAP_SERVER if (hapd->conf->eap_sim_db) { hapd->eap_sim_db_priv = eap_sim_db_init(hapd->conf->eap_sim_db, hostapd_sim_db_cb, hapd); if (hapd->eap_sim_db_priv == NULL) { wpa_printf(MSG_ERROR, "Failed to initialize EAP-SIM " "database interface"); goto fail; } }#endif /* EAP_SERVER */ hapd->driver = hapd->iconf->driver; return hapd;#if defined(EAP_TLS_FUNCS) || defined(EAP_SERVER)fail:#endif /* TODO: cleanup allocated resources(?) */ os_free(hapd); return NULL;}/** * hostapd_init - Allocate and initialize per-interface data * @config_file: Path to the configuration file * Returns: Pointer to the allocated interface data or %NULL on failure * * This function is used to allocate main data structures for per-interface * data. The allocated data buffer will be freed by calling * hostapd_cleanup_iface(). */static struct hostapd_iface * hostapd_init(const char *config_file){ struct hostapd_iface *hapd_iface = NULL; struct hostapd_config *conf = NULL; struct hostapd_data *hapd; size_t i; hapd_iface = os_zalloc(sizeof(*hapd_iface)); if (hapd_iface == NULL) goto fail; hapd_iface->config_fname = os_strdup(config_file); if (hapd_iface->config_fname == NULL) goto fail; conf = hostapd_config_read(hapd_iface->config_fname); if (conf == NULL) goto fail; hapd_iface->conf = conf; hapd_iface->num_bss = conf->num_bss; hapd_iface->bss = os_zalloc(conf->num_bss * sizeof(struct hostapd_data *)); if (hapd_iface->bss == NULL) goto fail; for (i = 0; i < conf->num_bss; i++) { hapd = hapd_iface->bss[i] = hostapd_alloc_bss_data(hapd_iface, conf, &conf->bss[i]); if (hapd == NULL) goto fail; } return hapd_iface;fail: if (conf) hostapd_config_free(conf); if (hapd_iface) { for (i = 0; hapd_iface->bss && i < hapd_iface->num_bss; i++) { hapd = hapd_iface->bss[i]; if (hapd && hapd->ssl_ctx) tls_deinit(hapd->ssl_ctx); } os_free(hapd_iface->config_fname); os_free(hapd_iface->bss); os_free(hapd_iface); } return NULL;}int main(int argc, char *argv[]){ struct hapd_interfaces interfaces; int ret = 1, k; size_t i, j; int c, debug = 0, daemonize = 0, tnc = 0; const char *pid_file = NULL; hostapd_logger_register_cb(hostapd_logger_cb); for (;;) { c = getopt(argc, argv, "BdhKP:tv"); 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 'K': wpa_debug_show_keys++; break; case 'P': pid_file = optarg; break; case 't': wpa_debug_timestamp++; break; case 'v': show_version(); exit(1); break; default: usage(); break; } } if (optind == argc) usage(); if (eap_server_register_methods()) { wpa_printf(MSG_ERROR, "Failed to register EAP methods"); return -1; } interfaces.count = argc - optind; interfaces.iface = os_malloc(interfaces.count * sizeof(struct hostapd_iface *)); if (interfaces.iface == NULL) { wpa_printf(MSG_ERROR, "malloc failed\n"); return -1; } if (eloop_init(&interfaces)) { wpa_printf(MSG_ERROR, "Failed to initialize event loop"); return -1; }#ifndef CONFIG_NATIVE_WINDOWS eloop_register_signal(SIGHUP, handle_reload, NULL); eloop_register_signal(SIGUSR1, handle_dump_state, NULL);#endif /* CONFIG_NATIVE_WINDOWS */ eloop_register_signal_terminate(handle_term, NULL); /* Initialize interfaces */ for (i = 0; i < interfaces.count; i++) { wpa_printf(MSG_ERROR, "Configuration file: %s", argv[optind + i]); interfaces.iface[i] = hostapd_init(argv[optind + i]); if (!interfaces.iface[i]) goto out; for (k = 0; k < debug; k++) { if (interfaces.iface[i]->bss[0]->conf-> logger_stdout_level > 0) interfaces.iface[i]->bss[0]->conf-> logger_stdout_level--; } ret = hostapd_setup_interface(interfaces.iface[i]); if (ret) goto out; for (k = 0; k < (int) interfaces.iface[i]->num_bss; k++) { if (interfaces.iface[i]->bss[0]->conf->tnc) tnc++; } }#ifdef EAP_TNC if (tnc && tncs_global_init() < 0) { wpa_printf(MSG_ERROR, "Failed to initialize TNCS"); goto out; }#endif /* EAP_TNC */ if (daemonize && os_daemonize(pid_file)) { perror("daemon"); goto out; }#ifndef CONFIG_NATIVE_WINDOWS openlog("hostapd", 0, LOG_DAEMON);#endif /* CONFIG_NATIVE_WINDOWS */ eloop_run(); /* Disconnect associated stations from all interfaces and BSSes */ for (i = 0; i < interfaces.count; i++) { for (j = 0; j < interfaces.iface[i]->num_bss; j++) { struct hostapd_data *hapd = interfaces.iface[i]->bss[j]; hostapd_free_stas(hapd); hostapd_flush_old_stations(hapd); } } ret = 0; out: /* Deinitialize all interfaces */ for (i = 0; i < interfaces.count; i++) { if (!interfaces.iface[i]) continue; hostapd_cleanup_iface_pre(interfaces.iface[i]); for (j = 0; j < interfaces.iface[i]->num_bss; j++) { struct hostapd_data *hapd = interfaces.iface[i]->bss[j]; hostapd_cleanup(hapd); if (j == interfaces.iface[i]->num_bss - 1 && hapd->driver) hostapd_driver_deinit(hapd); } for (j = 0; j < interfaces.iface[i]->num_bss; j++) os_free(interfaces.iface[i]->bss[j]); hostapd_cleanup_iface(interfaces.iface[i]); } os_free(interfaces.iface);#ifdef EAP_TNC tncs_global_deinit();#endif /* EAP_TNC */ eloop_destroy();#ifndef CONFIG_NATIVE_WINDOWS closelog();#endif /* CONFIG_NATIVE_WINDOWS */ eap_server_unregister_methods(); os_daemonize_terminate(pid_file); return ret;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?