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

📄 iw_ndis.c

📁 ndis在linux下的无线网卡驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		if (index != 0) {			int i;			for (i = 0; i < MAX_ENCR_KEYS; i++)				if (i != index &&				    encr_info->keys[i].length != 0)					break;			if (i == MAX_ENCR_KEYS) {				if (index == 0)					i = index + 1;				else					i = index - 1;				if (add_wep_key(wnd, key, key_len, i))					WARNING("couldn't add broadcast key"						" at %d", i);			}		}		/* ndis drivers want essid to be set after setting encr */		set_essid(wnd, wnd->essid.essid, wnd->essid.length);	}	EXIT2(return 0);}static int iw_set_nick(struct net_device *dev, struct iw_request_info *info,		       union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	if (wrqu->data.length > IW_ESSID_MAX_SIZE || wrqu->data.length <= 0)		return -EINVAL;	memcpy(wnd->nick, extra, wrqu->data.length);	wnd->nick[wrqu->data.length-1] = 0;	return 0;}static int iw_get_nick(struct net_device *dev, struct iw_request_info *info,		       union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	wrqu->data.length = strlen(wnd->nick);	memcpy(extra, wnd->nick, wrqu->data.length);	return 0;}static char *ndis_translate_scan(struct net_device *dev, char *event,				 char *end_buf, void *item){	struct iw_event iwe;	char *current_val;	int i, nrates;	unsigned char buf[MAX_WPA_IE_LEN * 2 + 30];	struct ndis_wlan_bssid *bssid;	struct ndis_wlan_bssid_ex *bssid_ex;	ENTER2("%p, %p", event, item);	bssid = item;	bssid_ex = item;	/* add mac address */	memset(&iwe, 0, sizeof(iwe));	iwe.cmd = SIOCGIWAP;	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;	iwe.len = IW_EV_ADDR_LEN;	memcpy(iwe.u.ap_addr.sa_data, bssid->mac, ETH_ALEN);	event = iwe_stream_add_event(event, end_buf, &iwe, IW_EV_ADDR_LEN);	/* add essid */	memset(&iwe, 0, sizeof(iwe));	iwe.cmd = SIOCGIWESSID;	iwe.u.data.length = bssid->ssid.length;	if (iwe.u.data.length > IW_ESSID_MAX_SIZE)		iwe.u.data.length = IW_ESSID_MAX_SIZE;	iwe.u.data.flags = 1;	iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;	event = iwe_stream_add_point(event, end_buf, &iwe, bssid->ssid.essid);	/* add protocol name */	memset(&iwe, 0, sizeof(iwe));	iwe.cmd = SIOCGIWNAME;	strncpy(iwe.u.name, network_type_to_name(bssid->net_type), IFNAMSIZ);	event = iwe_stream_add_event(event, end_buf, &iwe, IW_EV_CHAR_LEN);	/* add mode */	memset(&iwe, 0, sizeof(iwe));	iwe.cmd = SIOCGIWMODE;	if (bssid->mode == Ndis802_11IBSS)		iwe.u.mode = IW_MODE_ADHOC;	else if (bssid->mode == Ndis802_11Infrastructure)		iwe.u.mode = IW_MODE_INFRA;	else // if (bssid->mode == Ndis802_11AutoUnknown)		iwe.u.mode = IW_MODE_AUTO;	event = iwe_stream_add_event(event, end_buf, &iwe, IW_EV_UINT_LEN);	/* add freq */	memset(&iwe, 0, sizeof(iwe));	iwe.cmd = SIOCGIWFREQ;	iwe.u.freq.m = bssid->config.ds_config;	if (bssid->config.ds_config > 1000000) {		iwe.u.freq.m = bssid->config.ds_config / 10;		iwe.u.freq.e = 1;	}	else		iwe.u.freq.m = bssid->config.ds_config;	/* convert from kHz to Hz */	iwe.u.freq.e += 3;	iwe.len = IW_EV_FREQ_LEN;	event = iwe_stream_add_event(event, end_buf, &iwe, IW_EV_FREQ_LEN);	/* add qual */	memset(&iwe, 0, sizeof(iwe));	iwe.cmd = IWEVQUAL;	i = 100 * (bssid->rssi - WL_NOISE) / (WL_SIGMAX - WL_NOISE);	if (i < 0)		i = 0;	else if (i > 100)		i = 100;	iwe.u.qual.level = bssid->rssi;	iwe.u.qual.noise = WL_NOISE;	iwe.u.qual.qual  = i;	iwe.len = IW_EV_QUAL_LEN;	event = iwe_stream_add_event(event, end_buf, &iwe, IW_EV_QUAL_LEN);	/* add key info */	memset(&iwe, 0, sizeof(iwe));	iwe.cmd = SIOCGIWENCODE;	if (bssid->privacy == Ndis802_11PrivFilterAcceptAll)		iwe.u.data.flags = IW_ENCODE_DISABLED;	else		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;	iwe.u.data.length = 0;	iwe.len = IW_EV_POINT_LEN;	event = iwe_stream_add_point(event, end_buf, &iwe, bssid->ssid.essid);	/* add rate */	memset(&iwe, 0, sizeof(iwe));	current_val = event + IW_EV_LCP_LEN;	iwe.cmd = SIOCGIWRATE;	if (bssid->length > sizeof(*bssid))		nrates = NDIS_MAX_RATES_EX;	else		nrates = NDIS_MAX_RATES;	for (i = 0 ; i < nrates ; i++) {		if (bssid->rates[i] & 0x7f) {			iwe.u.bitrate.value = ((bssid->rates[i] & 0x7f) *					       500000);			current_val = iwe_stream_add_value(event, current_val,							   end_buf, &iwe,							   IW_EV_PARAM_LEN);		}	}	if ((current_val - event) > IW_EV_LCP_LEN)		event = current_val;	memset(&iwe, 0, sizeof(iwe));	iwe.cmd = IWEVCUSTOM;	sprintf(buf, "bcn_int=%d", bssid->config.beacon_period);	iwe.u.data.length = strlen(buf);	event = iwe_stream_add_point(event, end_buf, &iwe, buf);	memset(&iwe, 0, sizeof(iwe));	iwe.cmd = IWEVCUSTOM;	sprintf(buf, "atim=%u", bssid->config.atim_window);	iwe.u.data.length = strlen(buf);	event = iwe_stream_add_point(event, end_buf, &iwe, buf);	TRACE2("%d, %u", bssid->length, (unsigned int)sizeof(*bssid));	if (bssid->length > sizeof(*bssid)) {		unsigned char *iep = (unsigned char *)bssid_ex->ies +			sizeof(struct ndis_fixed_ies);		no_warn_unused unsigned char *end = iep + bssid_ex->ie_length;		while (iep + 1 < end && iep + 2 + iep[1] <= end) {			unsigned char ielen = 2 + iep[1];			if (ielen > SSID_MAX_WPA_IE_LEN) {				iep += ielen;				continue;			}#if WIRELESS_EXT > 17			if ((iep[0] == WLAN_EID_GENERIC && iep[1] >= 4 &&			     memcmp(iep + 2, "\x00\x50\xf2\x01", 4) == 0) ||			    iep[0] == RSN_INFO_ELEM) {				memset(&iwe, 0, sizeof(iwe));				iwe.cmd = IWEVGENIE;				iwe.u.data.length = ielen;				event = iwe_stream_add_point(event, end_buf,							     &iwe, iep);			}#else			if (iep[0] == WLAN_EID_GENERIC && iep[1] >= 4 &&			    memcmp(iep + 2, "\x00\x50\xf2\x01", 4) == 0) {				unsigned char *p = buf;				p += sprintf(p, "wpa_ie=");				for (i = 0; i < ielen; i++)					p += sprintf(p, "%02x", iep[i]);				TRACE2("adding wpa_ie :%lu",				       (unsigned long)strlen(buf));				memset(&iwe, 0, sizeof(iwe));				iwe.cmd = IWEVCUSTOM;				iwe.u.data.length = strlen(buf);				event = iwe_stream_add_point(event, end_buf,							     &iwe, buf);			} else if (iep[0] == RSN_INFO_ELEM) {				unsigned char *p = buf;				p += sprintf(p, "rsn_ie=");				for (i = 0; i < ielen; i++)					p += sprintf(p, "%02x", iep[i]);				TRACE2("adding rsn_ie :%lu",				       (unsigned long)strlen(buf));				memset(&iwe, 0, sizeof(iwe));				iwe.cmd = IWEVCUSTOM;				iwe.u.data.length = strlen(buf);				event = iwe_stream_add_point(event, end_buf,							     &iwe, buf);			}#endif			iep += ielen;		}	}	TRACE2("event = %p, current_val = %p", event, current_val);	EXIT2(return event);}int set_scan(struct wrap_ndis_device *wnd){	NDIS_STATUS res;	ENTER2("");	res = miniport_set_info(wnd, OID_802_11_BSSID_LIST_SCAN, NULL, 0);	if (res) {		WARNING("scanning failed (%08X)", res);		EXIT2(return -EOPNOTSUPP);	}	wnd->scan_timestamp = jiffies;	EXIT2(return 0);}static int iw_set_scan(struct net_device *dev, struct iw_request_info *info,		       union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	return set_scan(wnd);}static int iw_get_scan(struct net_device *dev, struct iw_request_info *info,		       union iwreq_data *wrqu, char *extra){	struct wrap_ndis_device *wnd = netdev_priv(dev);	unsigned int i, list_len, needed;	NDIS_STATUS res;	struct ndis_bssid_list *bssid_list = NULL;	char *event = extra;	struct ndis_wlan_bssid *cur_item ;	ENTER2("");	if (time_before(jiffies, wnd->scan_timestamp + 3 * HZ))		return -EAGAIN;	/* try with space for a few scan items */	list_len = sizeof(ULONG) + sizeof(struct ndis_wlan_bssid_ex) * 8;	bssid_list = kmalloc(list_len, GFP_KERNEL);	if (!bssid_list) {		ERROR("couldn't allocate memory");		return -ENOMEM;	}	/* some drivers don't set bssid_list->num_items to 0 if	   OID_802_11_BSSID_LIST returns no items (prism54 driver, e.g.,) */	memset(bssid_list, 0, list_len);	needed = 0;	res = miniport_query_info_needed(wnd, OID_802_11_BSSID_LIST,					 bssid_list, list_len, &needed);	if (res == NDIS_STATUS_INVALID_LENGTH ||	    res == NDIS_STATUS_BUFFER_TOO_SHORT) {		/* now try with required space */		kfree(bssid_list);		list_len = needed;		bssid_list = kmalloc(list_len, GFP_KERNEL);		if (!bssid_list) {			ERROR("couldn't allocate memory");			return -ENOMEM;		}		memset(bssid_list, 0, list_len);		res = miniport_query_info(wnd, OID_802_11_BSSID_LIST,					  bssid_list, list_len);	}	if (res) {		WARNING("getting BSSID list failed (%08X)", res);		kfree(bssid_list);		EXIT2(return -EOPNOTSUPP);	}	TRACE2("%d", bssid_list->num_items);	cur_item = &bssid_list->bssid[0];	for (i = 0; i < bssid_list->num_items; i++) {		event = ndis_translate_scan(dev, event,					    extra + IW_SCAN_MAX_DATA, cur_item);		cur_item = (struct ndis_wlan_bssid *)((char *)cur_item +						      cur_item->length);	}	wrqu->data.length = event - extra;	wrqu->data.flags = 0;	kfree(bssid_list);	EXIT2(return 0);}static int iw_set_power_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;	ULONG power_mode;	ENTER2("");	if (wrqu->power.disabled == 1)		power_mode = NDIS_POWER_OFF;	else if (wrqu->power.flags & IW_POWER_MIN)		power_mode = NDIS_POWER_MIN;	else // if (wrqu->power.flags & IW_POWER_MAX)		power_mode = NDIS_POWER_MAX;	res = miniport_set_info(wnd, OID_802_11_POWER_MODE,				&power_mode, sizeof(power_mode));	if (res)		WARNING("setting power mode failed (%08X)", res);	return 0;}static int iw_get_power_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;	ULONG power_mode;	ENTER2("");	res = miniport_query_info(wnd, OID_802_11_POWER_MODE,				  &power_mode, sizeof(power_mode));	if (res)		return -ENOTSUPP;	if (power_mode == NDIS_POWER_OFF)		wrqu->power.disabled = 1;	else {		if (wrqu->power.flags != 0)			return 0;		wrqu->power.flags |= IW_POWER_ALL_R;		wrqu->power.flags |= IW_POWER_TIMEOUT;		wrqu->power.value = 0;		wrqu->power.disabled = 0;		if (power_mode == NDIS_POWER_MIN)			wrqu->power.flags |= IW_POWER_MIN;		else // if (power_mode == NDIS_POWER_MAX)			wrqu->power.flags |= IW_POWER_MAX;	}	return 0;}static int iw_get_sensitivity(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;	ndis_rssi rssi_trigger;	ENTER2("");	res = miniport_query_info(wnd, OID_802_11_RSSI_TRIGGER,				  &rssi_trigger, sizeof(rssi_trigger));	if (res)		return -EOPNOTSUPP;	wrqu->param.value = rssi_trigger;	wrqu->param.disabled = (rssi_trigger == 0);	wrqu->param.fixed = 1;	return 0;}static int iw_set_sensitivity(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;	ndis_rssi rssi_trigger;	ENTER2("");	if (wrqu->param.disabled)		rssi_trigger = 0;	else		rssi_trigger = wrqu->param.value;	res = miniport_set_info(wnd, OID_802_11_RSSI_TRIGGER,				&rssi_trigger, sizeof(rssi_trigger));	if (res == NDIS_STATUS_INVALID_DATA)		return -EINVAL;	if (res)		return -EOPNOTSUPP;	return 0;}static int iw_get_ndis_stats(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_statistics *stats = &wnd->iw_stats;	memcpy(&wrqu->qual, &stats->qual, sizeof(stats->qual));	return 0;}static int iw_get_range(struct net_device *dev, struct iw_request_info *info,			union iwreq_data *wrqu, char *extra){	struct iw_range *range = (struct iw_range *)extra;	struct iw_point *data = &wrqu->data;	struct wrap_ndis_device *wnd = netdev_priv(dev);	unsigned int i, n;	NDIS_STATUS res;	ndis_rates_ex rates_ex;	ndis_tx_power_level tx_power;	ENTER2("");	data->length = sizeof(struct iw_range);	memset(range, 0, sizeof(struct iw_range));	range->txpower_capa = IW_TXPOW_MWATT;	range->num_txpower = 0;	res = miniport_query_info(wnd, OID_802_11_TX_POWER_LEVEL,				 &tx_power, sizeof(tx_power));	if (!res) {		range->num_txpower = 1;		range->txpower[0] = tx_power;	}	range->we_version_compiled = WIRELESS_EXT;	range->we_version_source = 18;	range->retry_capa = IW_RETRY_LIMIT;	range->retry_flags = IW_RETRY_LIMIT;	range->min_retry = 0;	range->max_retry = 255;	range->num_channels = 1;	range->max_qual.qual = 100;	range->max_qual.level = 154;	range->max_qual.noise = 154;	range->sensitivity = 3;	range->max_encoding_tokens = 4;	range->num_encoding_sizes = 2;	range->encoding_size[0] = 5;	range->encoding_size[1] = 13;	range->num_bitrates = 0;	n = NDIS_MAX_RATES_EX;	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;

⌨️ 快捷键说明

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