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

📄 iw_ndis.c

📁 ndis在linux下的无线网卡驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	struct wrap_ndis_device *wnd = netdev_priv(dev);	enum network_type network_type;	NDIS_STATUS res;	char type;	ENTER2("");	type = wrqu->param.value;	if (type == 'f')		network_type = Ndis802_11FH;	else if (type == 'b')		network_type = Ndis802_11DS;	else if (type == 'a')		network_type = Ndis802_11OFDM5;	else if (type == 'g' || type == 'n')		network_type = Ndis802_11OFDM24;	else		network_type = Ndis802_11Automode;	res = miniport_set_int(wnd, OID_802_11_NETWORK_TYPE_IN_USE,			       network_type);	if (res) {		WARNING("setting network type to %d failed (%08X)",			network_type, res);		EXIT2(return -EINVAL);	}	EXIT2(return 0);}static int priv_media_stream_mode(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;	int mode;	ENTER2("");	if (wrqu->param.value > 0)		mode = Ndis802_11MediaStreamOn;	else		mode = Ndis802_11MediaStreamOff;	res = miniport_set_int(wnd, OID_802_11_MEDIA_STREAM_MODE, mode);	if (res) {		WARNING("oid failed (%08X)", res);		EXIT2(return -EINVAL);	}	EXIT2(return 0);}static int priv_set_encr_mode(struct net_device *dev,			      struct iw_request_info *info,			      union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	int res;	ENTER2("");	res = set_encr_mode(wnd, wrqu->param.value);	if (res < 0)		EXIT2(return -1);	EXIT2(return 0);}static int priv_set_auth_mode(struct net_device *dev,			      struct iw_request_info *info,			      union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	int res;	ENTER2("");	res = set_auth_mode(wnd, wrqu->param.value);	if (res < 0)		EXIT2(return -1);	EXIT2(return 0);}static int priv_reload_defaults(struct net_device *dev,				struct iw_request_info *info,				union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	int res;	ENTER2("");	res = miniport_set_int(wnd, OID_802_11_RELOAD_DEFAULTS,			       Ndis802_11ReloadWEPKeys);	if (res) {		WARNING("reloading defaults failed: %08X", res);		return -EOPNOTSUPP;	}	return 0;}#if WIRELESS_EXT <= 17/* WPA support through 'ndiswrapper' driver interface */static int wpa_init(struct net_device *dev, struct iw_request_info *info,		    union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	ENTER2("");	if (test_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr) ||	    test_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr) ||	    test_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr))		EXIT2(return 0);	else {		WARNING("driver is not WEP/WPA capable");		EXIT2(return -1);	}}static int wpa_deinit(struct net_device *dev, struct iw_request_info *info,		      union iwreq_data *wrqu, char *extra){	ENTER2("");	EXIT2(return 0);}static int wpa_set_wpa(struct net_device *dev, struct iw_request_info *info,		       union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	ENTER2("flags = %d,  wnd->capa.encr = %ld",		    wrqu->data.flags, wnd->capa.encr);	if (wrqu->data.flags) {		if (test_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr) ||		    test_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr))			EXIT2(return 0);		else {			WARNING("driver is not WPA capable");			EXIT2(return -1);		}	} else		EXIT2(return 0);}static int wpa_set_key(struct net_device *dev, struct iw_request_info *info,		       union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	struct ndis_add_key ndis_key;	struct wpa_key wpa_key;	int i, size;	NDIS_STATUS res;	mac_address addr;	u8 seq[IW_ENCODING_TOKEN_MAX];	u8 key[IW_ENCODING_TOKEN_MAX];	ENTER2("");	if (wrqu->data.length)		size = wrqu->data.length;	else		size = sizeof(wpa_key);	if (copy_from_user(&wpa_key, wrqu->data.pointer, size))		EXIT2(return -EFAULT);	if (wpa_key.addr && copy_from_user(&addr, wpa_key.addr, ETH_ALEN))		EXIT2(return -EFAULT);	if (wpa_key.seq && copy_from_user(&seq, wpa_key.seq, wpa_key.seq_len))		EXIT2(return -EFAULT);	if (wpa_key.key && copy_from_user(&key, wpa_key.key, wpa_key.key_len))		EXIT2(return -EFAULT);	TRACE2("alg = %d, key_index = %d", wpa_key.alg, wpa_key.key_index);	if (wpa_key.alg == WPA_ALG_WEP) {		if (!test_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr))			EXIT2(return -1);		if (wpa_key.set_tx)			wnd->encr_info.tx_key_index = wpa_key.key_index;		if (add_wep_key(wnd, key, wpa_key.key_len, wpa_key.key_index))			EXIT2(return -1);		else			EXIT2(return 0);	}	if (wpa_key.key_len > sizeof(ndis_key.key)) {		TRACE2("incorrect key length (%u)", (u32)wpa_key.key_len);		EXIT2(return -1);	}	if (wpa_key.seq_len > IW_ENCODING_TOKEN_MAX) {		TRACE2("incorrect seq? length = (%u)", (u32)wpa_key.seq_len);		EXIT2(return -1);	}	TRACE2("setting key %d, %u", wpa_key.key_index, (u32)wpa_key.key_len);	memset(&ndis_key, 0, sizeof(ndis_key));	ndis_key.struct_size =		sizeof(ndis_key) - sizeof(ndis_key.key) + wpa_key.key_len;	ndis_key.length = wpa_key.key_len;	ndis_key.index = wpa_key.key_index;	if (wpa_key.seq && wpa_key.seq_len > 0) {		for (i = 0, ndis_key.rsc = 0 ; i < wpa_key.seq_len ; i++)			ndis_key.rsc |= (seq[i] << (i * 8));		ndis_key.index |= 1 << 29;	}	TRACE2("infra_mode = %d, key.addr = %p, addr = " MACSTRSEP,	       wnd->infrastructure_mode, wpa_key.addr, MAC2STR(addr));	if (wpa_key.addr == NULL ||	    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 (wpa_key.set_tx)		ndis_key.index |= (1 << 31);	if (wpa_key.alg == WPA_ALG_TKIP && wpa_key.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, wpa_key.key_len);	if (wpa_key.alg == WPA_ALG_NONE || wpa_key.key_len == 0) {		/* TI driver crashes kernel if OID_802_11_REMOVE_KEY is		 * called; other drivers seem to not require it, so		 * for now, don't remove the key from drvier */		wnd->encr_info.keys[wpa_key.key_index].length = 0;		memset(&wnd->encr_info.keys[wpa_key.key_index].key, 0,		       wpa_key.key_len);		TRACE2("key %d removed", wpa_key.key_index);	} else {		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[wpa_key.key_index].length =			wpa_key.key_len;		memcpy(&wnd->encr_info.keys[wpa_key.key_index].key,		       &ndis_key.key, wpa_key.key_len);		if (wpa_key.set_tx)			wnd->encr_info.tx_key_index = wpa_key.key_index;		TRACE2("key %d added", wpa_key.key_index);	}	EXIT2(return 0);}static int wpa_disassociate(struct net_device *dev,			    struct iw_request_info *info,			    union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	disassociate(wnd, 1);	EXIT2(return 0);}static int wpa_associate(struct net_device *dev, struct iw_request_info *info,			 union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	struct wpa_assoc_info wpa_assoc_info;	char ssid[NDIS_ESSID_MAX_SIZE];	int infra_mode, auth_mode, encr_mode, priv_mode, size;	ENTER2("");	memset(&wpa_assoc_info, 0, sizeof(wpa_assoc_info));	wpa_assoc_info.mode = IEEE80211_MODE_INFRA;	if (wrqu->data.length == 0)		size = (void *)&wpa_assoc_info.auth_alg -			(void *)&wpa_assoc_info.bssid;	else		size = min((size_t)wrqu->data.length, sizeof(wpa_assoc_info));	if (copy_from_user(&wpa_assoc_info, wrqu->data.pointer, size))		EXIT2(return -EFAULT);	if (copy_from_user(&ssid, wpa_assoc_info.ssid,			   wpa_assoc_info.ssid_len))		EXIT2(return -EFAULT);	if (wpa_assoc_info.mode == IEEE80211_MODE_IBSS)		infra_mode = Ndis802_11IBSS;	else		infra_mode = Ndis802_11Infrastructure;	TRACE2("key_mgmt_suite = %d, pairwise_suite = %d, group_suite= %d",	       wpa_assoc_info.key_mgmt_suite, wpa_assoc_info.pairwise_suite,	       wpa_assoc_info.group_suite);	if (wpa_assoc_info.wpa_ie == NULL || wpa_assoc_info.wpa_ie_len == 0) {		if (wpa_assoc_info.auth_alg & AUTH_ALG_SHARED_KEY) {			if (wpa_assoc_info.auth_alg & AUTH_ALG_OPEN_SYSTEM)				auth_mode = Ndis802_11AuthModeAutoSwitch;			else				auth_mode = Ndis802_11AuthModeShared;		} else			auth_mode = Ndis802_11AuthModeOpen;		priv_mode = Ndis802_11PrivFilterAcceptAll;	} else if (wpa_assoc_info.wpa_ie[0] == RSN_INFO_ELEM) {		priv_mode = Ndis802_11PrivFilter8021xWEP;		if (wpa_assoc_info.key_mgmt_suite == KEY_MGMT_PSK)			auth_mode = Ndis802_11AuthModeWPA2PSK;		else			auth_mode = Ndis802_11AuthModeWPA2;	} else {		priv_mode = Ndis802_11PrivFilter8021xWEP;		if (wpa_assoc_info.key_mgmt_suite == KEY_MGMT_WPA_NONE ||		    wpa_assoc_info.key_mgmt_suite == KEY_MGMT_802_1X_NO_WPA)			auth_mode = Ndis802_11AuthModeWPANone;		else if (wpa_assoc_info.key_mgmt_suite == KEY_MGMT_PSK)			auth_mode = Ndis802_11AuthModeWPAPSK;		else			auth_mode = Ndis802_11AuthModeWPA;	}	switch (wpa_assoc_info.pairwise_suite) {	case CIPHER_CCMP:		encr_mode = Ndis802_11Encryption3Enabled;		break;	case CIPHER_TKIP:		encr_mode = Ndis802_11Encryption2Enabled;		break;	case CIPHER_WEP40:	case CIPHER_WEP104:		encr_mode = Ndis802_11Encryption1Enabled;		break;	case CIPHER_NONE:		if (wpa_assoc_info.group_suite == CIPHER_CCMP)			encr_mode = Ndis802_11Encryption3Enabled;		else if (wpa_assoc_info.group_suite == CIPHER_TKIP)			encr_mode = Ndis802_11Encryption2Enabled;		else			encr_mode = Ndis802_11EncryptionDisabled;		break;	default:		encr_mode = Ndis802_11EncryptionDisabled;	};	set_infra_mode(wnd, infra_mode);	set_priv_filter(wnd, priv_mode);	set_auth_mode(wnd, auth_mode);	set_encr_mode(wnd, encr_mode);#if 0	/* set channel */	for (i = 0; i < (sizeof(freq_chan)/sizeof(freq_chan[0])); i++) {		if (wpa_assoc_info.freq == freq_chan[i]) {			union iwreq_data freq_req;			memset(&freq_req, 0, sizeof(freq_req));			freq_req.freq.m = i;			if (iw_set_freq(dev, NULL, &freq_req, NULL))				EXIT2(return -1);		}	}#endif	/* set ssid */	if (set_essid(wnd, ssid, wpa_assoc_info.ssid_len))		EXIT2(return -1);	EXIT2(return 0);}static int wpa_set_countermeasures(struct net_device *dev,				   struct iw_request_info *info,				   union iwreq_data *wrqu, char *extra){	ENTER2("");	return 0;}static int wpa_deauthenticate(struct net_device *dev,			      struct iw_request_info *info,			      union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	EXIT2(return deauthenticate(wnd));}static int wpa_set_priv_filter(struct net_device *dev,				  struct iw_request_info *info,				  union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	int flags;	ENTER2("filter: %d", wrqu->param.value);	if (wrqu->param.value)		flags = Ndis802_11PrivFilter8021xWEP;	else		flags = Ndis802_11PrivFilterAcceptAll;	if (set_priv_filter(wnd, flags))		EXIT2(return -1);	EXIT2(return 0);}static int wpa_set_auth_alg(struct net_device *dev,			    struct iw_request_info *info,			    union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	int mode;	ENTER2("");	if (wrqu->param.value & AUTH_ALG_SHARED_KEY)		mode = Ndis802_11AuthModeShared;	else if (wrqu->param.value & AUTH_ALG_OPEN_SYSTEM)		mode = Ndis802_11AuthModeOpen;	else		EXIT2(return -1);	TRACE2("%d", mode);	if (set_auth_mode(wnd, mode))		EXIT2(return -1);	EXIT2(return 0);}static int wpa_get_capa(struct net_device *dev, struct iw_request_info *info,			union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	struct wpa_driver_capa *drv_capa;	ENTER2("%p", wnd);	drv_capa = (struct wpa_driver_capa *)wrqu->data.pointer;	if (!drv_capa)		EXIT2(return -1);	drv_capa->key_mgmt = 0;	if (test_bit(Ndis802_11AuthModeWPA, &wnd->capa.auth))		drv_capa->key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA;	if (test_bit(Ndis802_11AuthModeWPAPSK, &wnd->capa.auth))		drv_capa->key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK;	if (test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth))		drv_capa->key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA2;	if (test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth))		drv_capa->key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK;	if (test_bit(Ndis802_11AuthModeWPANone, &wnd->capa.auth))		drv_capa->key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE;	drv_capa->enc = 0;	if (test_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr))		drv_capa->enc |= WPA_DRIVER_CAPA_ENC_WEP40 |			WPA_DRIVER_CAPA_ENC_WEP104;	if (test_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr))		drv_capa->enc |= WPA_DRIVER_CAPA_ENC_TKIP;	if (test_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr))		drv_capa->enc |= WPA_DRIVER_CAPA_ENC_CCMP;	/* TODO: how to check if LEAP is supported? */	drv_capa->auth = WPA_DRIVER_AUTH_OPEN | WPA_DRIVER_AUTH_SHARED;	drv_capa->flags = WPA_DRIVER_FLAGS_DRIVER_IE |		WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC;	EXIT2(return 0);}#endif // WIRELESS_EXT <= 17static const struct iw_priv_args priv_args[] = {#if WIRELESS_EXT <= 17	{W

⌨️ 快捷键说明

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