⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hostapd.c

📁 hostapd源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * hostapd / Initialization and configuration * Copyright (c) 2002-2006, Jouni Malinen <jkmaline@cc.hut.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Alternatively, this software may be distributed under the terms of BSD * license. * * See README and COPYING for more details. */#include "includes.h"#ifndef CONFIG_NATIVE_WINDOWS#include <syslog.h>#endif /* CONFIG_NATIVE_WINDOWS */#include "eloop.h"#include "hostapd.h"#include "ieee802_1x.h"#include "ieee802_11.h"#include "beacon.h"#include "hw_features.h"#include "accounting.h"#include "eapol_sm.h"#include "iapp.h"#include "ap.h"#include "ieee802_11_auth.h"#include "sta_info.h"#include "driver.h"#include "radius_client.h"#include "radius_server.h"#include "wpa.h"#include "preauth.h"#include "ctrl_iface.h"#include "tls.h"#include "eap_sim_db.h"#include "eap.h"#include "version.h"#ifndef CONFIG_NATIVE_WINDOWS#include "hostap_common.h"#else /* CONFIG_NATIVE_WINDOWS */#define WLAN_REASON_MICHAEL_MIC_FAILURE 14#endif /* CONFIG_NATIVE_WINDOWS */struct hapd_interfaces {	int count;	struct hostapd_iface **iface;};unsigned char rfc1042_header[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };extern int wpa_debug_level;extern int wpa_debug_show_keys;extern int wpa_debug_timestamp;void hostapd_logger(struct hostapd_data *hapd, const u8 *addr,		    unsigned int module, int level, const char *fmt, ...){	char *format, *module_str;	int maxlen;	va_list ap;	int conf_syslog_level, conf_stdout_level;	unsigned int conf_syslog, conf_stdout;	maxlen = strlen(fmt) + 100;	format = malloc(maxlen);	if (!format)		return;	if (hapd && hapd->conf) {		conf_syslog_level = hapd->conf->logger_syslog_level;		conf_stdout_level = hapd->conf->logger_stdout_level;		conf_syslog = hapd->conf->logger_syslog;		conf_stdout = hapd->conf->logger_stdout;	} else {		conf_syslog_level = conf_stdout_level = 0;		conf_syslog = conf_stdout = (unsigned int) -1;	}	switch (module) {	case HOSTAPD_MODULE_IEEE80211:		module_str = "IEEE 802.11";		break;	case HOSTAPD_MODULE_IEEE8021X:		module_str = "IEEE 802.1X";		break;	case HOSTAPD_MODULE_RADIUS:		module_str = "RADIUS";		break;	case HOSTAPD_MODULE_WPA:		module_str = "WPA";		break;	case HOSTAPD_MODULE_DRIVER:		module_str = "DRIVER";		break;	case HOSTAPD_MODULE_IAPP:		module_str = "IAPP";		break;	default:		module_str = NULL;		break;	}	if (hapd && hapd->conf && addr)		snprintf(format, maxlen, "%s: STA " MACSTR "%s%s: %s",			 hapd->conf->iface, MAC2STR(addr),			 module_str ? " " : "", module_str, fmt);	else if (hapd && hapd->conf)		snprintf(format, maxlen, "%s:%s%s %s",			 hapd->conf->iface, module_str ? " " : "",			 module_str, fmt);	else if (addr)		snprintf(format, maxlen, "STA " MACSTR "%s%s: %s",			 MAC2STR(addr), module_str ? " " : "",			 module_str, fmt);	else		snprintf(format, maxlen, "%s%s%s",			 module_str, module_str ? ": " : "", fmt);	if ((conf_stdout & module) && level >= conf_stdout_level) {		wpa_debug_print_timestamp();		va_start(ap, fmt);		vprintf(format, ap);		va_end(ap);		printf("\n");	}#ifndef CONFIG_NATIVE_WINDOWS	if ((conf_syslog & module) && level >= conf_syslog_level) {		int priority;		switch (level) {		case HOSTAPD_LEVEL_DEBUG_VERBOSE:		case HOSTAPD_LEVEL_DEBUG:			priority = LOG_DEBUG;			break;		case HOSTAPD_LEVEL_INFO:			priority = LOG_INFO;			break;		case HOSTAPD_LEVEL_NOTICE:			priority = LOG_NOTICE;			break;		case HOSTAPD_LEVEL_WARNING:			priority = LOG_WARNING;			break;		default:			priority = LOG_INFO;			break;		}		va_start(ap, fmt);		vsyslog(priority, format, ap);		va_end(ap);	}#endif /* CONFIG_NATIVE_WINDOWS */	free(format);}const char * hostapd_ip_txt(const struct hostapd_ip_addr *addr, char *buf,			    size_t buflen){	if (buflen == 0 || addr == NULL)		return NULL;	if (addr->af == AF_INET) {		snprintf(buf, buflen, "%s", inet_ntoa(addr->u.v4));	} else {		buf[0] = '\0';	}#ifdef CONFIG_IPV6	if (addr->af == AF_INET6) {		if (inet_ntop(AF_INET6, &addr->u.v6, buf, buflen) == NULL)			buf[0] = '\0';	}#endif /* CONFIG_IPV6 */	return buf;}static void hostapd_deauth_all_stas(struct hostapd_data *hapd){#if 0	u8 addr[ETH_ALEN];	memset(addr, 0xff, ETH_ALEN);	hostapd_sta_deauth(hapd, addr, WLAN_REASON_PREV_AUTH_NOT_VALID);#else	/* New Prism2.5/3 STA firmware versions seem to have issues with this	 * broadcast deauth frame. This gets the firmware in odd state where	 * nothing works correctly, so let's skip sending this for a while	 * until the issue has been resolved. */#endif}/* This function will be called whenever a station associates with the AP */void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,			   int reassoc){	if (hapd->tkip_countermeasures) {		hostapd_sta_deauth(hapd, sta->addr,				   WLAN_REASON_MICHAEL_MIC_FAILURE);		return;	}	/* IEEE 802.11F (IAPP) */	if (hapd->conf->ieee802_11f)		iapp_new_station(hapd->iapp, sta);	/* Start accounting here, if IEEE 802.1X and WPA are not used.	 * IEEE 802.1X/WPA code will start accounting after the station has	 * been authorized. */	if (!hapd->conf->ieee802_1x && !hapd->conf->wpa)		accounting_sta_start(hapd, sta);	/* Start IEEE 802.1X authentication process for new stations */	ieee802_1x_new_station(hapd, sta);	if (reassoc)		wpa_auth_sm_event(sta->wpa_sm, WPA_REAUTH);	else		wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm);}#ifdef EAP_SERVERstatic int hostapd_sim_db_cb_sta(struct hostapd_data *hapd,				 struct sta_info *sta, void *ctx){	if (eapol_sm_eap_pending_cb(sta->eapol_sm, ctx) == 0)		return 1;	return 0;}static void hostapd_sim_db_cb(void *ctx, void *session_ctx){	struct hostapd_data *hapd = ctx;	if (ap_for_each_sta(hapd, hostapd_sim_db_cb_sta, session_ctx) == 0)		radius_server_eap_pending_cb(hapd->radius_srv, session_ctx);}#endif /* EAP_SERVER */static void handle_term(int sig, void *eloop_ctx, void *signal_ctx){	printf("Signal %d received - terminating\n", sig);	eloop_terminate();}static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,				  struct wpa_auth_config *wconf){	wconf->wpa = conf->wpa;	wconf->wpa_key_mgmt = conf->wpa_key_mgmt;	wconf->wpa_pairwise = conf->wpa_pairwise;	wconf->wpa_group = conf->wpa_group;	wconf->wpa_group_rekey = conf->wpa_group_rekey;	wconf->wpa_strict_rekey = conf->wpa_strict_rekey;	wconf->wpa_gmk_rekey = conf->wpa_gmk_rekey;	wconf->rsn_preauth = conf->rsn_preauth;	wconf->stakey = conf->stakey;	wconf->eapol_version = conf->eapol_version;}#ifndef CONFIG_NATIVE_WINDOWSstatic void handle_reload(int sig, void *eloop_ctx, void *signal_ctx){	struct hapd_interfaces *hapds = (struct hapd_interfaces *) eloop_ctx;	struct hostapd_config *newconf;	int i;	struct wpa_auth_config wpa_auth_conf;	printf("Signal %d received - reloading configuration\n", sig);	for (i = 0; i < hapds->count; i++) {		struct hostapd_data *hapd = hapds->iface[i]->bss[0];		newconf = hostapd_config_read(hapds->iface[i]->config_fname);		if (newconf == NULL) {			printf("Failed to read new configuration file - "			       "continuing with old.\n");			continue;		}		/* TODO: update dynamic data based on changed configuration		 * items (e.g., open/close sockets, remove stations added to		 * deny list, etc.) */		radius_client_flush(hapd->radius, 0);		hostapd_config_free(hapd->iconf);		hostapd_wpa_auth_conf(&newconf->bss[0], &wpa_auth_conf);		wpa_reconfig(hapd->wpa_auth, &wpa_auth_conf);		hapd->iconf = newconf;		hapd->conf = &newconf->bss[0];		hapds->iface[i]->conf = newconf;	}}#ifdef HOSTAPD_DUMP_STATEstatic void hostapd_dump_state(struct hostapd_data *hapd){	FILE *f;	time_t now;	struct sta_info *sta;	int i;	char *buf;	if (!hapd->conf->dump_log_name) {		printf("Dump file not defined - ignoring dump request\n");		return;	}	printf("Dumping hostapd state to '%s'\n", hapd->conf->dump_log_name);	f = fopen(hapd->conf->dump_log_name, "w");	if (f == NULL) {		printf("Could not open dump file '%s' for writing.\n",		       hapd->conf->dump_log_name);		return;	}	time(&now);	fprintf(f, "hostapd state dump - %s", ctime(&now));	for (sta = hapd->sta_list; sta != NULL; sta = sta->next) {		fprintf(f, "\nSTA=" MACSTR "\n", MAC2STR(sta->addr));		fprintf(f,			"  AID=%d flags=0x%x %s%s%s%s%s%s\n"			"  capability=0x%x listen_interval=%d\n",			sta->aid,			sta->flags,			(sta->flags & WLAN_STA_AUTH ? "[AUTH]" : ""),			(sta->flags & WLAN_STA_ASSOC ? "[ASSOC]" : ""),			(sta->flags & WLAN_STA_PS ? "[PS]" : ""),			(sta->flags & WLAN_STA_TIM ? "[TIM]" : ""),			(sta->flags & WLAN_STA_PERM ? "[PERM]" : ""),			(sta->flags & WLAN_STA_AUTHORIZED ? "[AUTHORIZED]" :			 ""),			sta->capability,			sta->listen_interval);		fprintf(f, "  supported_rates=");		for (i = 0; i < sta->supported_rates_len; i++)			fprintf(f, "%02x ", sta->supported_rates[i]);		fprintf(f, "\n");		fprintf(f,			"  timeout_next=%s\n",			(sta->timeout_next == STA_NULLFUNC ? "NULLFUNC POLL" :			 (sta->timeout_next == STA_DISASSOC ? "DISASSOC" :			  "DEAUTH")));		ieee802_1x_dump_state(f, "  ", sta);	}	buf = malloc(4096);	if (buf) {		int count = radius_client_get_mib(hapd->radius, buf, 4096);		if (count < 0)			count = 0;		else if (count > 4095)			count = 4095;		buf[count] = '\0';		fprintf(f, "%s", buf);		count = radius_server_get_mib(hapd->radius_srv, buf, 4096);		if (count < 0)			count = 0;		else if (count > 4095)			count = 4095;		buf[count] = '\0';		fprintf(f, "%s", buf);		free(buf);	}	fclose(f);}#endif /* HOSTAPD_DUMP_STATE */static void handle_dump_state(int sig, void *eloop_ctx, void *signal_ctx){#ifdef HOSTAPD_DUMP_STATE	struct hapd_interfaces *hapds = (struct hapd_interfaces *) eloop_ctx;	int i, j;	for (i = 0; i < hapds->count; i++) {		struct hostapd_iface *hapd_iface = hapds->iface[i];		for (j = 0; j < hapd_iface->num_bss; j++)			hostapd_dump_state(hapd_iface->bss[j]);	}#endif /* HOSTAPD_DUMP_STATE */}#endif /* CONFIG_NATIVE_WINDOWS */static void hostapd_cleanup(struct hostapd_data *hapd){	hostapd_ctrl_iface_deinit(hapd);	free(hapd->default_wep_key);	hapd->default_wep_key = NULL;	iapp_deinit(hapd->iapp);	accounting_deinit(hapd);	rsn_preauth_iface_deinit(hapd);	if (hapd->wpa_auth) {		wpa_deinit(hapd->wpa_auth);		hapd->wpa_auth = NULL;		if (hostapd_set_privacy(hapd, 0)) {			wpa_printf(MSG_DEBUG, "Could not disable "				   "PrivacyInvoked for interface %s",				   hapd->conf->iface);		}		if (hostapd_set_generic_elem(hapd, (u8 *) "", 0)) {			wpa_printf(MSG_DEBUG, "Could not remove generic "				   "information element from interface %s",				   hapd->conf->iface);		}	}	ieee802_1x_deinit(hapd);	hostapd_acl_deinit(hapd);	radius_client_deinit(hapd->radius);	hapd->radius = NULL;	radius_server_deinit(hapd->radius_srv);	hapd->radius_srv = NULL;	hostapd_wireless_event_deinit(hapd);#ifdef EAP_TLS_FUNCS	if (hapd->ssl_ctx) {		tls_deinit(hapd->ssl_ctx);		hapd->ssl_ctx = NULL;	}#endif /* EAP_TLS_FUNCS */#ifdef EAP_SERVER	if (hapd->eap_sim_db_priv)		eap_sim_db_deinit(hapd->eap_sim_db_priv);#endif /* EAP_SERVER */}static void hostapd_cleanup_iface(struct hostapd_iface *iface){	hostapd_free_hw_features(iface->hw_features, iface->num_hw_features);	free(iface->current_rates);	hostapd_config_free(iface->conf);	free(iface->config_fname);	free(iface->bss);	free(iface);}static int hostapd_flush_old_stations(struct hostapd_data *hapd){	int ret = 0;	wpa_printf(MSG_DEBUG, "Flushing old station entries");	if (hostapd_flush(hapd)) {		printf("Could not connect to kernel driver.\n");		ret = -1;	}	wpa_printf(MSG_DEBUG, "Deauthenticate all stations");	hostapd_deauth_all_stas(hapd);	return ret;}static void hostapd_wpa_auth_logger(void *ctx, const u8 *addr,				    logger_level level, const char *txt){	struct hostapd_data *hapd = ctx;	int hlevel;	switch (level) {	case LOGGER_WARNING:		hlevel = HOSTAPD_LEVEL_WARNING;		break;	case LOGGER_INFO:		hlevel = HOSTAPD_LEVEL_INFO;		break;	case LOGGER_DEBUG:	default:		hlevel = HOSTAPD_LEVEL_DEBUG;		break;	}	hostapd_logger(hapd, addr, HOSTAPD_MODULE_WPA, hlevel, "%s", txt);}static void hostapd_wpa_auth_disconnect(void *ctx, const u8 *addr,					u16 reason){	struct hostapd_data *hapd = ctx;	struct sta_info *sta;	wpa_printf(MSG_DEBUG, "%s: WPA authenticator requests disconnect: "		   "STA " MACSTR " reason %d",		   __func__, MAC2STR(addr), reason);	sta = ap_get_sta(hapd, addr);	hostapd_sta_deauth(hapd, addr, reason);	if (sta == NULL)		return;	sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_AUTHORIZED);	eloop_cancel_timeout(ap_handle_timer, hapd, sta);	eloop_register_timeout(0, 0, ap_handle_timer, hapd, sta);	sta->timeout_next = STA_REMOVE;}static void hostapd_wpa_auth_mic_failure_report(void *ctx, const u8 *addr){	struct hostapd_data *hapd = ctx;	ieee80211_michael_mic_failure(hapd, addr, 0);}static void hostapd_wpa_auth_set_eapol(void *ctx, const u8 *addr,				       wpa_eapol_variable var, int value){	struct hostapd_data *hapd = ctx;	struct sta_info *sta = ap_get_sta(hapd, addr);	if (sta == NULL)		return;	switch (var) {	case WPA_EAPOL_portEnabled:		ieee802_1x_notify_port_enabled(sta->eapol_sm, value);		break;	case WPA_EAPOL_portValid:		ieee802_1x_notify_port_valid(sta->eapol_sm, value);		break;	case WPA_EAPOL_authorized:		ieee802_1x_set_sta_authorized(hapd, sta, value);		break;	case WPA_EAPOL_portControl_Auto:		if (sta->eapol_sm)			sta->eapol_sm->portControl = Auto;		break;	case WPA_EAPOL_keyRun:		if (sta->eapol_sm)			sta->eapol_sm->keyRun = value ? TRUE : FALSE;		break;	case WPA_EAPOL_keyAvailable:		if (sta->eapol_sm)			sta->eapol_sm->keyAvailable = value ? TRUE : FALSE;		break;	case WPA_EAPOL_keyDone:		if (sta->eapol_sm)			sta->eapol_sm->keyDone = value ? TRUE : FALSE;		break;	case WPA_EAPOL_inc_EapolFramesTx:		if (sta->eapol_sm)			sta->eapol_sm->dot1xAuthEapolFramesTx++;		break;	}}static int hostapd_wpa_auth_get_eapol(void *ctx, const u8 *addr,				      wpa_eapol_variable var){	struct hostapd_data *hapd = ctx;	struct sta_info *sta = ap_get_sta(hapd, addr);	if (sta == NULL || sta->eapol_sm == NULL)		return -1;	switch (var) {	case WPA_EAPOL_keyRun:		return sta->eapol_sm->keyRun;	case WPA_EAPOL_keyAvailable:		return sta->eapol_sm->keyAvailable;	default:		return -1;	}}static const u8 * hostapd_wpa_auth_get_psk(void *ctx, const u8 *addr,					   const u8 *prev_psk){	struct hostapd_data *hapd = ctx;	return hostapd_get_psk(hapd->conf, addr, prev_psk);}static int hostapd_wpa_auth_get_pmk(void *ctx, const u8 *addr, u8 *pmk,				    size_t *len){	struct hostapd_data *hapd = ctx;	u8 *key;	size_t keylen;	struct sta_info *sta;	sta = ap_get_sta(hapd, addr);	if (sta == NULL)		return -1;	key = ieee802_1x_get_key_crypt(sta->eapol_sm, &keylen);	if (key == NULL)		return -1;	if (keylen > *len)		keylen = WPA_PMK_LEN;	memcpy(pmk, key, keylen);	*len = keylen;	return 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -