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

📄 sta_info.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * hostapd / Station table * Copyright (c) 2002-2008, Jouni Malinen <j@w1.fi> * Copyright (c) 2007-2008, Intel Corporation * * 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"#include "hostapd.h"#include "sta_info.h"#include "eloop.h"#include "accounting.h"#include "ieee802_1x.h"#include "ieee802_11.h"#include "radius/radius.h"#include "wpa.h"#include "preauth.h"#include "radius/radius_client.h"#include "driver.h"#include "beacon.h"#include "hw_features.h"#include "mlme.h"#include "vlan_init.h"static int ap_sta_in_other_bss(struct hostapd_data *hapd,			       struct sta_info *sta, u32 flags);static void ap_handle_session_timer(void *eloop_ctx, void *timeout_ctx);#ifdef CONFIG_IEEE80211Wstatic void ap_sa_query_timer(void *eloop_ctx, void *timeout_ctx);#endif /* CONFIG_IEEE80211W */int ap_for_each_sta(struct hostapd_data *hapd,		    int (*cb)(struct hostapd_data *hapd, struct sta_info *sta,			      void *ctx),		    void *ctx){	struct sta_info *sta;	for (sta = hapd->sta_list; sta; sta = sta->next) {		if (cb(hapd, sta, ctx))			return 1;	}	return 0;}struct sta_info * ap_get_sta(struct hostapd_data *hapd, const u8 *sta){	struct sta_info *s;	s = hapd->sta_hash[STA_HASH(sta)];	while (s != NULL && os_memcmp(s->addr, sta, 6) != 0)		s = s->hnext;	return s;}static void ap_sta_list_del(struct hostapd_data *hapd, struct sta_info *sta){	struct sta_info *tmp;	if (hapd->sta_list == sta) {		hapd->sta_list = sta->next;		return;	}	tmp = hapd->sta_list;	while (tmp != NULL && tmp->next != sta)		tmp = tmp->next;	if (tmp == NULL) {		wpa_printf(MSG_DEBUG, "Could not remove STA " MACSTR " from "			   "list.", MAC2STR(sta->addr));	} else		tmp->next = sta->next;}void ap_sta_hash_add(struct hostapd_data *hapd, struct sta_info *sta){	sta->hnext = hapd->sta_hash[STA_HASH(sta->addr)];	hapd->sta_hash[STA_HASH(sta->addr)] = sta;}static void ap_sta_hash_del(struct hostapd_data *hapd, struct sta_info *sta){	struct sta_info *s;	s = hapd->sta_hash[STA_HASH(sta->addr)];	if (s == NULL) return;	if (os_memcmp(s->addr, sta->addr, 6) == 0) {		hapd->sta_hash[STA_HASH(sta->addr)] = s->hnext;		return;	}	while (s->hnext != NULL &&	       os_memcmp(s->hnext->addr, sta->addr, ETH_ALEN) != 0)		s = s->hnext;	if (s->hnext != NULL)		s->hnext = s->hnext->hnext;	else		wpa_printf(MSG_DEBUG, "AP: could not remove STA " MACSTR			   " from hash table", MAC2STR(sta->addr));}void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta){	int set_beacon = 0;	accounting_sta_stop(hapd, sta);	if (!ap_sta_in_other_bss(hapd, sta, WLAN_STA_ASSOC) &&	    !(sta->flags & WLAN_STA_PREAUTH))		hostapd_sta_remove(hapd, sta->addr);	ap_sta_hash_del(hapd, sta);	ap_sta_list_del(hapd, sta);	if (sta->aid > 0)		hapd->sta_aid[sta->aid - 1] = NULL;	hapd->num_sta--;	if (sta->nonerp_set) {		sta->nonerp_set = 0;		hapd->iface->num_sta_non_erp--;		if (hapd->iface->num_sta_non_erp == 0)			set_beacon++;	}	if (sta->no_short_slot_time_set) {		sta->no_short_slot_time_set = 0;		hapd->iface->num_sta_no_short_slot_time--;		if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G		    && hapd->iface->num_sta_no_short_slot_time == 0)			set_beacon++;	}	if (sta->no_short_preamble_set) {		sta->no_short_preamble_set = 0;		hapd->iface->num_sta_no_short_preamble--;		if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G		    && hapd->iface->num_sta_no_short_preamble == 0)			set_beacon++;	}#ifdef CONFIG_IEEE80211N	if (sta->no_ht_gf_set) {		sta->no_ht_gf_set = 0;		hapd->iface->num_sta_ht_no_gf--;	}	if (sta->no_ht_set) {		sta->no_ht_set = 0;		hapd->iface->num_sta_no_ht--;	}	if (sta->ht_20mhz_set) {		sta->ht_20mhz_set = 0;		hapd->iface->num_sta_ht_20mhz--;	}	if (hostapd_ht_operation_update(hapd->iface) > 0)		set_beacon++;#endif /* CONFIG_IEEE80211N */	if (set_beacon)		ieee802_11_set_beacons(hapd->iface);	eloop_cancel_timeout(ap_handle_timer, hapd, sta);	eloop_cancel_timeout(ap_handle_session_timer, hapd, sta);	ieee802_1x_free_station(sta);	wpa_auth_sta_deinit(sta->wpa_sm);	rsn_preauth_free_station(hapd, sta);	radius_client_flush_auth(hapd->radius, sta->addr);	os_free(sta->last_assoc_req);	os_free(sta->challenge);#ifdef CONFIG_IEEE80211W	os_free(sta->sa_query_trans_id);	eloop_cancel_timeout(ap_sa_query_timer, hapd, sta);#endif /* CONFIG_IEEE80211W */	wpabuf_free(sta->wps_ie);	os_free(sta);}void hostapd_free_stas(struct hostapd_data *hapd){	struct sta_info *sta, *prev;	sta = hapd->sta_list;	while (sta) {		prev = sta;		if (sta->flags & WLAN_STA_AUTH) {			mlme_deauthenticate_indication(				hapd, sta, WLAN_REASON_UNSPECIFIED);		}		sta = sta->next;		wpa_printf(MSG_DEBUG, "Removing station " MACSTR,			   MAC2STR(prev->addr));		ap_free_sta(hapd, prev);	}}/** * ap_handle_timer - Per STA timer handler * @eloop_ctx: struct hostapd_data * * @timeout_ctx: struct sta_info * * * This function is called to check station activity and to remove inactive * stations. */void ap_handle_timer(void *eloop_ctx, void *timeout_ctx){	struct hostapd_data *hapd = eloop_ctx;	struct sta_info *sta = timeout_ctx;	unsigned long next_time = 0;	if (sta->timeout_next == STA_REMOVE) {		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,			       HOSTAPD_LEVEL_INFO, "deauthenticated due to "			       "local deauth request");		ap_free_sta(hapd, sta);		return;	}	if ((sta->flags & WLAN_STA_ASSOC) &&	    (sta->timeout_next == STA_NULLFUNC ||	     sta->timeout_next == STA_DISASSOC)) {		int inactive_sec;		wpa_printf(MSG_DEBUG, "Checking STA " MACSTR " inactivity:",			   MAC2STR(sta->addr));		inactive_sec = hostapd_get_inact_sec(hapd, sta->addr);		if (inactive_sec == -1) {			wpa_printf(MSG_DEBUG, "Could not get station info "				   "from kernel driver for " MACSTR ".",				   MAC2STR(sta->addr));		} else if (inactive_sec < hapd->conf->ap_max_inactivity &&			   sta->flags & WLAN_STA_ASSOC) {			/* station activity detected; reset timeout state */			wpa_printf(MSG_DEBUG, "  Station has been active");			sta->timeout_next = STA_NULLFUNC;			next_time = hapd->conf->ap_max_inactivity -				inactive_sec;		}	}	if ((sta->flags & WLAN_STA_ASSOC) &&	    sta->timeout_next == STA_DISASSOC &&	    !(sta->flags & WLAN_STA_PENDING_POLL)) {		wpa_printf(MSG_DEBUG, "  Station has ACKed data poll");		/* data nullfunc frame poll did not produce TX errors; assume		 * station ACKed it */		sta->timeout_next = STA_NULLFUNC;		next_time = hapd->conf->ap_max_inactivity;	}	if (next_time) {		eloop_register_timeout(next_time, 0, ap_handle_timer, hapd,				       sta);		return;	}	if (sta->timeout_next == STA_NULLFUNC &&	    (sta->flags & WLAN_STA_ASSOC)) {		/* send data frame to poll STA and check whether this frame		 * is ACKed */		struct ieee80211_hdr hdr;		wpa_printf(MSG_DEBUG, "  Polling STA with data frame");		sta->flags |= WLAN_STA_PENDING_POLL;#ifndef CONFIG_NATIVE_WINDOWS		os_memset(&hdr, 0, sizeof(hdr));		if (hapd->driver &&		    os_strcmp(hapd->driver->name, "hostap") == 0) {			/*			 * WLAN_FC_STYPE_NULLFUNC would be more appropriate,			 * but it is apparently not retried so TX Exc events			 * are not received for it.			 */			hdr.frame_control =				IEEE80211_FC(WLAN_FC_TYPE_DATA,					     WLAN_FC_STYPE_DATA);		} else {			hdr.frame_control =				IEEE80211_FC(WLAN_FC_TYPE_DATA,					     WLAN_FC_STYPE_NULLFUNC);		}		hdr.frame_control |= host_to_le16(WLAN_FC_FROMDS);		os_memcpy(hdr.IEEE80211_DA_FROMDS, sta->addr, ETH_ALEN);		os_memcpy(hdr.IEEE80211_BSSID_FROMDS, hapd->own_addr,			  ETH_ALEN);		os_memcpy(hdr.IEEE80211_SA_FROMDS, hapd->own_addr, ETH_ALEN);		if (hostapd_send_mgmt_frame(hapd, &hdr, sizeof(hdr), 0) < 0)			perror("ap_handle_timer: send");#endif /* CONFIG_NATIVE_WINDOWS */	} else if (sta->timeout_next != STA_REMOVE) {		int deauth = sta->timeout_next == STA_DEAUTH;		wpa_printf(MSG_DEBUG, "Sending %s info to STA " MACSTR,			   deauth ? "deauthentication" : "disassociation",			   MAC2STR(sta->addr));		if (deauth) {			hostapd_sta_deauth(hapd, sta->addr,					   WLAN_REASON_PREV_AUTH_NOT_VALID);		} else {			hostapd_sta_disassoc(				hapd, sta->addr,				WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);		}	}	switch (sta->timeout_next) {	case STA_NULLFUNC:		sta->timeout_next = STA_DISASSOC;		eloop_register_timeout(AP_DISASSOC_DELAY, 0, ap_handle_timer,				       hapd, sta);		break;	case STA_DISASSOC:		sta->flags &= ~WLAN_STA_ASSOC;		ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);		if (!sta->acct_terminate_cause)			sta->acct_terminate_cause =				RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT;		accounting_sta_stop(hapd, sta);		ieee802_1x_free_station(sta);		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,			       HOSTAPD_LEVEL_INFO, "disassociated due to "			       "inactivity");		sta->timeout_next = STA_DEAUTH;		eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer,				       hapd, sta);		mlme_disassociate_indication(			hapd, sta, WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);		break;

⌨️ 快捷键说明

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