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

📄 iw_ndis.c

📁 ndis在linux下的无线网卡驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	struct wrap_ndis_device *wnd = netdev_priv(dev);	int i, n;	NDIS_STATUS res;	ndis_rates_ex rates_ex;	ENTER2("");	if (wrqu->bitrate.fixed == 0)		EXIT2(return 0);	res = miniport_query_info(wnd, OID_802_11_SUPPORTED_RATES,				  &rates_ex, sizeof(ndis_rates_ex));	if (res) {		res = miniport_query_info(wnd, OID_802_11_SUPPORTED_RATES,					  &rates_ex, sizeof(ndis_rates));		n = NDIS_MAX_RATES;	} else		n = NDIS_MAX_RATES_EX;	if (res) {		WARNING("getting bit rate failed (%08X)", res);		EXIT2(return 0);	}	for (i = 0 ; i < n ; i++) {		if (rates_ex[i] & 0x80)			continue;		if ((rates_ex[i] & 0x7f) * 500000 > wrqu->bitrate.value) {			TRACE2("setting rate %d to 0",			       (rates_ex[i] & 0x7f) * 500000);			rates_ex[i] = 0;		}	}	if (n == NDIS_MAX_RATES_EX)		res = miniport_set_info(wnd, OID_802_11_DESIRED_RATES,					&rates_ex, sizeof(ndis_rates_ex));	else		res = miniport_set_info(wnd, OID_802_11_DESIRED_RATES,					&rates_ex, sizeof(ndis_rates));	if (res) {		WARNING("setting bit rate failed (%08X)", res);		EXIT2(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 wrap_ndis_device *wnd = netdev_priv(dev);	ndis_rts_threshold threshold;	NDIS_STATUS res;	ENTER2("");	res = miniport_query_info(wnd, OID_802_11_RTS_THRESHOLD,				  &threshold, sizeof(threshold));	if (res)		return -EOPNOTSUPP;	wrqu->rts.value = threshold;	return 0;}static int iw_set_rts_threshold(struct net_device *dev,				struct iw_request_info *info,				union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	ndis_rts_threshold threshold;	NDIS_STATUS res;	ENTER2("");	threshold = wrqu->rts.value;	res = miniport_set_info(wnd, OID_802_11_RTS_THRESHOLD,				&threshold, sizeof(threshold));	if (res == NDIS_STATUS_INVALID_DATA)		return -EINVAL;	if (res)		return -EOPNOTSUPP;	return 0;}static int iw_get_frag_threshold(struct net_device *dev,				 struct iw_request_info *info,				 union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	ndis_fragmentation_threshold frag_threshold;	NDIS_STATUS res;	ENTER2("");	res = miniport_query_info(wnd, OID_802_11_FRAGMENTATION_THRESHOLD,				  &frag_threshold, sizeof(frag_threshold));	if (res)		return -ENOTSUPP;	wrqu->frag.value = frag_threshold;	return 0;}static int iw_set_frag_threshold(struct net_device *dev,				 struct iw_request_info *info,				 union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	ndis_rts_threshold threshold;	NDIS_STATUS res;	ENTER2("");	threshold = wrqu->frag.value;	res = miniport_set_info(wnd, OID_802_11_FRAGMENTATION_THRESHOLD,				&threshold, sizeof(threshold));	if (res == NDIS_STATUS_INVALID_DATA)		return -EINVAL;	if (res)		return -EOPNOTSUPP;	return 0;}int get_ap_address(struct wrap_ndis_device *wnd, mac_address ap_addr){	NDIS_STATUS res;	res = NDIS_STATUS_ADAPTER_NOT_READY;	/* this OID is valid only when associated */	if (netif_carrier_ok(wnd->net_dev))		res = miniport_query_info(wnd, OID_802_11_BSSID, ap_addr,					  ETH_ALEN);	TRACE2(MACSTRSEP, MAC2STR(ap_addr));	if (res) {		TRACE2("res: %08X", res);		memset(ap_addr, 0x0, ETH_ALEN);		EXIT2(return -EOPNOTSUPP);	}	EXIT2(return 0);}static int iw_get_ap_address(struct net_device *dev,			     struct iw_request_info *info,			     union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	mac_address ap_addr;	ENTER2("");	get_ap_address(wnd, ap_addr);	memcpy(wrqu->ap_addr.sa_data, ap_addr, ETH_ALEN);	wrqu->ap_addr.sa_family = ARPHRD_ETHER;	EXIT2(return 0);}static int iw_set_ap_address(struct net_device *dev,			     struct iw_request_info *info,			     union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	NDIS_STATUS res;	mac_address ap_addr;	ENTER2("");	memcpy(ap_addr, wrqu->ap_addr.sa_data, ETH_ALEN);	TRACE2(MACSTRSEP, MAC2STR(ap_addr));	res = miniport_set_info(wnd, OID_802_11_BSSID, ap_addr, ETH_ALEN);	/* user apps may set ap's mac address, which is not required;	 * they may fail to work if this function fails, so return	 * success */	if (res)		WARNING("setting AP mac address failed (%08X)", res);	EXIT2(return 0);}int set_auth_mode(struct wrap_ndis_device *wnd, ULONG auth_mode){	NDIS_STATUS res;	ENTER2("%d", auth_mode);	res = miniport_set_int(wnd, OID_802_11_AUTHENTICATION_MODE, auth_mode);	if (res) {		WARNING("setting auth mode to %u failed (%08X)",			auth_mode, res);		if (res == NDIS_STATUS_INVALID_DATA)			EXIT2(return -EINVAL);		return -EOPNOTSUPP;	}	wnd->auth_mode = auth_mode;	EXIT2(return 0);}int get_auth_mode(struct wrap_ndis_device *wnd){	ULONG mode;	NDIS_STATUS res;	res = miniport_query_int(wnd, OID_802_11_AUTHENTICATION_MODE, &mode);	if (res) {		WARNING("getting authentication mode failed (%08X)", res);		EXIT2(return -EOPNOTSUPP);	}	TRACE2("%d", mode);	return mode;}int set_encr_mode(struct wrap_ndis_device *wnd, ULONG encr_mode){	NDIS_STATUS res;	ENTER2("%d", encr_mode);	res = miniport_set_int(wnd, OID_802_11_ENCRYPTION_STATUS, encr_mode);	if (res) {		WARNING("setting encryption mode to %u failed (%08X)",			encr_mode, res);		if (res == NDIS_STATUS_INVALID_DATA)			EXIT2(return -EINVAL);		return -EOPNOTSUPP;	}	wnd->encr_mode = encr_mode;	EXIT2(return 0);}int get_encr_mode(struct wrap_ndis_device *wnd){	ULONG mode;	NDIS_STATUS res;	ENTER2("");	res = miniport_query_int(wnd, OID_802_11_ENCRYPTION_STATUS, &mode);	if (res) {		WARNING("getting encryption status failed (%08X)", res);		EXIT2(return -EOPNOTSUPP);	} else		EXIT2(return mode);}static int iw_get_encr(struct net_device *dev, struct iw_request_info *info,		       union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	int index, mode;	struct encr_info *encr_info = &wnd->encr_info;	ENTER2("wnd = %p", wnd);	wrqu->data.length = 0;	extra[0] = 0;	index = (wrqu->encoding.flags & IW_ENCODE_INDEX);	TRACE2("index = %u", index);	if (index > 0)		index--;	else		index = encr_info->tx_key_index;	if (index < 0 || index >= MAX_ENCR_KEYS) {		WARNING("encryption index out of range (%u)", index);		EXIT2(return -EINVAL);	}	if (index != encr_info->tx_key_index) {		if (encr_info->keys[index].length > 0) {			wrqu->data.flags |= IW_ENCODE_ENABLED;			wrqu->data.length = encr_info->keys[index].length;			memcpy(extra, encr_info->keys[index].key,			       encr_info->keys[index].length);		}		else			wrqu->data.flags |= IW_ENCODE_DISABLED;		EXIT2(return 0);	}	/* transmit key */	mode = get_encr_mode(wnd);	if (mode < 0)		EXIT2(return -EOPNOTSUPP);	if (mode == Ndis802_11EncryptionDisabled ||	    mode == Ndis802_11EncryptionNotSupported)		wrqu->data.flags |= IW_ENCODE_DISABLED;	else {		if (mode == Ndis802_11Encryption1KeyAbsent ||		    mode == Ndis802_11Encryption2KeyAbsent ||		    mode == Ndis802_11Encryption3KeyAbsent)			wrqu->data.flags |= IW_ENCODE_NOKEY;		else {			wrqu->data.flags |= IW_ENCODE_ENABLED;			wrqu->encoding.flags |= index+1;			wrqu->data.length = encr_info->keys[index].length;			memcpy(extra, encr_info->keys[index].key,			       encr_info->keys[index].length);		}	}	mode = get_auth_mode(wnd);	if (mode < 0)		EXIT2(return -EOPNOTSUPP);	if (mode == Ndis802_11AuthModeOpen)		wrqu->data.flags |= IW_ENCODE_OPEN;	else if (mode == Ndis802_11AuthModeAutoSwitch)		wrqu->data.flags |= IW_ENCODE_RESTRICTED;	else // Ndis802_11AuthModeAutoSwitch, Ndis802_11AuthModeWPA etc.		wrqu->data.flags |= IW_ENCODE_RESTRICTED;	EXIT2(return 0);}/* index must be 0 - N, as per NDIS  */int add_wep_key(struct wrap_ndis_device *wnd, char *key, int key_len,		int index){	struct ndis_encr_key ndis_key;	NDIS_STATUS res;	ENTER2("key index: %d, length: %d", index, key_len);	if (key_len <= 0 || key_len > NDIS_ENCODING_TOKEN_MAX) {		WARNING("invalid key length (%d)", key_len);		EXIT2(return -EINVAL);	}	if (index < 0 || index >= MAX_ENCR_KEYS) {		WARNING("invalid key index (%d)", index);		EXIT2(return -EINVAL);	}	ndis_key.struct_size = sizeof(ndis_key);	ndis_key.length = key_len;	memcpy(&ndis_key.key, key, key_len);	ndis_key.index = index;	if (index == wnd->encr_info.tx_key_index) {		ndis_key.index |= (1 << 31);		res = set_encr_mode(wnd, Ndis802_11Encryption1Enabled);		if (res)			WARNING("encryption couldn't be enabled (%08X)", res);	}	TRACE2("key %d: " MACSTRSEP, index, MAC2STR(key));	res = miniport_set_info(wnd, OID_802_11_ADD_WEP, &ndis_key,				sizeof(ndis_key));	if (res) {		WARNING("adding encryption key %d failed (%08X)",			index+1, res);		EXIT2(return -EINVAL);	}	/* Atheros driver messes up ndis_key during ADD_WEP, so	 * don't rely on that; instead use info in key and key_len */	wnd->encr_info.keys[index].length = key_len;	memcpy(&wnd->encr_info.keys[index].key, key, key_len);	EXIT2(return 0);}/* remove_key is for both wep and wpa */static int remove_key(struct wrap_ndis_device *wnd, int index,		      mac_address bssid){	NDIS_STATUS res;	if (wnd->encr_info.keys[index].length == 0)		EXIT2(return 0);	wnd->encr_info.keys[index].length = 0;	memset(&wnd->encr_info.keys[index].key, 0,	       sizeof(wnd->encr_info.keys[index].length));	if (wnd->encr_mode == Ndis802_11Encryption2Enabled ||	    wnd->encr_mode == Ndis802_11Encryption3Enabled) {		struct ndis_remove_key remove_key;		remove_key.struct_size = sizeof(remove_key);		remove_key.index = index;		if (bssid) {			/* pairwise key */			if (memcmp(bssid, "\xff\xff\xff\xff\xff\xff",				   ETH_ALEN) != 0)				remove_key.index |= (1 << 30);			memcpy(remove_key.bssid, bssid,			       sizeof(remove_key.bssid));		} else			memset(remove_key.bssid, 0xff,			       sizeof(remove_key.bssid));		if (miniport_set_info(wnd, OID_802_11_REMOVE_KEY,				      (char *)&remove_key, sizeof(remove_key)))			EXIT2(return -EINVAL);	} else {		ndis_key_index keyindex = index;		res = miniport_set_int(wnd, OID_802_11_REMOVE_WEP, keyindex);		if (res) {			WARNING("removing encryption key %d failed (%08X)",				keyindex, res);			EXIT2(return -EINVAL);		}	}	/* if it is transmit key, disable encryption */	if (index == wnd->encr_info.tx_key_index) {		res = set_encr_mode(wnd, Ndis802_11EncryptionDisabled);		if (res)			WARNING("changing encr status failed (%08X)", res);	}	TRACE2("key %d removed", index);	EXIT2(return 0);}static int iw_set_wep(struct net_device *dev, struct iw_request_info *info,		      union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	NDIS_STATUS res;	unsigned int index, key_len;	struct encr_info *encr_info = &wnd->encr_info;	unsigned char *key;	ENTER2("");	index = (wrqu->encoding.flags & IW_ENCODE_INDEX);	TRACE2("index = %u", index);	/* iwconfig gives index as 1 - N */	if (index > 0)		index--;	else		index = encr_info->tx_key_index;	if (index < 0 || index >= MAX_ENCR_KEYS) {		WARNING("encryption index out of range (%u)", index);		EXIT2(return -EINVAL);	}	/* remove key if disabled */	if (wrqu->data.flags & IW_ENCODE_DISABLED) {		if (remove_key(wnd, index, NULL))			EXIT2(return -EINVAL);		else			EXIT2(return 0);	}	/* global encryption state (for all keys) */	if (wrqu->data.flags & IW_ENCODE_OPEN)		res = set_auth_mode(wnd, Ndis802_11AuthModeOpen);	else // if (wrqu->data.flags & IW_ENCODE_RESTRICTED)		res = set_auth_mode(wnd, Ndis802_11AuthModeShared);	if (res) {		WARNING("setting authentication mode failed (%08X)", res);		EXIT2(return -EINVAL);	}	TRACE2("key length: %d", wrqu->data.length);	if (wrqu->data.length > 0) {		key_len = wrqu->data.length;		key = extra;	} else { // must be set as tx key		if (encr_info->keys[index].length == 0) {			WARNING("key %d is not set", index+1);			EXIT2(return -EINVAL);		}		key_len = encr_info->keys[index].length;		key = encr_info->keys[index].key;		encr_info->tx_key_index = index;	}	if (add_wep_key(wnd, key, key_len, index))		EXIT2(return -EINVAL);	if (index == encr_info->tx_key_index) {		/* if transmit key is at index other than 0, some		 * drivers, at least Atheros and TI, want another		 * (global) non-transmit key to be set; don't know why */

⌨️ 快捷键说明

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