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

📄 iw_ndis.c

📁 改文件可以安装无线网卡在linux下的驱动,大家可以在网站上查找一下用法
💻 C
📖 第 1 页 / 共 4 页
字号:
 /* *  Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  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. * */#include <linux/version.h>#include <linux/wireless.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/ethtool.h>#include <linux/if_arp.h>#include <linux/usb.h>#include <linux/random.h>#include <net/iw_handler.h>#include <linux/rtnetlink.h>#include <asm/uaccess.h>#include "iw_ndis.h"#include "wrapper.h"static int freq_chan[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,			   2447, 2452, 2457, 2462, 2467, 2472, 2484 };static const char *network_names[] = {"IEEE 802.11FH", "IEEE 802.11b",				      "IEEE 802.11a", "IEEE 802.11g", "Auto"};int set_essid(struct ndis_handle *handle, const char *ssid, int ssid_len){	NDIS_STATUS res;	struct ndis_essid req;	memset(&req, 0, sizeof(req));		if (ssid_len == 0)		req.length = 1;	else {		if (ssid_len > NDIS_ESSID_MAX_SIZE)			return -EINVAL;		req.length = ssid_len;		memcpy(&req.essid, ssid, req.length);		DBGTRACE1("ssid = '%s'", req.essid);	}		res = miniport_set_info(handle, OID_802_11_SSID, &req, sizeof(req));	if (res)		WARNING("setting essid failed (%08X)", res); 	memcpy(&handle->essid, &req, sizeof(req));	TRACEEXIT1(return 0);}static int iw_set_essid(struct net_device *dev, struct iw_request_info *info,			union iwreq_data *wrqu, char *extra){	struct ndis_handle *handle = dev->priv;	char ssid[IW_ESSID_MAX_SIZE];	memset(ssid, 0, sizeof(ssid));	/* iwconfig adds 1 to the actual length */	/* there is no way to turn off essid other than to set to	 * random bytes; instead, we use off to mean any */	if (wrqu->essid.flags)		wrqu->essid.length--;	else		wrqu->essid.length = 0;	if (wrqu->essid.length > IW_ESSID_MAX_SIZE)		TRACEEXIT1(return -EINVAL);	memcpy(ssid, extra, wrqu->essid.length);	if (set_essid(handle, ssid, wrqu->essid.length))		TRACEEXIT1(return -EINVAL);	TRACEEXIT1(return 0);}static int iw_get_essid(struct net_device *dev, struct iw_request_info *info,			union iwreq_data *wrqu, char *extra){	struct ndis_handle *handle = dev->priv; 	NDIS_STATUS res;	struct ndis_essid req;	TRACEENTER1("%s", "");	memset(&req, 0, sizeof(req));	res = miniport_query_info(handle, OID_802_11_SSID, &req, sizeof(req));	if (res)		WARNING("getting essid failed (%08X)", res);	memcpy(extra, req.essid, req.length);	extra[req.length] = 0;	if (req.length > 0)		wrqu->essid.flags  = 1;	else		wrqu->essid.flags = 0;	wrqu->essid.length = req.length;	TRACEEXIT1(return 0);}int set_infra_mode(struct ndis_handle *handle,		   enum network_infrastructure mode){	NDIS_STATUS res;	unsigned int i;	TRACEENTER1("%s", "");	res = miniport_set_int(handle, OID_802_11_INFRASTRUCTURE_MODE, mode);	if (res == NDIS_STATUS_INVALID_DATA) {		WARNING("setting operating mode failed (%08X)", res); 		TRACEEXIT1(return -EINVAL);	}	for (i = 0; i < MAX_ENCR_KEYS; i++)		handle->encr_info.keys[i].length = 0;	handle->infrastructure_mode = mode;	TRACEEXIT1(return 0);}static int iw_set_infra_mode(struct net_device *dev,			     struct iw_request_info *info,			     union iwreq_data *wrqu, char *extra){	struct ndis_handle *handle = dev->priv;	enum network_infrastructure ndis_mode;	TRACEENTER1("%s", "");	switch (wrqu->mode) {	case IW_MODE_ADHOC:		ndis_mode = Ndis802_11IBSS;		break;		case IW_MODE_INFRA:		ndis_mode = Ndis802_11Infrastructure;		break;		case IW_MODE_AUTO:		ndis_mode = Ndis802_11AutoUnknown;		break;		default:		TRACEEXIT1(return -EINVAL);	}		if (set_infra_mode(handle, ndis_mode))		TRACEEXIT1(return -EINVAL);	TRACEEXIT1(return 0);}static int iw_get_infra_mode(struct net_device *dev,			     struct iw_request_info *info,			     union iwreq_data *wrqu, char *extra){	struct ndis_handle *handle = dev->priv; 	int ndis_mode, iw_mode;	NDIS_STATUS res;	TRACEENTER1("%s", "");	res = miniport_query_int(handle, OID_802_11_INFRASTRUCTURE_MODE,				 &ndis_mode);	if (res) {		WARNING("getting operating mode failed (%08X)", res);		TRACEEXIT1(return -EOPNOTSUPP);	}	switch(ndis_mode) {	case Ndis802_11IBSS:		iw_mode = IW_MODE_ADHOC;		break;	case Ndis802_11Infrastructure:		iw_mode = IW_MODE_INFRA;		break;	case Ndis802_11AutoUnknown:		iw_mode = IW_MODE_AUTO;		break;	default:		ERROR("invalid operating mode (%u)", ndis_mode);		TRACEEXIT1(return -EINVAL);	}	wrqu->mode = iw_mode;	TRACEEXIT1(return 0);}static const char *network_type_to_name(int net_type){	if (net_type >= 0 &&	    net_type < (sizeof(network_names)/sizeof(network_names[0])))		return network_names[net_type];	else		return network_names[sizeof(network_names) / 				     sizeof(network_names[0]) - 1];}static int iw_get_network_type(struct net_device *dev,			       struct iw_request_info *info,			       union iwreq_data *wrqu, char *extra){	struct ndis_handle *handle = dev->priv;	unsigned int network_type;	NDIS_STATUS res;		res = miniport_query_int(handle, OID_802_11_NETWORK_TYPE_IN_USE,				 &network_type);	if (res == NDIS_STATUS_INVALID_DATA)		network_type = -1;	strncpy(wrqu->name, network_type_to_name(network_type),	        sizeof(wrqu->name) - 1);	wrqu->name[sizeof(wrqu->name)-1] = 0;	return 0;}static int iw_get_freq(struct net_device *dev, struct iw_request_info *info,		       union iwreq_data *wrqu, char *extra){	struct ndis_handle *handle = dev->priv;	NDIS_STATUS res;	struct ndis_configuration req;	memset(&req, 0, sizeof(req));	res = miniport_query_info(handle, OID_802_11_CONFIGURATION,				  &req, sizeof(req));	if (res == NDIS_STATUS_INVALID_DATA) {		WARNING("getting configuration failed (%08X)", res);		TRACEEXIT2(return -EOPNOTSUPP);	}	memset(&(wrqu->freq), 0, sizeof(struct iw_freq));	/* see comment in wireless.h above the "struct iw_freq"	   definition for an explanation of this if	   NOTE: 1000000 is due to the kHz	*/	if (req.ds_config > 1000000) {		wrqu->freq.m = req.ds_config / 10;		wrqu->freq.e = 1;	}	else		wrqu->freq.m = req.ds_config;	/* convert from kHz to Hz */	wrqu->freq.e += 3;	return 0;}static int iw_set_freq(struct net_device *dev, struct iw_request_info *info,		       union iwreq_data *wrqu, char *extra){	struct ndis_handle *handle = dev->priv;	NDIS_STATUS res;	struct ndis_configuration req;	memset(&req, 0, sizeof(req));	res = miniport_query_info(handle, OID_802_11_CONFIGURATION,				  &req, sizeof(req));	if (res == NDIS_STATUS_INVALID_DATA) {		WARNING("getting configuration failed (%08X)", res);		TRACEEXIT2(return -EOPNOTSUPP);	}	if (wrqu->freq.m < 1000 && wrqu->freq.e == 0) {		if (wrqu->freq.m >= 1 &&		    wrqu->freq.m <= (sizeof(freq_chan)/sizeof(freq_chan[0])))			req.ds_config = freq_chan[wrqu->freq.m - 1] * 1000;		else			return -EINVAL;	} else {		int i;		for (req.ds_config = wrqu->freq.m, i = wrqu->freq.e ;		     i > 0 ; i--)			req.ds_config *= 10;		req.ds_config /= 1000;			}	res = miniport_set_info(handle, OID_802_11_CONFIGURATION, &req,				sizeof(req));	if (res == NDIS_STATUS_INVALID_DATA) {		WARNING("setting configuration failed (%08X)", res);		return -EINVAL;	}	return 0;}static int iw_get_tx_power(struct net_device *dev,			   struct iw_request_info *info,			   union iwreq_data *wrqu, char *extra){	struct ndis_handle *handle = dev->priv; 	ndis_tx_power_level ndis_power;	NDIS_STATUS res;	res = miniport_query_info(handle, OID_802_11_TX_POWER_LEVEL,				  &ndis_power, sizeof(ndis_power));	/* Centrino driver returns NDIS_STATUS_INVALID_OID (why?) */	if (res == NDIS_STATUS_NOT_SUPPORTED || res == NDIS_STATUS_INVALID_OID)		return -EOPNOTSUPP;	wrqu->txpower.flags = IW_TXPOW_MWATT;	wrqu->txpower.disabled = 0;	wrqu->txpower.fixed = 0;	wrqu->txpower.value = ndis_power;	return 0;}static int iw_set_tx_power(struct net_device *dev,			   struct iw_request_info *info,			   union iwreq_data *wrqu, char *extra){	struct ndis_handle *handle = dev->priv; 	ndis_tx_power_level ndis_power;	NDIS_STATUS res;	if (wrqu->txpower.disabled) {		ndis_power = 0;		res = miniport_set_info(handle, OID_802_11_TX_POWER_LEVEL,					&ndis_power, sizeof(ndis_power));		if (res == NDIS_STATUS_INVALID_DATA)			return -EINVAL;		res = miniport_set_int(handle, OID_802_11_DISASSOCIATE, 0);		if (res)			return -EINVAL;		return 0;	} else {		if (wrqu->txpower.flags == IW_TXPOW_MWATT)			ndis_power = wrqu->txpower.value;		else { // wrqu->txpower.flags == IW_TXPOW_DBM			if (wrqu->txpower.value > 20)				ndis_power = 128;			else if (wrqu->txpower.value < -43)				ndis_power = 127;			else {				signed char tmp;				tmp = wrqu->txpower.value;				tmp = -12 - tmp;				tmp <<= 2;				ndis_power = (unsigned char)tmp;			}		}	}	res = miniport_set_info(handle, OID_802_11_TX_POWER_LEVEL,				&ndis_power, sizeof(ndis_power));	if (res)		WARNING("setting tx_power failed (%08X)", res);	if (res == NDIS_STATUS_NOT_SUPPORTED)		return -EOPNOTSUPP;	if (res == NDIS_STATUS_INVALID_DATA)		return -EINVAL;	return 0;}static int iw_get_bitrate(struct net_device *dev, struct iw_request_info *info,			  union iwreq_data *wrqu, char *extra){	struct ndis_handle *handle = dev->priv; 	ULONG ndis_rate;	int res = miniport_query_info(handle, OID_GEN_LINK_SPEED,				      &ndis_rate, sizeof(ndis_rate));	if (res) {		WARNING("getting bitrate failed (%08X)", res);		ndis_rate = 0;	}	wrqu->bitrate.value = ndis_rate * 100;	return 0;}static int iw_set_bitrate(struct net_device *dev, struct iw_request_info *info,			  union iwreq_data *wrqu, char *extra){	struct ndis_handle *handle = dev->priv; 	int i;	NDIS_STATUS res;	ndis_rates rates;	if (wrqu->bitrate.fixed == 0)		TRACEEXIT1(return 0);	res = miniport_query_info(handle, OID_802_11_SUPPORTED_RATES,				  &rates, sizeof(rates));	if (res == NDIS_STATUS_NOT_SUPPORTED ||	    res == NDIS_STATUS_INVALID_DATA) {		WARNING("getting bit rate failed (%08X)", res);		TRACEEXIT1(return 0);	}			for (i = 0 ; i < NDIS_MAX_RATES_EX ; i++) {		if (rates[i] & 0x80)			continue;		if ((rates[i] & 0x7f) * 500000 > wrqu->bitrate.value) {			DBGTRACE1("setting rate %d to 0",				  (rates[i] & 0x7f) * 500000);			rates[i] = 0;		}	}	res = miniport_query_info(handle, OID_802_11_DESIRED_RATES,				  &rates, sizeof(rates));	if (res == NDIS_STATUS_NOT_SUPPORTED ||	    res == NDIS_STATUS_INVALID_DATA) {		WARNING("setting bit rate failed (%08X)", res);		TRACEEXIT1(return 0);	}	return 0;}static int iw_set_dummy(struct net_device *dev, struct iw_request_info *info,			union iwreq_data *wrqu, char *extra){	/* Do nothing. Used for ioctls that are not implemented. */	return 0;}static int iw_get_rts_threshold(struct net_device *dev,				struct iw_request_info *info,				union iwreq_data *wrqu, char *extra){	struct ndis_handle *handle = dev->priv;	ndis_rts_threshold rts_threshold;	NDIS_STATUS res;

⌨️ 快捷键说明

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