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

📄 ieee80211_wx.c

📁 rtl8180网卡在linux下的驱动程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************    Copyright(c) 2004 Intel Corporation. All rights reserved.  Portions of this file are based on the WEP enablement code provided by the  Host AP project hostap-drivers v0.1.3  Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen  <jkmaline@cc.hut.fi>  Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>  Association logic, scanning WX and logics added by Andrea Merello   <andreamrl@tiscali.it>    This program is free software; you can redistribute it and/or modify it   under the terms of version 2 of the GNU General Public License as   published by the Free Software Foundation.    This program is distributed in the hope that it will be useful, but WITHOUT   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for   more details.    You should have received a copy of the GNU General Public License along with  this program; if not, write to the Free Software Foundation, Inc., 59   Temple Place - Suite 330, Boston, MA  02111-1307, USA.    The full GNU General Public License is included in this distribution in the  file called LICENSE.    Contact Information:  James P. Ketrenos <ipw2100-admin@linux.intel.com>  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497******************************************************************************/#include <linux/wireless.h>#include <linux/version.h>#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)#include <linux/kmod.h> /* request_module */#include <linux/kernel.h>#include <linux/module.h>#endif#include "ieee80211.h"#include <linux/if_arp.h>#define RSSI2DBM(x) 98-(x)static inline char *wlan_translate_scan(char *start, char *stop, 					   struct ieee80211_beacon *beacon){	struct iw_event iwe;	int i;	/* First entry *MUST* be the AP MAC address */	iwe.cmd = SIOCGIWAP;	iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 	memcpy(iwe.u.ap_addr.sa_data, beacon->bssid, ETH_ALEN);	start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN);		/* Remaining entries will be displayed in the order we provide them */	/* Add the ESSID */        iwe.u.data.length = beacon->ssid_len;        if (iwe.u.data.length > 32)		iwe.u.data.length = 32;        iwe.cmd = SIOCGIWESSID;        iwe.u.data.flags = 1;        start = iwe_stream_add_point(start, stop, &iwe, beacon->ssid);        /* Add mode */        iwe.cmd = SIOCGIWMODE;        if (beacon->capability & 	    (WLAN_CAPABILITY_BSS | WLAN_CAPABILITY_IBSS)) {		if (beacon->capability & WLAN_CAPABILITY_BSS)			iwe.u.mode = IW_MODE_MASTER;		else			iwe.u.mode = IW_MODE_ADHOC;		start = iwe_stream_add_event(start, stop, &iwe, 					     IW_EV_UINT_LEN);	}	        /* Add frequency */	iwe.cmd = SIOCGIWFREQ;	iwe.u.freq.m = wlan_frequencies[beacon->channel -1] * 100000;	iwe.u.freq.e = 1;	start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);	/* Add rates */	iwe.cmd = SIOCGIWRATE;	iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;	for (i = 0; i < beacon->rates_len; i++) {		iwe.u.bitrate.value = (beacon->rates[i] & 0x7F) * 500000;		start = iwe_stream_add_event(start, stop, &iwe, 					     IW_EV_PARAM_LEN);	}	/* Add quality statistics */	iwe.cmd = IWEVQUAL;	iwe.u.qual.qual = beacon->quality ;	iwe.u.qual.level = beacon->rssi ;	iwe.u.qual.noise = 0;	iwe.u.qual.updated = 7;		start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);	/* Add encryption capability */	iwe.cmd = SIOCGIWENCODE;	if (beacon->capability & WLAN_CAPABILITY_PRIVACY)		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;	else		iwe.u.data.flags = IW_ENCODE_DISABLED;	iwe.u.data.length = 0;	start = iwe_stream_add_point(start, stop, &iwe, beacon->ssid);	return start;}  int ieee80211_r8180_wx_get_scan(struct ieee80211_device *ieee,struct iw_request_info *a,union iwreq_data *wrqu,char *extra){		struct ieee80211_beacon *beacon;	struct list_head *b,*delprev,*prev,*next;	unsigned long flags;	char *ev = extra;	char *stop = ev + IW_SCAN_MAX_DATA;		delprev = NULL;		spin_lock_irqsave(&ieee->irq_lock, flags);			list_for_each(b,&ieee->beacons){		if (delprev){			kfree(list_entry(delprev,struct ieee80211_beacon,list));			delprev=NULL;		}		beacon=list_entry(b,struct ieee80211_beacon,list);					if(beacon->last_scanned + SCAN_JIFFI < jiffies){ 					  prev = b->prev;			  next = b->next;			  next->prev = prev;			  prev->next = next;			  delprev=b;				}else{			ev = wlan_translate_scan(ev, stop, beacon);		/*	printk("cell %s : %x %x %x %x %x %x\n",beacon->ssid,beacon->bssid[0],				beacon->bssid[1],beacon->bssid[2],beacon->bssid[3],beacon->bssid[4],				beacon->bssid[5]);*/		}	}		spin_unlock_irqrestore(&ieee->irq_lock, flags);	wrqu->data.length = ev -  extra;	wrqu->data.flags = 0;		return 0;	}#ifndef CONFIG_IEEE80211_NOWEPstatic void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,					   struct ieee80211_crypt_data **crypt){	struct ieee80211_crypt_data *tmp;	unsigned long flags;	if (*crypt == NULL)		return;		tmp = *crypt;	*crypt = NULL;	/* must not run ops->deinit() while there may be pending encrypt or	 * decrypt operations. Use a list of delayed deinits to avoid needing	 * locking. */	spin_lock_irqsave(&ieee->lock, flags);	list_add(&tmp->list, &ieee->crypt_deinit_list);	if (!timer_pending(&ieee->crypt_deinit_timer)) {		ieee->crypt_deinit_timer.expires = jiffies + HZ;		add_timer(&ieee->crypt_deinit_timer);	}	spin_unlock_irqrestore(&ieee->lock, flags);}#endifint ieee80211_r8180_wx_set_encode(struct ieee80211_device *ieee,			    struct iw_request_info *info, 			    union iwreq_data *wrqu, char *keybuf){	struct iw_point *erq = &(wrqu->encoding);#ifdef CONFIG_IEEE80211_NOWEP	if (erq->flags & IW_ENCODE_DISABLED)		return 0;	return -EOPNOTSUPP;#else	struct net_device *dev = ieee->dev;	struct ieee80211_security sec = {		.flags = 0	};	int key;	struct ieee80211_crypt_data **crypt;		key = erq->flags & IW_ENCODE_INDEX;	if (key) {		if (key > 4)			return -EINVAL;		else			key--;		if (key >= WEP_KEYS)			return -EINVAL;	} else 		key = ieee->tx_keyidx; 		crypt = &ieee->crypt[key];		if (erq->flags & IW_ENCODE_DISABLED) {		if (*crypt) {			sec.enabled = 0;			sec.level = SEC_LEVEL_0;			sec.flags |= SEC_ENABLED | SEC_LEVEL;			ieee80211_crypt_delayed_deinit(ieee, crypt);		}		goto done;	}		sec.enabled = 1;	sec.flags |= SEC_ENABLED;	if (*crypt != NULL && (*crypt)->ops != NULL &&	    strcmp((*crypt)->ops->name, "WEP") != 0) {		/* changing to use WEP; deinit previously used algorithm */		ieee80211_crypt_delayed_deinit(ieee, crypt);	}		if (*crypt == NULL) {		struct ieee80211_crypt_data *new_crypt;				/* take WEP into use */		new_crypt = (struct ieee80211_crypt_data *)			kmalloc(sizeof(struct ieee80211_crypt_data), GFP_KERNEL);		if (new_crypt == NULL)			return -ENOMEM;		memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));		new_crypt->ops = ieee80211_r8180_get_crypto_ops("WEP");		if (!new_crypt->ops) {			request_module("ieee80211_crypt_wep-r8180");			new_crypt->ops = ieee80211_r8180_get_crypto_ops("WEP");		}		if (new_crypt->ops)			new_crypt->priv = new_crypt->ops->init(key);		if (!new_crypt->ops || !new_crypt->priv) {			kfree(new_crypt);			new_crypt = NULL;			printk(KERN_WARNING "%s: could not initialize WEP: "			       "load module ieee80211_crypt_wep_r8180.o\n",			       dev->name);			return -EOPNOTSUPP;		}		*crypt = new_crypt;	}	if (erq->length > 0) {		int len = erq->length <= 5 ? 5 : 13;		int first = 1, j;		if (len > erq->length)			memset(keybuf + erq->length, 0, len - erq->length);		(*crypt)->ops->set_key(keybuf, len, NULL, (*crypt)->priv);		memcpy(sec.keys[key], keybuf, len);		sec.key_sizes[key] = len;		sec.flags |= (1 << key);		for (j = 0; j < WEP_KEYS; j++) {			if (j != key && ieee->crypt[j]) {				first = 0;				break;			}		}		if (first)			ieee->tx_keyidx = key;			sec.active_key = key;			sec.flags |= SEC_ACTIVE_KEY;	} else {		/* No key data - just set the default TX key index */		ieee->tx_keyidx = key;		sec.active_key = key;		sec.flags |= SEC_ACTIVE_KEY;	}	 done:	ieee->open_wep = erq->flags & IW_ENCODE_OPEN;	sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;	sec.flags |= SEC_AUTH_MODE;	/* For now we just support WEP, so only set that security level... 	 * TODO: When WPA is added this is one place that needs to change */	sec.flags |= SEC_LEVEL;	sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */	if (ieee->func && ieee->func->set_security)		ieee->func->set_security(ieee, &sec);	/* Do not reset port if card is in Managed mode since resetting will	 * generate new IEEE 802.11 authentication which may end up in looping	 * with IEEE 802.1X.  If your hardware requires a reset after WEP	 * configuration (for example... Prism2), implement the reset_port in 	 * the callbacks structures used to initialize the 802.11 stack. */	if (ieee->reset_on_keychange &&	    ieee->iw_mode != IW_MODE_INFRA && 	    ieee->func->reset_port &&	    ieee->func->reset_port(dev)) {		printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);		return -EINVAL;	}	return 0;#endif}#if 0int ieee80211_wx_set_encode(struct ieee80211_device *ieee,			   struct iw_request_info *info, 			   union iwreq_data *wrqu, char *key){	struct iw_point *erq = &(wrqu->encoding);#ifdef CONFIG_IEEE80211_NOWEP	if (erq->flags & IW_ENCODE_DISABLED)		return 0;	return -EOPNOTSUPP;#else	struct net_device *dev = ieee->dev;	struct ieee80211_security sec = {		.flags = 0	};	int first = 0;	int i;	if (erq->flags & IW_ENCODE_DISABLED) {		sec.enabled = 0;		sec.flags |= SEC_ENABLED;		ieee80211_crypt_delayed_deinit(ieee, &ieee->crypt);		goto done;	}		sec.enabled = 1;	sec.flags |= SEC_ENABLED;	if (ieee->crypt != NULL && ieee->crypt->ops != NULL &&	    strcmp(ieee->crypt->ops->name, "WEP") != 0) {		/* changing to use WEP; deinit previously used algorithm */		ieee80211_crypt_delayed_deinit(ieee, &ieee->crypt);

⌨️ 快捷键说明

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