hostapd.c

来自「hostapd无线AP工具」· C语言 代码 · 共 835 行 · 第 1/2 页

C
835
字号
/* * Host AP (software wireless LAN access point) user space daemon for * Host AP kernel driver * Copyright (c) 2002-2005, 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 <stdlib.h>#include <stdio.h>#include <unistd.h>#include <netinet/in.h>#include <string.h>#include <signal.h>#include <time.h>#include <syslog.h>#include <stdarg.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include "eloop.h"#include "hostapd.h"#include "ieee802_1x.h"#include "ieee802_11.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 "ctrl_iface.h"#include "tls.h"#include "eap_sim_db.h"#include "version.h"struct hapd_interfaces {	int count;	hostapd **hapd;};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;	va_start(ap, fmt);	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) {		vprintf(format, ap);		printf("\n");	}	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;		}		vsyslog(priority, format, ap);	}	free(format);	va_end(ap);}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(hostapd *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(hostapd *hapd, struct sta_info *sta){	/* IEEE 802.11F (IAPP) */	if (hapd->conf->ieee802_11f)		iapp_new_station(hapd->iapp, sta);	/* Start accounting here, if IEEE 802.1X is not used. IEEE 802.1X code	 * will start accounting after the station has been authorized. */	if (!hapd->conf->ieee802_1x)		accounting_sta_start(hapd, sta);	/* Start IEEE 802.1X authentication process for new stations */	ieee802_1x_new_station(hapd, sta);	wpa_new_station(hapd, sta);}static void handle_term(int sig, void *eloop_ctx, void *signal_ctx){	printf("Signal %d received - terminating\n", sig);	eloop_terminate();}static 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;	printf("Signal %d received - reloading configuration\n", sig);	for (i = 0; i < hapds->count; i++) {		hostapd *hapd = hapds->hapd[i];		newconf = hostapd_config_read(hapd->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);		hostapd_config_free(hapd->conf);		hapd->conf = newconf;	}}#ifdef HOSTAPD_DUMP_STATEstatic void hostapd_dump_state(hostapd *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 < sizeof(sta->supported_rates); i++)			if (sta->supported_rates[i] != 0)				fprintf(f, "%02x ", sta->supported_rates[i]);		fprintf(f, "%s%s%s%s\n",			(sta->tx_supp_rates & WLAN_RATE_1M ? "[1M]" : ""),			(sta->tx_supp_rates & WLAN_RATE_2M ? "[2M]" : ""),			(sta->tx_supp_rates & WLAN_RATE_5M5 ? "[5.5M]" : ""),			(sta->tx_supp_rates & WLAN_RATE_11M ? "[11M]" : ""));		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;	for (i = 0; i < hapds->count; i++) {		hostapd *hapd = hapds->hapd[i];		hostapd_dump_state(hapd);	}#endif /* HOSTAPD_DUMP_STATE */}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);	wpa_deinit(hapd);	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);	if (hapd->driver)		hostapd_driver_deinit(hapd);	hostapd_config_free(hapd->conf);	hapd->conf = NULL;	free(hapd->config_fname);#ifdef EAP_TLS_FUNCS	if (hapd->ssl_ctx) {		tls_deinit(hapd->ssl_ctx);		hapd->ssl_ctx = NULL;	}#endif /* EAP_TLS_FUNCS */	if (hapd->eap_sim_db_priv)		eap_sim_db_deinit(hapd->eap_sim_db_priv);}static int hostapd_flush_old_stations(hostapd *hapd){	int ret = 0;	printf("Flushing old station entries\n");	if (hostapd_flush(hapd)) {		printf("Could not connect to kernel driver.\n");		ret = -1;	}	printf("Deauthenticate all stations\n");	hostapd_deauth_all_stas(hapd);	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;	}

⌨️ 快捷键说明

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