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

📄 p80211wext.c

📁 对于无线网卡采用prism芯片的linux的开源驱动.
💻 C
📖 第 1 页 / 共 3 页
字号:
/* src/p80211/p80211wext.c* * Glue code to make linux-wlan-ng a happy wireless extension camper.* * original author:  Reyk Floeter <reyk@synack.de>* Completely re-written by Solomon Peachy <solomon@linux-wlan.com>** Copyright (C) 2002 AbsoluteValue Systems, Inc.  All Rights Reserved.* --------------------------------------------------------------------** linux-wlan**   The contents of this file are subject to the Mozilla Public*   License Version 1.1 (the "License"); you may not use this file*   except in compliance with the License. You may obtain a copy of*   the License at http://www.mozilla.org/MPL/**   Software distributed under the License is distributed on an "AS*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or*   implied. See the License for the specific language governing*   rights and limitations under the License.**   Alternatively, the contents of this file may be used under the*   terms of the GNU Public License version 2 (the "GPL"), in which*   case the provisions of the GPL are applicable instead of the*   above.  If you wish to allow the use of your version of this file*   only under the terms of the GPL and not to allow others to use*   your version of this file under the MPL, indicate your decision*   by deleting the provisions above and replace them with the notice*   and other provisions required by the GPL.  If you do not delete*   the provisions above, a recipient may use your version of this*   file under either the MPL or the GPL.** --------------------------------------------------------------------*//*================================================================*//* System Includes */#include <linux/config.h>#include <linux/version.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/types.h>#include <linux/slab.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/wireless.h>#if WIRELESS_EXT > 12#include <net/iw_handler.h>#endif#include <linux/if_arp.h>#include <asm/bitops.h>#include <asm/uaccess.h>#include <asm/byteorder.h>/*================================================================*//* Project Includes */#include <wlan/version.h>#include <wlan/wlan_compat.h>#include <wlan/p80211types.h>#include <wlan/p80211hdr.h>#include <wlan/p80211conv.h>#include <wlan/p80211mgmt.h>#include <wlan/p80211msg.h>#include <wlan/p80211metastruct.h>#include <wlan/p80211metadef.h>#include <wlan/p80211netdev.h>#include <wlan/p80211ioctl.h>#include <wlan/p80211req.h>static int p80211wext_giwrate(netdevice_t *dev,			      struct iw_request_info *info,			      struct iw_param *rrq, char *extra);static int p80211wext_giwessid(netdevice_t *dev,			       struct iw_request_info *info,			       struct iw_point *data, char *essid);/* compatibility to wireless extensions */#ifdef WIRELESS_EXTUINT8 p80211_mhz_to_channel(UINT16 mhz){	if (mhz >= 5000) {		return ((mhz - 5000) / 5);	} 	if (mhz == 2482)		return 14;		if (mhz >= 2407) {		return ((mhz - 2407) / 5);	}	return 0;}UINT16 p80211_channel_to_mhz(UINT8 ch, int dot11a){	if (ch == 0)		return 0;	if (ch > 200)		return 0;	/* 5G */	if (dot11a) {		return (5000 + (5 * ch));	}		/* 2.4G */	if (ch == 14)		return 2484;		if ((ch < 14) && (ch > 0)) {		return (2407 + (5 * ch));	}		return 0;}/* taken from orinoco.c ;-) */const long p80211wext_channel_freq[] = {	2412, 2417, 2422, 2427, 2432, 2437, 2442,	2447, 2452, 2457, 2462, 2467, 2472, 2484};#define NUM_CHANNELS (sizeof(p80211wext_channel_freq) / sizeof(p80211wext_channel_freq[0])) /** function declarations =============== */static int p80211wext_dorequest(wlandevice_t *wlandev, UINT32 did, UINT32 data){	p80211msg_dot11req_mibset_t	msg;	p80211item_uint32_t		mibitem;	int	result;		DBFENTER;	msg.msgcode = DIDmsg_dot11req_mibset;	mibitem.did = did;	mibitem.data = data;	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));	result = p80211req_dorequest(wlandev, (UINT8*)&msg);	DBFEXIT;	return result;}static int p80211wext_autojoin(wlandevice_t *wlandev){	p80211msg_lnxreq_autojoin_t     msg;	struct iw_point			data;	char ssid[IW_ESSID_MAX_SIZE];        	int result;	int err = 0;	DBFENTER;	/* Get ESSID */	result = p80211wext_giwessid(wlandev->netdev, NULL, &data, ssid);	if (result) {		err = -EFAULT;		goto exit;	}#warning "make a smarter sharedkey/opensystem auth decision"	/* Get WEPDef */	if (wlandev->hostwep & HOSTWEP_PRIVACYINVOKED ||	    wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED) {		msg.authtype.data = P80211ENUM_authalg_sharedkey;	}	else {		msg.authtype.data = P80211ENUM_authalg_opensystem;	}	msg.msgcode = DIDmsg_lnxreq_autojoin;			/* Trim the last '\0' to fit the SSID format */	if (ssid[data.length-1] == '\0') {		data.length = data.length - 1;	}		memcpy(msg.ssid.data.data, ssid, data.length);	msg.ssid.data.len = data.length;	result = p80211req_dorequest(wlandev, (UINT8*)&msg);	if (result) {		err = -EFAULT;		goto exit;	}exit:	DBFEXIT;	return err;	}/* called by /proc/net/wireless */struct iw_statistics* p80211wext_get_wireless_stats (netdevice_t *dev) {	p80211msg_lnxreq_commsquality_t  quality;	wlandevice_t *wlandev = (wlandevice_t*)dev->priv;	struct iw_statistics* wstats = &wlandev->wstats;	int retval;		DBFENTER;		/* Check */	if ( (wlandev == NULL) || (wlandev->msdstate != WLAN_MSD_RUNNING) )		return NULL;	/* XXX Only valid in station mode */	wstats->status = 0;	/* build request message */	quality.msgcode = DIDmsg_lnxreq_commsquality;	quality.dbm.data = P80211ENUM_truth_true;	quality.dbm.status = P80211ENUM_msgitem_status_data_ok;	/* send message to nsd */	if ( wlandev->mlmerequest == NULL )		return NULL;	retval = wlandev->mlmerequest(wlandev, (p80211msg_t*) &quality);	wstats->qual.qual = quality.link.data;    /* overall link quality */	wstats->qual.level = quality.level.data;  /* instant signal level */	wstats->qual.noise = quality.noise.data;  /* instant noise level */	wstats->qual.updated = 7;	wstats->discard.code = wlandev->rx.decrypt_err;	wstats->discard.nwid = 0;	wstats->discard.misc = 0;#if WIRELESS_EXT > 11		wstats->discard.fragment = 0;  // incomplete fragments	wstats->discard.retries = 0;   // tx retries.	wstats->miss.beacon = 0;#endif	DBFEXIT;		return wstats;}static int p80211wext_giwname(netdevice_t *dev,			      struct iw_request_info *info,			      char *name, char *extra){	struct iw_param rate;	int result;	int err = 0;		DBFENTER;	result = p80211wext_giwrate(dev, NULL, &rate, NULL); 	if (result) {		err = -EFAULT;		goto exit;	}		switch (rate.value) {	case 1000000:	case 2000000:		strcpy(name, "IEEE 802.11-DS");		break;	case 5500000:	case 11000000:		strcpy(name, "IEEE 802.11-b");		break;	}exit:	DBFEXIT;	return err;}static int p80211wext_giwfreq(netdevice_t *dev,			      struct iw_request_info *info,			      struct iw_freq *freq, char *extra){	wlandevice_t *wlandev = (wlandevice_t*)dev->priv;	p80211item_uint32_t             mibitem;	p80211msg_dot11req_mibset_t     msg;	int result;	int err = 0;	DBFENTER;	msg.msgcode = DIDmsg_dot11req_mibget;	mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel;	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));	result = p80211req_dorequest(wlandev, (UINT8*)&msg);		if (result) {		err = -EFAULT;		goto exit;	}		memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));		if (mibitem.data > NUM_CHANNELS) {		err = -EFAULT;		goto exit;	}		/* convert into frequency instead of a channel */	freq->e = 1;			freq->m = p80211_channel_to_mhz(mibitem.data, 0) * 100000; exit:	DBFEXIT;	return err;}static int p80211wext_siwfreq(netdevice_t *dev,			      struct iw_request_info *info,			      struct iw_freq *freq, char *extra){	wlandevice_t *wlandev = (wlandevice_t*)dev->priv;	p80211item_uint32_t             mibitem;	p80211msg_dot11req_mibset_t     msg;	int result;	int err = 0;	DBFENTER;	if (!wlan_wext_write) {		err = (-EOPNOTSUPP);		goto exit;	}	msg.msgcode = DIDmsg_dot11req_mibset;	mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel;	mibitem.status = P80211ENUM_msgitem_status_data_ok;		if ( (freq->e == 0) && (freq->m <= 1000) )		mibitem.data = freq->m;	else		mibitem.data = p80211_mhz_to_channel(freq->m);  	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));	result = p80211req_dorequest(wlandev, (UINT8*)&msg);		if (result) {		err = -EFAULT;		goto exit;	}	 exit:	DBFEXIT;	return err;}#if WIRELESS_EXT > 8static int p80211wext_giwmode(netdevice_t *dev,			      struct iw_request_info *info,			      __u32 *mode, char *extra){	wlandevice_t *wlandev = (wlandevice_t*)dev->priv;	DBFENTER;	switch (wlandev->macmode) {	case WLAN_MACMODE_IBSS_STA: 		*mode = IW_MODE_ADHOC;		break;	case WLAN_MACMODE_ESS_STA:		*mode = IW_MODE_INFRA;		break;	case WLAN_MACMODE_ESS_AP:		*mode = IW_MODE_MASTER;		break;	default:		/* Not set yet. */		*mode = IW_MODE_AUTO;	}	DBFEXIT;	return 0;}static int p80211wext_siwmode(netdevice_t *dev,			      struct iw_request_info *info,			      __u32 *mode, char *extra){	wlandevice_t *wlandev = (wlandevice_t*)dev->priv;	p80211item_uint32_t             mibitem;	p80211msg_dot11req_mibset_t     msg;	int 	result;	int     err = 0;	DBFENTER;	if (!wlan_wext_write) {		err = (-EOPNOTSUPP);		goto exit;	}	if (*mode != IW_MODE_ADHOC && *mode != IW_MODE_INFRA &&	    *mode != IW_MODE_MASTER) {		err = (-EOPNOTSUPP);		goto exit;	}	/* Operation mode is the same with current mode */	if (*mode == wlandev->macmode)		goto exit;	switch (*mode) {	case IW_MODE_ADHOC:		wlandev->macmode = WLAN_MACMODE_IBSS_STA;		break;	case IW_MODE_INFRA:		wlandev->macmode = WLAN_MACMODE_ESS_STA;		break;	case IW_MODE_MASTER:		wlandev->macmode = WLAN_MACMODE_ESS_AP;		break;	default:		/* Not set yet. */		WLAN_LOG_INFO("Operation mode: %d not support\n", *mode);		return -EOPNOTSUPP;	}	/* Set Operation mode to the PORT TYPE RID */#warning "get rid of p2mib here"	msg.msgcode = DIDmsg_dot11req_mibset;	mibitem.did = DIDmib_p2_p2Static_p2CnfPortType;	mibitem.data = (*mode == IW_MODE_ADHOC) ? 0 : 1;	memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));	result = p80211req_dorequest(wlandev, (UINT8*)&msg);	if (result)		err = -EFAULT; exit:	DBFEXIT;	return err;}static int p80211wext_giwrange(netdevice_t *dev,			       struct iw_request_info *info,			       struct iw_point *data, char *extra){        struct iw_range *range = (struct iw_range *) extra;	int i, val;	DBFENTER;#if WIRELESS_EXT > 9	range->txpower_capa = IW_TXPOW_DBM;	// XXX what about min/max_pmp, min/max_pmt, etc.#endif#if WIRELESS_EXT > 10	range->we_version_compiled = WIRELESS_EXT;	range->we_version_source = 13;		range->retry_capa = IW_RETRY_LIMIT;	range->retry_flags = IW_RETRY_LIMIT;	range->min_retry = 0;	range->max_retry = 255;#endif /* WIRELESS_EXT > 10 */#if WIRELESS_EXT > 16        range->event_capa[0] = (IW_EVENT_CAPA_K_0 |  //mode/freq/ssid                                 IW_EVENT_CAPA_MASK(SIOCGIWAP) |                                 IW_EVENT_CAPA_MASK(SIOCGIWSCAN));        range->event_capa[1] = IW_EVENT_CAPA_K_1;  //encode        range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVQUAL) |                                IW_EVENT_CAPA_MASK(IWEVCUSTOM) );#endif	range->num_channels = NUM_CHANNELS;	/* XXX need to filter against the regulatory domain &| active set */	val = 0;	for (i = 0; i < NUM_CHANNELS ; i++) {		range->freq[val].i = i + 1;		range->freq[val].m = p80211wext_channel_freq[i] * 100000;		range->freq[val].e = 1;		val++;	}	range->num_frequency = val;		/* Max of /proc/net/wireless */	range->max_qual.qual = 92;	range->max_qual.level = 154;	range->max_qual.noise = 154;	range->sensitivity = 3;	// XXX these need to be nsd-specific!	range->min_rts = 0;	range->max_rts = 2347;	range->min_frag = 256;	range->max_frag = 2346;		range->max_encoding_tokens = NUM_WEPKEYS;	range->num_encoding_sizes = 2;	range->encoding_size[0] = 5;	range->encoding_size[1] = 13;		// XXX what about num_bitrates/throughput?	range->num_bitrates = 0;	/* estimated max throughput */	// XXX need to cap it if we're running at ~2Mbps..	range->throughput = 5500000;	DBFEXIT;	return 0;}#endifstatic int p80211wext_giwap(netdevice_t *dev,			    struct iw_request_info *info,			    struct sockaddr *ap_addr, char *extra){	wlandevice_t *wlandev = (wlandevice_t*)dev->priv;	DBFENTER;	memcpy(ap_addr->sa_data, wlandev->bssid, WLAN_BSSID_LEN);	ap_addr->sa_family = ARPHRD_ETHER;	DBFEXIT;	return 0;}#if WIRELESS_EXT > 8static int p80211wext_giwencode(netdevice_t *dev,				struct iw_request_info *info,				struct iw_point *erq, char *key){	wlandevice_t *wlandev = (wlandevice_t*)dev->priv;	int err = 0;	int i;	DBFENTER;	if (wlandev->hostwep & HOSTWEP_PRIVACYINVOKED)		erq->flags = IW_ENCODE_ENABLED;	else		erq->flags = IW_ENCODE_DISABLED;		if (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED)		erq->flags |= IW_ENCODE_RESTRICTED;	else		erq->flags |= IW_ENCODE_OPEN;	i = (erq->flags & IW_ENCODE_INDEX) - 1;	if (i == -1)		i = wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK;	if ((i < 0) || (i >= NUM_WEPKEYS)) {		err = -EINVAL;		goto exit;	}	erq->flags |= i + 1;	/* copy the key from the driver cache as the keys are read-only MIBs */	erq->length = wlandev->wep_keylens[i];	memcpy(key, wlandev->wep_keys[i], erq->length); exit:	DBFEXIT;	return err;}static int p80211wext_siwencode(netdevice_t *dev,				struct iw_request_info *info,				struct iw_point *erq, char *key){	wlandevice_t *wlandev = (wlandevice_t*)dev->priv;	p80211msg_dot11req_mibset_t	msg;	p80211item_pstr32_t		pstr;

⌨️ 快捷键说明

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