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

📄 ieee802_11.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * hostapd / IEEE 802.11 Management * 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"#ifndef CONFIG_NATIVE_WINDOWS#include <net/if.h>#include "eloop.h"#include "hostapd.h"#include "ieee802_11.h"#include "beacon.h"#include "hw_features.h"#include "radius/radius.h"#include "radius/radius_client.h"#include "ieee802_11_auth.h"#include "sta_info.h"#include "rc4.h"#include "ieee802_1x.h"#include "wpa.h"#include "wme.h"#include "ap_list.h"#include "accounting.h"#include "driver.h"#include "mlme.h"u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid){	u8 *pos = eid;	int i, num, count;	if (hapd->iface->current_rates == NULL)		return eid;	*pos++ = WLAN_EID_SUPP_RATES;	num = hapd->iface->num_rates;	if (num > 8) {		/* rest of the rates are encoded in Extended supported		 * rates element */		num = 8;	}	*pos++ = num;	count = 0;	for (i = 0, count = 0; i < hapd->iface->num_rates && count < num;	     i++) {		count++;		*pos = hapd->iface->current_rates[i].rate / 5;		if (hapd->iface->current_rates[i].flags & HOSTAPD_RATE_BASIC)			*pos |= 0x80;		pos++;	}	return pos;}u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid){	u8 *pos = eid;	int i, num, count;	if (hapd->iface->current_rates == NULL)		return eid;	num = hapd->iface->num_rates;	if (num <= 8)		return eid;	num -= 8;	*pos++ = WLAN_EID_EXT_SUPP_RATES;	*pos++ = num;	count = 0;	for (i = 0, count = 0; i < hapd->iface->num_rates && count < num + 8;	     i++) {		count++;		if (count <= 8)			continue; /* already in SuppRates IE */		*pos = hapd->iface->current_rates[i].rate / 5;		if (hapd->iface->current_rates[i].flags & HOSTAPD_RATE_BASIC)			*pos |= 0x80;		pos++;	}	return pos;}u8 * hostapd_eid_ht_capabilities_info(struct hostapd_data *hapd, u8 *eid){#ifdef CONFIG_IEEE80211N	struct ieee80211_ht_capability *cap;	u8 *pos = eid;	if (!hapd->iconf->ieee80211n)		return eid;	*pos++ = WLAN_EID_HT_CAP;	*pos++ = sizeof(*cap);	cap = (struct ieee80211_ht_capability *) pos;	os_memset(cap, 0, sizeof(*cap));	SET_2BIT_U8(&cap->mac_ht_params_info,		    MAC_HT_PARAM_INFO_MAX_RX_AMPDU_FACTOR_OFFSET,		    MAX_RX_AMPDU_FACTOR_64KB);	cap->capabilities_info = host_to_le16(hapd->iconf->ht_capab);	cap->supported_mcs_set[0] = 0xff;	cap->supported_mcs_set[1] = 0xff; 	pos += sizeof(*cap);	return pos;#else /* CONFIG_IEEE80211N */	return eid;#endif /* CONFIG_IEEE80211N */}u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid){#ifdef CONFIG_IEEE80211N	struct ieee80211_ht_operation *oper;	u8 *pos = eid;	if (!hapd->iconf->ieee80211n)		return eid;	*pos++ = WLAN_EID_HT_OPERATION;	*pos++ = sizeof(*oper);	oper = (struct ieee80211_ht_operation *) pos;	os_memset(oper, 0, sizeof(*oper));	oper->control_chan = hapd->iconf->channel;	oper->operation_mode = host_to_le16(hapd->iface->ht_op_mode);	if (hapd->iconf->secondary_channel == 1)		oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE |			HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH;	if (hapd->iconf->secondary_channel == -1)		oper->ht_param |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW |			HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH;	pos += sizeof(*oper);	return pos;#else /* CONFIG_IEEE80211N */	return eid;#endif /* CONFIG_IEEE80211N */}#ifdef CONFIG_IEEE80211N/*op_modeSet to 0 (HT pure) under the followign conditions	- all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or	- all STAs in the BSS are 20 MHz HT in 20 MHz BSSSet to 1 (HT non-member protection) if there may be non-HT STAs	in both the primary and the secondary channelSet to 2 if only HT STAs are associated in BSS,	however and at least one 20 MHz HT STA is associatedSet to 3 (HT mixed mode) when one or more non-HT STAs are associated	(currently non-GF HT station is considered as non-HT STA also)*/int hostapd_ht_operation_update(struct hostapd_iface *iface){	u16 cur_op_mode, new_op_mode;	int op_mode_changes = 0;	if (!iface->conf->ieee80211n || iface->conf->ht_op_mode_fixed)		return 0;	wpa_printf(MSG_DEBUG, "%s current operation mode=0x%X",		   __func__, iface->ht_op_mode);	if (!(iface->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT)	    && iface->num_sta_ht_no_gf) {		iface->ht_op_mode |=			HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;		op_mode_changes++;	} else if ((iface->ht_op_mode &		    HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) &&		   iface->num_sta_ht_no_gf == 0) {		iface->ht_op_mode &=			~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;		op_mode_changes++;	}	if (!(iface->ht_op_mode & HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&	    (iface->num_sta_no_ht || iface->olbc_ht)) {		iface->ht_op_mode |= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;		op_mode_changes++;	} else if ((iface->ht_op_mode &		    HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&		   (iface->num_sta_no_ht == 0 && !iface->olbc_ht)) {		iface->ht_op_mode &=			~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;		op_mode_changes++;	}	/* Note: currently we switch to the MIXED op mode if HT non-greenfield	 * station is associated. Probably it's a theoretical case, since	 * it looks like all known HT STAs support greenfield.	 */	new_op_mode = 0;	if (iface->num_sta_no_ht ||	    (iface->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT))		new_op_mode = OP_MODE_MIXED;	else if ((iface->conf->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)		 && iface->num_sta_ht_20mhz)		new_op_mode = OP_MODE_20MHZ_HT_STA_ASSOCED;	else if (iface->olbc_ht)		new_op_mode = OP_MODE_MAY_BE_LEGACY_STAS;	else		new_op_mode = OP_MODE_PURE;	cur_op_mode = iface->ht_op_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK;	if (cur_op_mode != new_op_mode) {		iface->ht_op_mode &= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK;		iface->ht_op_mode |= new_op_mode;		op_mode_changes++;	}	wpa_printf(MSG_DEBUG, "%s new operation mode=0x%X changes=%d",		   __func__, iface->ht_op_mode, op_mode_changes);	return op_mode_changes;}#endif /* CONFIG_IEEE80211N */u16 hostapd_own_capab_info(struct hostapd_data *hapd, struct sta_info *sta,			   int probe){	int capab = WLAN_CAPABILITY_ESS;	int privacy;	if (hapd->iface->num_sta_no_short_preamble == 0 &&	    hapd->iconf->preamble == SHORT_PREAMBLE)		capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;	privacy = hapd->conf->ssid.wep.keys_set;	if (hapd->conf->ieee802_1x &&	    (hapd->conf->default_wep_key_len ||	     hapd->conf->individual_wep_key_len))		privacy = 1;	if (hapd->conf->wpa)		privacy = 1;	if (sta) {		int policy, def_klen;		if (probe && sta->ssid_probe) {			policy = sta->ssid_probe->security_policy;			def_klen = sta->ssid_probe->wep.default_len;		} else {			policy = sta->ssid->security_policy;			def_klen = sta->ssid->wep.default_len;		}		privacy = policy != SECURITY_PLAINTEXT;		if (policy == SECURITY_IEEE_802_1X && def_klen == 0)			privacy = 0;	}	if (privacy)		capab |= WLAN_CAPABILITY_PRIVACY;	if (hapd->iface->current_mode &&	    hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G &&	    hapd->iface->num_sta_no_short_slot_time == 0)		capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;	return capab;}#ifdef CONFIG_IEEE80211Wstatic u8 * hostapd_eid_assoc_comeback_time(struct hostapd_data *hapd,					    struct sta_info *sta, u8 *eid){	u8 *pos = eid;	u32 timeout, tu;	struct os_time now, passed;	*pos++ = WLAN_EID_TIMEOUT_INTERVAL;	*pos++ = 5;	*pos++ = WLAN_TIMEOUT_ASSOC_COMEBACK;	os_get_time(&now);	os_time_sub(&now, &sta->sa_query_start, &passed);	tu = (passed.sec * 1000000 + passed.usec) / 1024;	if (hapd->conf->assoc_sa_query_max_timeout > tu)		timeout = hapd->conf->assoc_sa_query_max_timeout - tu;	else		timeout = 0;	if (timeout < hapd->conf->assoc_sa_query_max_timeout)		timeout++; /* add some extra time for local timers */	WPA_PUT_LE32(pos, timeout);	pos += 4;	return pos;}#endif /* CONFIG_IEEE80211W */void ieee802_11_print_ssid(char *buf, const u8 *ssid, u8 len){	int i;	if (len > HOSTAPD_MAX_SSID_LEN)		len = HOSTAPD_MAX_SSID_LEN;	for (i = 0; i < len; i++) {		if (ssid[i] >= 32 && ssid[i] < 127)			buf[i] = ssid[i];		else			buf[i] = '.';	}	buf[len] = '\0';}/** * ieee802_11_send_deauth - Send Deauthentication frame * @hapd: hostapd BSS data * @addr: Address of the destination STA * @reason: Reason code for Deauthentication */void ieee802_11_send_deauth(struct hostapd_data *hapd, u8 *addr, u16 reason){	struct ieee80211_mgmt mgmt;	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,		       HOSTAPD_LEVEL_DEBUG,		       "deauthenticate - reason %d", reason);	os_memset(&mgmt, 0, sizeof(mgmt));	mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,					  WLAN_FC_STYPE_DEAUTH);	os_memcpy(mgmt.da, addr, ETH_ALEN);	os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);	os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN);	mgmt.u.deauth.reason_code = host_to_le16(reason);	if (hostapd_send_mgmt_frame(hapd, &mgmt, IEEE80211_HDRLEN +				    sizeof(mgmt.u.deauth), 0) < 0)		perror("ieee802_11_send_deauth: send");}static u16 auth_shared_key(struct hostapd_data *hapd, struct sta_info *sta,			   u16 auth_transaction, u8 *challenge, int iswep){	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,		       HOSTAPD_LEVEL_DEBUG,		       "authentication (shared key, transaction %d)",		       auth_transaction);	if (auth_transaction == 1) {		if (!sta->challenge) {			/* Generate a pseudo-random challenge */			u8 key[8];			time_t now;			int r;			sta->challenge = os_zalloc(WLAN_AUTH_CHALLENGE_LEN);			if (sta->challenge == NULL)				return WLAN_STATUS_UNSPECIFIED_FAILURE;			now = time(NULL);			r = random();			os_memcpy(key, &now, 4);			os_memcpy(key + 4, &r, 4);			rc4(sta->challenge, WLAN_AUTH_CHALLENGE_LEN,			    key, sizeof(key));		}		return 0;	}	if (auth_transaction != 3)		return WLAN_STATUS_UNSPECIFIED_FAILURE;	/* Transaction 3 */	if (!iswep || !sta->challenge || !challenge ||	    os_memcmp(sta->challenge, challenge, WLAN_AUTH_CHALLENGE_LEN)) {		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,			       HOSTAPD_LEVEL_INFO,			       "shared key authentication - invalid "			       "challenge-response");		return WLAN_STATUS_CHALLENGE_FAIL;	}	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,		       HOSTAPD_LEVEL_DEBUG,		       "authentication OK (shared key)");#ifdef IEEE80211_REQUIRE_AUTH_ACK	/* Station will be marked authenticated if it ACKs the	 * authentication reply. */#else	sta->flags |= WLAN_STA_AUTH;	wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);#endif	os_free(sta->challenge);	sta->challenge = NULL;	return 0;}static void send_auth_reply(struct hostapd_data *hapd,			    const u8 *dst, const u8 *bssid,			    u16 auth_alg, u16 auth_transaction, u16 resp,			    const u8 *ies, size_t ies_len){	struct ieee80211_mgmt *reply;	u8 *buf;	size_t rlen;	rlen = IEEE80211_HDRLEN + sizeof(reply->u.auth) + ies_len;	buf = os_zalloc(rlen);	if (buf == NULL)		return;	reply = (struct ieee80211_mgmt *) buf;	reply->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,					    WLAN_FC_STYPE_AUTH);	os_memcpy(reply->da, dst, ETH_ALEN);	os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN);	os_memcpy(reply->bssid, bssid, ETH_ALEN);	reply->u.auth.auth_alg = host_to_le16(auth_alg);	reply->u.auth.auth_transaction = host_to_le16(auth_transaction);	reply->u.auth.status_code = host_to_le16(resp);	if (ies && ies_len)		os_memcpy(reply->u.auth.variable, ies, ies_len);	wpa_printf(MSG_DEBUG, "authentication reply: STA=" MACSTR

⌨️ 快捷键说明

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