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 + -
显示快捷键?