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

📄 ieee802_11.c

📁 hostapd源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * hostapd / IEEE 802.11 Management * 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 "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.h"#include "radius_client.h"#include "ieee802_11_auth.h"#include "sta_info.h"#include "eapol_sm.h"#include "rc4.h"#include "ieee802_1x.h"#include "wpa.h"#include "accounting.h"#include "driver.h"#include "hostap_common.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;}u16 hostapd_own_capab_info(struct hostapd_data *hapd, struct sta_info *sta,			   int probe){	int capab = WLAN_CAPABILITY_ESS;	int privacy;	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;	return capab;}static const u8 WPA_OUI_TYPE[] = { 0x00, 0x50, 0xf2, 1 };ParseRes ieee802_11_parse_elems(struct hostapd_data *hapd, u8 *start,				size_t len,				struct ieee802_11_elems *elems,				int show_errors){	size_t left = len;	u8 *pos = start;	int unknown = 0;	memset(elems, 0, sizeof(*elems));	while (left >= 2) {		u8 id, elen;		id = *pos++;		elen = *pos++;		left -= 2;		if (elen > left) {			if (show_errors) {				HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,					      "IEEE 802.11 element parse "					      "failed (id=%d elen=%d "					      "left=%lu)\n",					      id, elen, (unsigned long) left);				wpa_hexdump(MSG_MSGDUMP, "IEs", start, len);			}			return ParseFailed;		}		switch (id) {		case WLAN_EID_SSID:			elems->ssid = pos;			elems->ssid_len = elen;			break;		case WLAN_EID_SUPP_RATES:			elems->supp_rates = pos;			elems->supp_rates_len = elen;			break;		case WLAN_EID_FH_PARAMS:			elems->fh_params = pos;			elems->fh_params_len = elen;			break;		case WLAN_EID_DS_PARAMS:			elems->ds_params = pos;			elems->ds_params_len = elen;			break;		case WLAN_EID_CF_PARAMS:			elems->cf_params = pos;			elems->cf_params_len = elen;			break;		case WLAN_EID_TIM:			elems->tim = pos;			elems->tim_len = elen;			break;		case WLAN_EID_IBSS_PARAMS:			elems->ibss_params = pos;			elems->ibss_params_len = elen;			break;		case WLAN_EID_CHALLENGE:			elems->challenge = pos;			elems->challenge_len = elen;			break;		case WLAN_EID_EXT_SUPP_RATES:			elems->ext_supp_rates = pos;			elems->ext_supp_rates_len = elen;			break;		case WLAN_EID_GENERIC:			if (elen > 4 && memcmp(pos, WPA_OUI_TYPE, 4) == 0) {				elems->wpa_ie = pos;				elems->wpa_ie_len = elen;			} else if (show_errors) {				HOSTAPD_DEBUG(HOSTAPD_DEBUG_EXCESSIVE,					      "IEEE 802.11 element parse "					      "ignored unknown generic element"					      " (id=%d elen=%d OUI:type="					      "%02x-%02x-%02x:%d)\n",					      id, elen,					      elen >= 1 ? pos[0] : 0,					      elen >= 2 ? pos[1] : 0,					      elen >= 3 ? pos[2] : 0,					      elen >= 4 ? pos[3] : 0);				unknown++;			} else {				unknown++;			}			break;		case WLAN_EID_RSN:			elems->rsn_ie = pos;			elems->rsn_ie_len = elen;			break;		default:			unknown++;			if (!show_errors)				break;			HOSTAPD_DEBUG(HOSTAPD_DEBUG_EXCESSIVE,				      "IEEE 802.11 element parse ignored "				      "unknown element (id=%d elen=%d)\n",				      id, elen);			break;		}		left -= elen;		pos += elen;	}	if (left)		return ParseFailed;	return unknown ? ParseUnknown : ParseOK;}void ieee802_11_print_ssid(const u8 *ssid, u8 len){	int i;	for (i = 0; i < len; i++) {		if (ssid[i] >= 32 && ssid[i] < 127)			printf("%c", ssid[i]);		else			printf("<%02x>", ssid[i]);	}}static void ieee802_11_sta_authenticate(void *eloop_ctx, void *timeout_ctx){	struct hostapd_data *hapd = eloop_ctx;	struct ieee80211_mgmt mgmt;	if (hapd->assoc_ap_state == WAIT_BEACON)		hapd->assoc_ap_state = AUTHENTICATE;	if (hapd->assoc_ap_state != AUTHENTICATE)		return;	printf("Authenticate with AP " MACSTR " SSID=",	       MAC2STR(hapd->conf->assoc_ap_addr));	ieee802_11_print_ssid((u8 *) hapd->assoc_ap_ssid,			      hapd->assoc_ap_ssid_len);	printf(" (as station)\n");	memset(&mgmt, 0, sizeof(mgmt));	mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,					  WLAN_FC_STYPE_AUTH);	/* Request TX callback */	mgmt.frame_control |= host_to_le16(BIT(1));	memcpy(mgmt.da, hapd->conf->assoc_ap_addr, ETH_ALEN);	memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);	memcpy(mgmt.bssid, hapd->conf->assoc_ap_addr, ETH_ALEN);	mgmt.u.auth.auth_alg = host_to_le16(WLAN_AUTH_OPEN);	mgmt.u.auth.auth_transaction = host_to_le16(1);	mgmt.u.auth.status_code = host_to_le16(0);	if (hostapd_send_mgmt_frame(hapd, &mgmt, IEEE80211_HDRLEN +				    sizeof(mgmt.u.auth), 0) < 0)		perror("ieee802_11_sta_authenticate: send");	/* Try to authenticate again, if this attempt fails or times out. */	eloop_register_timeout(5, 0, ieee802_11_sta_authenticate, hapd, NULL);}static void ieee802_11_sta_associate(void *eloop_ctx, void *timeout_ctx){	struct hostapd_data *hapd = eloop_ctx;	u8 buf[256];	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) buf;	u8 *p;	if (hapd->assoc_ap_state == AUTHENTICATE)		hapd->assoc_ap_state = ASSOCIATE;	if (hapd->assoc_ap_state != ASSOCIATE)		return;	printf("Associate with AP " MACSTR " SSID=",	       MAC2STR(hapd->conf->assoc_ap_addr));	ieee802_11_print_ssid((u8 *) hapd->assoc_ap_ssid,			      hapd->assoc_ap_ssid_len);	printf(" (as station)\n");	memset(mgmt, 0, sizeof(*mgmt));	mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,					  WLAN_FC_STYPE_ASSOC_REQ);	/* Request TX callback */	mgmt->frame_control |= host_to_le16(BIT(1));	memcpy(mgmt->da, hapd->conf->assoc_ap_addr, ETH_ALEN);	memcpy(mgmt->sa, hapd->own_addr, ETH_ALEN);	memcpy(mgmt->bssid, hapd->conf->assoc_ap_addr, ETH_ALEN);	mgmt->u.assoc_req.capab_info = host_to_le16(0);	mgmt->u.assoc_req.listen_interval = host_to_le16(1);	p = &mgmt->u.assoc_req.variable[0];	*p++ = WLAN_EID_SSID;	*p++ = hapd->assoc_ap_ssid_len;	memcpy(p, hapd->assoc_ap_ssid, hapd->assoc_ap_ssid_len);	p += hapd->assoc_ap_ssid_len;	p = hostapd_eid_supp_rates(hapd, p);	p = hostapd_eid_ext_supp_rates(hapd, p);	if (hostapd_send_mgmt_frame(hapd, mgmt, p - (u8 *) mgmt, 0) < 0)		perror("ieee802_11_sta_associate: send");	/* Try to authenticate again, if this attempt fails or times out. */	eloop_register_timeout(5, 0, ieee802_11_sta_associate, hapd, NULL);}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 = wpa_zalloc(WLAN_AUTH_CHALLENGE_LEN);			if (sta->challenge == NULL)				return WLAN_STATUS_UNSPECIFIED_FAILURE;			now = time(NULL);			r = random();			memcpy(key, &now, 4);			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 ||	    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	free(sta->challenge);	sta->challenge = NULL;	return 0;}static void send_auth_reply(struct hostapd_data *hapd,			    struct ieee80211_mgmt *mgmt,			    u16 auth_alg, u16 auth_transaction, u16 resp,			    u8 *challenge){	u8 buf[IEEE80211_HDRLEN + sizeof(mgmt->u.auth) + 2 +	       WLAN_AUTH_CHALLENGE_LEN];	struct ieee80211_mgmt *reply;	size_t rlen;	memset(buf, 0, sizeof(buf));	reply = (struct ieee80211_mgmt *) buf;	reply->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,					   WLAN_FC_STYPE_AUTH);	/* Request TX callback */	reply->frame_control |= host_to_le16(BIT(1));	memcpy(reply->da, mgmt->sa, ETH_ALEN);	memcpy(reply->sa, hapd->own_addr, ETH_ALEN);	memcpy(reply->bssid, mgmt->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);	rlen = IEEE80211_HDRLEN + sizeof(reply->u.auth);	if (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 2 &&	    challenge) {		u8 *p = reply->u.auth.variable;		*p++ = WLAN_EID_CHALLENGE;		*p++ = WLAN_AUTH_CHALLENGE_LEN;		memcpy(p, challenge, WLAN_AUTH_CHALLENGE_LEN);		rlen += 2 + WLAN_AUTH_CHALLENGE_LEN;	} else		challenge = NULL;	HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,		      "authentication reply: STA=" MACSTR " auth_alg=%d "		      "auth_transaction=%d resp=%d%s\n",		      MAC2STR(mgmt->sa), auth_alg, auth_transaction,		      resp, challenge ? " challenge" : "");	if (hostapd_send_mgmt_frame(hapd, reply, rlen, 0) < 0)		perror("send_auth_reply: send");}static void handle_auth(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt,

⌨️ 快捷键说明

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