📄 hostapd.c
字号:
}static int hostapd_wpa_auth_set_key(void *ctx, const char *alg, const u8 *addr, int idx, u8 *key, size_t key_len){ struct hostapd_data *hapd = ctx; return hostapd_set_encryption(hapd->conf->iface, hapd, alg, addr, idx, key, key_len, 1);}static int hostapd_wpa_auth_get_seqnum(void *ctx, const u8 *addr, int idx, u8 *seq){ struct hostapd_data *hapd = ctx; return hostapd_get_seqnum(hapd->conf->iface, hapd, addr, idx, seq);}static int hostapd_wpa_auth_send_eapol(void *ctx, const u8 *addr, const u8 *data, size_t data_len, int encrypt){ struct hostapd_data *hapd = ctx; return hostapd_send_eapol(hapd, addr, data, data_len, encrypt);}static int hostapd_wpa_auth_for_each_sta( void *ctx, int (*cb)(struct wpa_state_machine *sm, void *ctx), void *cb_ctx){ struct hostapd_data *hapd = ctx; struct sta_info *sta; for (sta = hapd->sta_list; sta; sta = sta->next) { if (sta->wpa_sm && cb(sta->wpa_sm, cb_ctx)) return 1; } return 0;}static int hostapd_setup_interface(struct hostapd_iface *iface){ struct hostapd_data *hapd = iface->bss[0]; struct hostapd_bss_config *conf = hapd->conf; u8 ssid[HOSTAPD_MAX_SSID_LEN + 1]; int ssid_len, set_ssid, freq; 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.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.ssid_len != ssid_len || memcmp(conf->ssid.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.ssid_len = ssid_len; memcpy(conf->ssid.ssid, ssid, conf->ssid.ssid_len); conf->ssid.ssid[conf->ssid.ssid_len] = '\0'; } printf("Using interface %s with hwaddr " MACSTR " and ssid '%s'\n", hapd->conf->iface, MAC2STR(hapd->own_addr), hapd->conf->ssid.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.ssid, conf->ssid.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) { struct wpa_auth_config conf; struct wpa_auth_callbacks cb; const u8 *wpa_ie; size_t wpa_ie_len; hostapd_wpa_auth_conf(hapd->conf, &conf); memset(&cb, 0, sizeof(cb)); cb.ctx = hapd; cb.logger = hostapd_wpa_auth_logger; cb.disconnect = hostapd_wpa_auth_disconnect; cb.mic_failure_report = hostapd_wpa_auth_mic_failure_report; cb.set_eapol = hostapd_wpa_auth_set_eapol; cb.get_eapol = hostapd_wpa_auth_get_eapol; cb.get_psk = hostapd_wpa_auth_get_psk; cb.get_pmk = hostapd_wpa_auth_get_pmk; cb.set_key = hostapd_wpa_auth_set_key; cb.get_seqnum = hostapd_wpa_auth_get_seqnum; cb.send_eapol = hostapd_wpa_auth_send_eapol; cb.for_each_sta = hostapd_wpa_auth_for_each_sta; hapd->wpa_auth = wpa_init(hapd->own_addr, &conf, &cb); if (hapd->wpa_auth == NULL) { printf("WPA initialization failed.\n"); return -1; } if (hostapd_set_privacy(hapd, 1)) { wpa_printf(MSG_ERROR, "Could not set PrivacyInvoked " "for interface %s", hapd->conf->iface); return -1; } wpa_ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &wpa_ie_len); if (hostapd_set_generic_elem(hapd, wpa_ie, wpa_ie_len)) { wpa_printf(MSG_ERROR, "Failed to configure WPA IE for " "the kernel driver."); return -1; } if (rsn_preauth_iface_init(hapd)) { printf("Initialization of RSN pre-authentication " "failed.\n"); return -1; } } 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; ieee802_11_set_beacon(hapd); if (hostapd_flush_old_stations(hapd)) return -1; if (hostapd_ctrl_iface_init(hapd)) { printf("Failed to setup control interface\n"); ret = -1; } if (hostapd_get_hw_features(iface)) { /* Not all drivers support this yet, so continue without hw * feature data. */ } else if (hostapd_select_hw_mode(iface)) { printf("Could not select hw_mode and channel.\n"); } if (hapd->iconf->channel) { freq = hostapd_hw_get_freq(hapd, hapd->iconf->channel); printf("Mode: %s Channel: %d Frequency: %d MHz\n", hostapd_hw_mode_txt(hapd->iconf->hw_mode), hapd->iconf->channel, freq); if (hostapd_set_freq(hapd, hapd->iconf->hw_mode, freq)) { printf("Could not set channel for kernel driver\n"); return -1; } } return ret;}struct driver { struct driver *next; char *name; const struct driver_ops *ops;};static struct driver *drivers = NULL;void driver_register(const char *name, const struct driver_ops *ops){ struct driver *d; d = malloc(sizeof(struct driver)); if (d == NULL) { printf("Failed to register driver %s!\n", name); return; } d->name = strdup(name); if (d->name == NULL) { printf("Failed to register driver %s!\n", name); free(d); return; } d->ops = ops; d->next = drivers; drivers = d;}void driver_unregister(const char *name){ struct driver *p, **pp; for (pp = &drivers; (p = *pp) != NULL; pp = &p->next) { if (strcasecmp(p->name, name) == 0) { *pp = p->next; p->next = NULL; free(p->name); free(p); break; } }}static void driver_unregister_all(void){ struct driver *p, *pp; p = drivers; drivers = NULL; while (p) { pp = p; p = p->next; free(pp->name); free(pp); }}const struct driver_ops * driver_lookup(const char *name){ struct driver *p; if (strcmp(name, "default") == 0) { p = drivers; while (p && p->next) p = p->next; return p->ops; } for (p = drivers; p != NULL; p = p->next) { if (strcasecmp(p->name, name) == 0) return p->ops; } return NULL;}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-2006, Jouni Malinen <jkmaline@cc.hut.fi> " "and contributors\n");}static void usage(void){ show_version(); fprintf(stderr, "\n" "usage: hostapd [-hdBKt] <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" " -K include key data in debug messages\n" " -t include timestamps in some debug messages\n" " -v show hostapd version\n"); exit(1);}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 = wpa_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)) { struct tls_connection_params params; hapd->ssl_ctx = tls_init(NULL); if (hapd->ssl_ctx == NULL) { printf("Failed to initialize TLS\n"); goto fail; } 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; if (tls_global_set_params(hapd->ssl_ctx, ¶ms)) { printf("Failed to set TLS parameters\n"); goto fail; } if (tls_global_set_verify(hapd->ssl_ctx, hapd->conf->check_crl)) { printf("Failed to enable check_crl\n"); 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) { printf("Failed to initialize EAP-SIM database " "interface\n"); goto fail; } }#endif /* EAP_SERVER */ if (hapd->conf->assoc_ap) hapd->assoc_ap_state = WAIT_BEACON; /* FIX: need to fix this const vs. not */ hapd->driver = (struct driver_ops *) hapd->iconf->driver; return hapd;#if defined(EAP_TLS_FUNCS) || defined(EAP_SERVER)fail:#endif /* TODO: cleanup allocated resources(?) */ free(hapd); return NULL;}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; int i; hapd_iface = wpa_zalloc(sizeof(*hapd_iface)); if (hapd_iface == NULL) goto fail; hapd_iface->config_fname = 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 = wpa_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; i < hapd_iface->num_bss; i++) { hapd = hapd_iface->bss[i]; if (hapd->ssl_ctx) tls_deinit(hapd->ssl_ctx); } free(hapd_iface->config_fname); free(hapd_iface); } return NULL;}/** * register_drivers - Register driver interfaces * * This function is generated by Makefile (into driver_conf.c) to call all * configured driver interfaces to register them to core hostapd. */void register_drivers(void);int main(int argc, char *argv[]){ struct hapd_interfaces interfaces; int ret = 1, i, j; int c, debug = 0, daemonize = 0; for (;;) { c = getopt(argc, argv, "BdhKtv"); 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 't': wpa_debug_timestamp++; break; case 'v': show_version(); exit(1); break; default: usage(); break; } } if (optind == argc) usage(); register_drivers(); /* NB: generated by Makefile */ if (eap_server_register_methods()) { wpa_printf(MSG_ERROR, "Failed to register EAP methods"); return -1; } interfaces.count = argc - optind; interfaces.iface = malloc(interfaces.count * sizeof(struct hostapd_iface *)); if (interfaces.iface == NULL) { printf("malloc failed\n"); exit(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); for (i = 0; i < interfaces.count; i++) { printf("Configuration file: %s\n", argv[optind + i]); interfaces.iface[i] = hostapd_init(argv[optind + i]); if (!interfaces.iface[i]) goto out; for (j = 0; j < debug; j++) { if (interfaces.iface[i]->bss[0]->conf-> logger_stdout_level > 0) interfaces.iface[i]->bss[0]->conf-> logger_stdout_level--; interfaces.iface[i]->bss[0]->conf->debug++; } if (hostapd_setup_interface(interfaces.iface[i])) goto out; } if (daemonize && os_daemonize(NULL)) { perror("daemon"); goto out; }#ifndef CONFIG_NATIVE_WINDOWS openlog("hostapd", 0, LOG_DAEMON);#endif /* CONFIG_NATIVE_WINDOWS */ eloop_run(); 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: for (i = 0; i < interfaces.count; i++) { if (!interfaces.iface[i]) continue; 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); free(hapd); } hostapd_cleanup_iface(interfaces.iface[i]); } free(interfaces.iface); eloop_destroy();#ifndef CONFIG_NATIVE_WINDOWS closelog();#endif /* CONFIG_NATIVE_WINDOWS */ eap_server_unregister_methods(); driver_unregister_all(); os_daemonize_terminate(NULL); return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -