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

📄 iw_ndis.c

📁 ndis在linux下的无线网卡驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	}	if (res)		WARNING("getting bit rates failed: %08X", res);	else {		for (i = 0; i < n && range->num_bitrates < IW_MAX_BITRATES; i++)			if (rates_ex[i] & 0x80)				continue;			else if (rates_ex[i] & 0x7f) {				range->bitrate[range->num_bitrates] =					(rates_ex[i] & 0x7f) * 500000;				range->num_bitrates++;			}	}	range->num_channels = (sizeof(freq_chan)/sizeof(freq_chan[0]));	for (i = 0; i < (sizeof(freq_chan)/sizeof(freq_chan[0])) &&		    i < IW_MAX_FREQUENCIES; i++) {		range->freq[i].i = i + 1;		range->freq[i].m = freq_chan[i] * 100000;		range->freq[i].e = 1;	}	range->num_frequency = i;	range->min_rts = 0;	range->max_rts = 2347;	range->min_frag = 256;	range->max_frag = 2346;#if WIRELESS_EXT > 16	/* Event capability (kernel + driver) */	range->event_capa[0] = (IW_EVENT_CAPA_K_0 |				IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |				IW_EVENT_CAPA_MASK(SIOCGIWAP) |				IW_EVENT_CAPA_MASK(SIOCGIWSCAN));	range->event_capa[1] = IW_EVENT_CAPA_K_1;	range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVTXDROP) |				IW_EVENT_CAPA_MASK(IWEVCUSTOM) |				IW_EVENT_CAPA_MASK(IWEVREGISTERED) |				IW_EVENT_CAPA_MASK(IWEVEXPIRED));#endif /* WIRELESS_EXT > 16 */#if WIRELESS_EXT > 17	range->enc_capa = 0;	if (test_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr))		range->enc_capa |= IW_ENC_CAPA_CIPHER_TKIP;	if (test_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr))		range->enc_capa |= IW_ENC_CAPA_CIPHER_CCMP;	if (test_bit(Ndis802_11AuthModeWPA, &wnd->capa.auth) ||	    test_bit(Ndis802_11AuthModeWPAPSK, &wnd->capa.auth))		range->enc_capa |= IW_ENC_CAPA_WPA;	if (test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) ||	    test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth))		range->enc_capa |= IW_ENC_CAPA_WPA2;#endif /* WIRELESS_EXT > 17 */	return 0;}NDIS_STATUS disassociate(struct wrap_ndis_device *wnd, int reset_ssid){	NDIS_STATUS res;	u8 buf[NDIS_ESSID_MAX_SIZE];	int i;	TRACE2("");	res = miniport_set_info(wnd, OID_802_11_DISASSOCIATE, NULL, 0);	/* disassociate causes radio to be turned off; if reset_ssid	 * is given, set ssid to random to enable radio */	if (reset_ssid) {		get_random_bytes(buf, sizeof(buf));		for (i = 0; i < sizeof(buf); i++)			buf[i] = 'a' + (buf[i] % 26);		set_essid(wnd, buf, sizeof(buf));	}	return res;}static int deauthenticate(struct wrap_ndis_device *wnd){	int ret;	ENTER2("");	ret = disassociate(wnd, 1);	set_priv_filter(wnd, Ndis802_11PrivFilterAcceptAll);	set_auth_mode(wnd, Ndis802_11AuthModeOpen);	set_encr_mode(wnd, Ndis802_11EncryptionDisabled);	EXIT2(return ret);}int set_priv_filter(struct wrap_ndis_device *wnd, int flags){	NDIS_STATUS res;	ENTER2("filter: %d", flags);	res = miniport_set_int(wnd, OID_802_11_PRIVACY_FILTER, flags);	if (res)		TRACE2("setting privacy filter to %d failed (%08X)",		       flags, res);	EXIT2(return 0);}#if WIRELESS_EXT > 17static int iw_set_mlme(struct net_device *dev, struct iw_request_info *info,		       union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	struct iw_mlme *mlme = (struct iw_mlme *)extra;	ENTER2("");	switch (mlme->cmd) {	case IW_MLME_DEAUTH:		return deauthenticate(wnd);	case IW_MLME_DISASSOC:		TRACE2("cmd=%d reason_code=%d", mlme->cmd, mlme->reason_code);		return disassociate(wnd, 1);	default:		return -EOPNOTSUPP;	}	return 0;}static int iw_set_genie(struct net_device *dev,			struct iw_request_info *info,			union iwreq_data *wrqu, char *extra){	/*	 * NDIS drivers do not allow IEs to be configured; this is	 * done by the driver based on other configuration. Return 0	 * to avoid causing issues with user space programs that	 * expect this function to succeed.	 */	return 0;}static int iw_set_auth(struct net_device *dev,		       struct iw_request_info *info,		       union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	TRACE2("index=%d value=%d", wrqu->param.flags & IW_AUTH_INDEX,	       wrqu->param.value);	wnd->iw_auth_set = 1;	switch (wrqu->param.flags & IW_AUTH_INDEX) {	case IW_AUTH_WPA_VERSION:		wnd->iw_auth_wpa_version = wrqu->param.value;		break;	case IW_AUTH_CIPHER_PAIRWISE:		wnd->iw_auth_cipher_pairwise = wrqu->param.value;		break;	case IW_AUTH_CIPHER_GROUP:		wnd->iw_auth_cipher_group = wrqu->param.value;		break;	case IW_AUTH_KEY_MGMT:		wnd->iw_auth_key_mgmt = wrqu->param.value;		break;	case IW_AUTH_80211_AUTH_ALG:		wnd->iw_auth_80211_auth_alg = wrqu->param.value;		break;	case IW_AUTH_WPA_ENABLED:	case IW_AUTH_TKIP_COUNTERMEASURES:	case IW_AUTH_DROP_UNENCRYPTED:	case IW_AUTH_RX_UNENCRYPTED_EAPOL:	case IW_AUTH_PRIVACY_INVOKED:		TRACE2("%d not implemented", wrqu->param.flags & IW_AUTH_INDEX);		/* TODO */		break;	default:		WARNING("invalid cmd %d", wrqu->param.flags & IW_AUTH_INDEX);		return -EOPNOTSUPP;	}	return 0;}static int iw_get_auth(struct net_device *dev,		       struct iw_request_info *info,		       union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	ENTER2("index=%d", wrqu->param.flags & IW_AUTH_INDEX);	switch (wrqu->param.flags & IW_AUTH_INDEX) {	case IW_AUTH_WPA_VERSION:		wrqu->param.value = wnd->iw_auth_wpa_version;		break;	case IW_AUTH_CIPHER_PAIRWISE:		wrqu->param.value = wnd->iw_auth_cipher_pairwise;		break;	case IW_AUTH_CIPHER_GROUP:		wrqu->param.value = wnd->iw_auth_cipher_group;		break;	case IW_AUTH_KEY_MGMT:		wrqu->param.value = wnd->iw_auth_key_mgmt;		break;	case IW_AUTH_80211_AUTH_ALG:		wrqu->param.value = wnd->iw_auth_80211_auth_alg;		break;	default:		WARNING("invalid cmd %d", wrqu->param.flags & IW_AUTH_INDEX);		return -EOPNOTSUPP;	}	return 0;}static int iw_set_encodeext(struct net_device *dev,			    struct iw_request_info *info,			    union iwreq_data *wrqu, char *extra){	struct iw_encode_ext ext;	struct wrap_ndis_device *wnd = netdev_priv(dev);	struct ndis_add_key ndis_key;	int i, keyidx;	NDIS_STATUS res;	u8 *addr;	u8 key[IW_ENCODING_TOKEN_MAX];	ENTER2("");	keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX;	if (keyidx > 0)		keyidx--;	else		keyidx = wnd->encr_info.tx_key_index;	if (keyidx < 0 || keyidx >= MAX_ENCR_KEYS)		return -EINVAL;	if (copy_from_user(&ext, wrqu->encoding.pointer, sizeof(ext)))		EXIT2(return -EFAULT);	if (copy_from_user(key, wrqu->encoding.pointer + sizeof(ext),			   ext.key_len))		EXIT2(return -EFAULT);	if (ext.alg == WPA_ALG_WEP) {		if (!test_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr))			EXIT2(return -1);		if (ext.ext_flags & IW_ENCODE_EXT_SET_TX_KEY)			wnd->encr_info.tx_key_index = keyidx;		if (add_wep_key(wnd, key, ext.key_len, keyidx))			EXIT2(return -1);		else			EXIT2(return 0);	}	if ((wrqu->encoding.flags & IW_ENCODE_DISABLED) ||	    ext.alg == IW_ENCODE_ALG_NONE || ext.key_len == 0)		EXIT2(return remove_key(wnd, keyidx, ndis_key.bssid));	if (ext.key_len > sizeof(ndis_key.key)) {		TRACE2("incorrect key length (%u)", ext.key_len);		EXIT2(return -1);	}	memset(&ndis_key, 0, sizeof(ndis_key));	ndis_key.struct_size =		sizeof(ndis_key) - sizeof(ndis_key.key) + ext.key_len;	ndis_key.length = ext.key_len;	ndis_key.index = keyidx;	if (ext.ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {		for (i = ndis_key.rsc = 0 ; i < 6 ; i++)			ndis_key.rsc |= (ext.rx_seq[i] << (i * 8));		ndis_key.index |= 1 << 29;	}	addr = ext.addr.sa_data;	TRACE2("infra_mode = %d, addr = " MACSTRSEP,	       wnd->infrastructure_mode, MAC2STR(addr));	if (memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0) {		/* group key */		if (wnd->infrastructure_mode == Ndis802_11IBSS)			memset(ndis_key.bssid, 0xff, ETH_ALEN);		else			get_ap_address(wnd, ndis_key.bssid);	} else {		/* pairwise key */		ndis_key.index |= (1 << 30);		memcpy(&ndis_key.bssid, addr, ETH_ALEN);	}	TRACE2("bssid " MACSTRSEP, MAC2STR(ndis_key.bssid));	if (ext.ext_flags & IW_ENCODE_EXT_SET_TX_KEY)		ndis_key.index |= (1 << 31);	if (ext.alg == IW_ENCODE_ALG_TKIP && ext.key_len == 32) {		/* wpa_supplicant gives us the Michael MIC RX/TX keys in		 * different order than NDIS spec, so swap the order here. */		memcpy(ndis_key.key, key, 16);		memcpy(ndis_key.key + 16, key + 24, 8);		memcpy(ndis_key.key + 24, key + 16, 8);	} else		memcpy(ndis_key.key, key, ext.key_len);	res = miniport_set_info(wnd, OID_802_11_ADD_KEY,				&ndis_key, ndis_key.struct_size);	if (res) {		TRACE2("adding key failed (%08X), %u",		       res, ndis_key.struct_size);		EXIT2(return -1);	}	wnd->encr_info.keys[keyidx].length = ext.key_len;	memcpy(&wnd->encr_info.keys[keyidx].key,	       &ndis_key.key, ext.key_len);	if (ext.ext_flags & IW_ENCODE_EXT_SET_TX_KEY)		wnd->encr_info.tx_key_index = keyidx;	TRACE2("key %d added", keyidx);	EXIT2(return 0);}static int iw_get_encodeext(struct net_device *dev,			    struct iw_request_info *info,			    union iwreq_data *wrqu, char *extra){	/* struct iw_encode_ext *ext = (struct iw_encode_ext *) extra; */	/* TODO */	ENTER2("");	return 0;}static int iw_set_pmksa(struct net_device *dev, struct iw_request_info *info,			union iwreq_data *wrqu, char *extra){	struct iw_pmksa *pmksa = (struct iw_pmksa *) extra;	struct ndis_pmkid pmkid;	NDIS_STATUS res;	struct wrap_ndis_device *wnd = netdev_priv(dev);	/* TODO: must keep local list of PMKIDs since NDIS drivers	 * expect that all PMKID entries are included whenever a new	 * one is added. */	ENTER2("");	if (wnd->auth_mode != Ndis802_11AuthModeWPA2)		return -EOPNOTSUPP;	memset(&pmkid, 0, sizeof(pmkid));	if (pmksa->cmd == IW_PMKSA_ADD) {		pmkid.bssid_info_count = 1;		memcpy(pmkid.bssid_info[0].bssid, pmksa->bssid.sa_data,		       ETH_ALEN);		memcpy(pmkid.bssid_info[0].pmkid, pmksa->pmkid, IW_PMKID_LEN);	}	pmkid.length = 8 + pmkid.bssid_info_count *		sizeof(struct ndis_bssid_info);	res = miniport_set_info(wnd, OID_802_11_PMKID, &pmkid, sizeof(pmkid));	if (res == NDIS_STATUS_FAILURE)		return -EOPNOTSUPP;	TRACE2("OID_802_11_PMKID -> %d", res);	if (res)		return -EINVAL;	return 0;}#endif /* WIRELESS_EXT > 17 */static const iw_handler	ndis_handler[] = {	[SIOCGIWNAME	- SIOCIWFIRST] = iw_get_network_type,	[SIOCSIWESSID	- SIOCIWFIRST] = iw_set_essid,	[SIOCGIWESSID	- SIOCIWFIRST] = iw_get_essid,	[SIOCSIWMODE	- SIOCIWFIRST] = iw_set_infra_mode,	[SIOCGIWMODE	- SIOCIWFIRST] = iw_get_infra_mode,	[SIOCGIWFREQ	- SIOCIWFIRST] = iw_get_freq,	[SIOCSIWFREQ	- SIOCIWFIRST] = iw_set_freq,	[SIOCGIWTXPOW	- SIOCIWFIRST] = iw_get_tx_power,	[SIOCSIWTXPOW	- SIOCIWFIRST] = iw_set_tx_power,	[SIOCGIWRATE	- SIOCIWFIRST] = iw_get_bitrate,	[SIOCSIWRATE	- SIOCIWFIRST] = iw_set_bitrate,	[SIOCGIWRTS	- SIOCIWFIRST] = iw_get_rts_threshold,	[SIOCSIWRTS	- SIOCIWFIRST] = iw_set_rts_threshold,	[SIOCGIWFRAG	- SIOCIWFIRST] = iw_get_frag_threshold,	[SIOCSIWFRAG	- SIOCIWFIRST] = iw_set_frag_threshold,	[SIOCGIWAP	- SIOCIWFIRST] = iw_get_ap_address,	[SIOCSIWAP	- SIOCIWFIRST] = iw_set_ap_address,	[SIOCSIWENCODE	- SIOCIWFIRST] = iw_set_wep,	[SIOCGIWENCODE	- SIOCIWFIRST] = iw_get_encr,	[SIOCSIWSCAN	- SIOCIWFIRST] = iw_set_scan,	[SIOCGIWSCAN	- SIOCIWFIRST] = iw_get_scan,	[SIOCGIWPOWER	- SIOCIWFIRST] = iw_get_power_mode,	[SIOCSIWPOWER	- SIOCIWFIRST] = iw_set_power_mode,	[SIOCGIWRANGE	- SIOCIWFIRST] = iw_get_range,	[SIOCGIWSTATS	- SIOCIWFIRST] = iw_get_ndis_stats,	[SIOCGIWSENS	- SIOCIWFIRST] = iw_get_sensitivity,	[SIOCSIWSENS	- SIOCIWFIRST] = iw_set_sensitivity,	[SIOCGIWNICKN	- SIOCIWFIRST] = iw_get_nick,	[SIOCSIWNICKN	- SIOCIWFIRST] = iw_set_nick,	[SIOCSIWCOMMIT	- SIOCIWFIRST] = iw_set_dummy,#if WIRELESS_EXT > 17	[SIOCSIWMLME	- SIOCIWFIRST] = iw_set_mlme,	[SIOCSIWGENIE	- SIOCIWFIRST] = iw_set_genie,	[SIOCSIWAUTH	- SIOCIWFIRST] = iw_set_auth,	[SIOCGIWAUTH	- SIOCIWFIRST] = iw_get_auth,	[SIOCSIWENCODEEXT - SIOCIWFIRST] = iw_set_encodeext,	[SIOCGIWENCODEEXT - SIOCIWFIRST] = iw_get_encodeext,	[SIOCSIWPMKSA	- SIOCIWFIRST] = iw_set_pmksa,#endif /* WIRELESS_EXT > 17 */};/* private ioctl's */static int priv_reset(struct net_device *dev, struct iw_request_info *info,		      union iwreq_data *wrqu, char *extra){	int res;	ENTER2("");	res = miniport_reset(netdev_priv(dev));	if (res) {		WARNING("reset failed: %08X", res);		return -EOPNOTSUPP;	}	return 0;}static int priv_usb_reset(struct net_device *dev, struct iw_request_info *info,			  union iwreq_data *wrqu, char *extra){	int res;	struct wrap_ndis_device *wnd;	ENTER2("");	wnd = netdev_priv(dev);	res = 0;#if defined(CONFIG_USB) && LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)	res = usb_reset_configuration(wnd->wd->usb.udev);	if (res) {		WARNING("reset failed: %08X", res);		return -EOPNOTSUPP;	}#endif	return 0;}static int priv_power_profile(struct net_device *dev,			      struct iw_request_info *info,			      union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	struct miniport_char *miniport;	ULONG profile_inf;	ENTER2("");	miniport = &wnd->wd->driver->ndis_driver->miniport;	if (!miniport->pnp_event_notify)		EXIT2(return -EOPNOTSUPP);	/* 1 for AC and 0 for Battery */	if (wrqu->param.value)		profile_inf = NdisPowerProfileAcOnLine;	else		profile_inf = NdisPowerProfileBattery;	LIN2WIN4(miniport->pnp_event_notify, wnd->nmb->adapter_ctx,		 NdisDevicePnPEventPowerProfileChanged,		 &profile_inf, sizeof(profile_inf));	EXIT2(return 0);}static int priv_network_type(struct net_device *dev,			     struct iw_request_info *info,			     union iwreq_data *wrqu, char *extra){

⌨️ 快捷键说明

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