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

📄 driver_ndis.c

📁 一个Linux下无线网卡的设置工具
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (b == NULL)		return -1;	memset(b, 0, blen);	len = ndis_get_oid(drv, OID_802_11_BSSID_LIST, (char *) b, blen);	if (len < 0) {		wpa_printf(MSG_DEBUG, "NDIS: failed to get scan results");		free(b);		return -1;	}	count = b->NumberOfItems;	if (count > max_size)		count = max_size;	memset(results, 0, max_size * sizeof(struct wpa_scan_result));	pos = (char *) &b->Bssid[0];	for (i = 0; i < count; i++) {		NDIS_WLAN_BSSID_EX *bss = (NDIS_WLAN_BSSID_EX *) pos;		memcpy(results[i].bssid, bss->MacAddress, ETH_ALEN);		memcpy(results[i].ssid, bss->Ssid.Ssid, bss->Ssid.SsidLength);		results[i].ssid_len = bss->Ssid.SsidLength;		if (bss->Privacy)			results[i].caps |= IEEE80211_CAP_PRIVACY;		results[i].level = (int) bss->Rssi;		results[i].freq = bss->Configuration.DSConfig / 1000;		for (j = 0; j < sizeof(bss->SupportedRates); j++) {			if ((bss->SupportedRates[j] & 0x7f) >			    results[i].maxrate) {				results[i].maxrate =					bss->SupportedRates[j] & 0x7f;			}		}		wpa_driver_ndis_get_ies(&results[i], bss->IEs, bss->IELength);		pos += bss->Length;		if (pos > (char *) b + blen)			break;	}	free(b);	return count;}static int wpa_driver_ndis_remove_key(struct wpa_driver_ndis_data *drv,				      int key_idx, const u8 *addr,				      const u8 *bssid, int pairwise){	NDIS_802_11_REMOVE_KEY rkey;	NDIS_802_11_KEY_INDEX index;	int res, res2;	memset(&rkey, 0, sizeof(rkey));	rkey.Length = sizeof(rkey);	rkey.KeyIndex = key_idx;	if (pairwise)		rkey.KeyIndex |= 1 << 30;	memcpy(rkey.BSSID, bssid, ETH_ALEN);	res = ndis_set_oid(drv, OID_802_11_REMOVE_KEY, (char *) &rkey,			   sizeof(rkey));	if (!pairwise) {		res2 = ndis_set_oid(drv, OID_802_11_REMOVE_WEP,				    (char *) &index, sizeof(index));	} else		res2 = 0;	if (res < 0 && res2 < 0)		return res;	return 0;}static int wpa_driver_ndis_add_wep(struct wpa_driver_ndis_data *drv,				   int pairwise, int key_idx, int set_tx,				   const u8 *key, size_t key_len){	NDIS_802_11_WEP *wep;	size_t len;	int res;	len = 12 + key_len;	wep = malloc(len);	if (wep == NULL)		return -1;	memset(wep, 0, len);	wep->Length = len;	wep->KeyIndex = key_idx;	if (set_tx)		wep->KeyIndex |= 1 << 31;#if 0 /* Setting bit30 does not seem to work with some NDIS drivers */	if (pairwise)		wep->KeyIndex |= 1 << 30;#endif	wep->KeyLength = key_len;	memcpy(wep->KeyMaterial, key, key_len);	wpa_hexdump_key(MSG_MSGDUMP, "NDIS: OIS_802_11_ADD_WEP",			(char *) wep, len);	res = ndis_set_oid(drv, OID_802_11_ADD_WEP, (char *) wep, len);	free(wep);	return res;}static int wpa_driver_ndis_set_key(void *priv, wpa_alg alg, const u8 *addr,				   int key_idx, int set_tx,				   const u8 *seq, size_t seq_len,				   const u8 *key, size_t key_len){	struct wpa_driver_ndis_data *drv = priv;	size_t len;	NDIS_802_11_KEY *nkey;	int i, res, pairwise;	u8 bssid[ETH_ALEN];	if (addr == NULL || memcmp(addr, "\xff\xff\xff\xff\xff\xff",				   ETH_ALEN) == 0) {		/* Group Key */		pairwise = 0;		wpa_driver_ndis_get_bssid(drv, bssid);	} else {		/* Pairwise Key */		pairwise = 1;		memcpy(bssid, addr, ETH_ALEN);	}	if (alg == WPA_ALG_NONE || key_len == 0) {		return wpa_driver_ndis_remove_key(drv, key_idx, addr, bssid,						  pairwise);	}	if (alg == WPA_ALG_WEP) {		return wpa_driver_ndis_add_wep(drv, pairwise, key_idx, set_tx,					       key, key_len);	}	len = 12 + 6 + 6 + 8 + key_len;	nkey = malloc(len);	if (nkey == NULL)		return -1;	memset(nkey, 0, len);	nkey->Length = len;	nkey->KeyIndex = key_idx;	if (set_tx)		nkey->KeyIndex |= 1 << 31;	if (pairwise)		nkey->KeyIndex |= 1 << 30;	if (seq && seq_len)		nkey->KeyIndex |= 1 << 29;	nkey->KeyLength = key_len;	memcpy(nkey->BSSID, bssid, ETH_ALEN);	if (seq && seq_len) {		for (i = 0; i < seq_len; i++)			nkey->KeyRSC |= seq[i] << (i * 8);	}	if (alg == WPA_ALG_TKIP && key_len == 32) {		memcpy(nkey->KeyMaterial, key, 16);		memcpy(nkey->KeyMaterial + 16, key + 24, 8);		memcpy(nkey->KeyMaterial + 24, key + 16, 8);	} else {		memcpy(nkey->KeyMaterial, key, key_len);	}	wpa_hexdump_key(MSG_MSGDUMP, "NDIS: OIS_802_11_ADD_KEY",			(char *) nkey, len);	res = ndis_set_oid(drv, OID_802_11_ADD_KEY, (char *) nkey, len);	free(nkey);	return res;}static intwpa_driver_ndis_associate(void *priv,			  struct wpa_driver_associate_params *params){	struct wpa_driver_ndis_data *drv = priv;	u32 auth_mode, encr, priv_mode, mode;	/* Note: Setting OID_802_11_INFRASTRUCTURE_MODE clears current keys,	 * so static WEP keys needs to be set again after this. */	if (params->mode == IEEE80211_MODE_IBSS)		mode = Ndis802_11IBSS;	else		mode = Ndis802_11Infrastructure;	if (ndis_set_oid(drv, OID_802_11_INFRASTRUCTURE_MODE,			 (char *) &mode, sizeof(mode)) < 0) {		wpa_printf(MSG_DEBUG, "NDIS: Failed to set "			   "OID_802_11_INFRASTRUCTURE_MODE (%d)",			   (int) mode);		/* Try to continue anyway */	}	if (params->wpa_ie == NULL || params->wpa_ie_len == 0) {		if (params->auth_alg & AUTH_ALG_SHARED_KEY) {			if (params->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 (params->wpa_ie[0] == RSN_INFO_ELEM) {		priv_mode = Ndis802_11PrivFilter8021xWEP;		if (params->key_mgmt_suite == KEY_MGMT_PSK)			auth_mode = Ndis802_11AuthModeWPA2PSK;		else			auth_mode = Ndis802_11AuthModeWPA2;	} else {		priv_mode = Ndis802_11PrivFilter8021xWEP;		if (params->key_mgmt_suite == KEY_MGMT_WPA_NONE)			auth_mode = Ndis802_11AuthModeWPANone;		else if (params->key_mgmt_suite == KEY_MGMT_PSK)			auth_mode = Ndis802_11AuthModeWPAPSK;		else			auth_mode = Ndis802_11AuthModeWPA;	}	switch (params->pairwise_suite) {	case CIPHER_CCMP:		encr = Ndis802_11Encryption3Enabled;		break;	case CIPHER_TKIP:		encr = Ndis802_11Encryption2Enabled;		break;	case CIPHER_WEP40:	case CIPHER_WEP104:		encr = Ndis802_11Encryption1Enabled;		break;	case CIPHER_NONE:		if (params->group_suite == CIPHER_CCMP)			encr = Ndis802_11Encryption3Enabled;		else if (params->group_suite == CIPHER_TKIP)			encr = Ndis802_11Encryption2Enabled;		else			encr = Ndis802_11EncryptionDisabled;		break;	default:		encr = Ndis802_11EncryptionDisabled;	};	if (ndis_set_oid(drv, OID_802_11_PRIVACY_FILTER,			 (char *) &priv_mode, sizeof(priv_mode)) < 0) {		wpa_printf(MSG_DEBUG, "NDIS: Failed to set "			   "OID_802_11_PRIVACY_FILTER (%d)",			   (int) priv_mode);		/* Try to continue anyway */	}	ndis_set_auth_mode(drv, auth_mode);	ndis_set_encr_status(drv, encr);	return wpa_driver_ndis_set_ssid(drv, params->ssid, params->ssid_len);}static int wpa_driver_ndis_set_pmkid(struct wpa_driver_ndis_data *drv){	int len, count, i, ret;	struct ndis_pmkid_entry *entry;	NDIS_802_11_PMKID *p;	count = 0;	entry = drv->pmkid;	while (entry) {		count++;		if (count >= drv->no_of_pmkid)			break;		entry = entry->next;	}	len = 8 + count * sizeof(BSSID_INFO);	p = malloc(len);	if (p == NULL)		return -1;	memset(p, 0, len);	p->Length = len;	p->BSSIDInfoCount = count;	entry = drv->pmkid;	for (i = 0; i < count; i++) {		memcpy(&p->BSSIDInfo[i].BSSID, entry->bssid, ETH_ALEN);		memcpy(&p->BSSIDInfo[i].PMKID, entry->pmkid, 16);		entry = entry->next;	}	wpa_hexdump(MSG_MSGDUMP, "NDIS: OID_802_11_PMKID", (char *) p, len);	ret = ndis_set_oid(drv, OID_802_11_PMKID, (char *) p, len);	free(p);	return ret;}static int wpa_driver_ndis_add_pmkid(void *priv, const u8 *bssid,				     const u8 *pmkid){	struct wpa_driver_ndis_data *drv = priv;	struct ndis_pmkid_entry *entry, *prev;	if (drv->no_of_pmkid == 0)		return 0;	prev = NULL;	entry = drv->pmkid;	while (entry) {		if (memcmp(entry->bssid, bssid, ETH_ALEN) == 0)			break;		prev = entry;		entry = entry->next;	}	if (entry) {		/* Replace existing entry for this BSSID and move it into the		 * beginning of the list. */		memcpy(entry->pmkid, pmkid, 16);		if (prev) {			prev->next = entry->next;			entry->next = drv->pmkid;			drv->pmkid = entry;		}	} else {		entry = malloc(sizeof(*entry));		if (entry) {			memcpy(entry->bssid, bssid, ETH_ALEN);			memcpy(entry->pmkid, pmkid, 16);			entry->next = drv->pmkid;			drv->pmkid = entry;		}	}	return wpa_driver_ndis_set_pmkid(drv);}static int wpa_driver_ndis_remove_pmkid(void *priv, const u8 *bssid,		 			const u8 *pmkid){	struct wpa_driver_ndis_data *drv = priv;	struct ndis_pmkid_entry *entry, *prev;	if (drv->no_of_pmkid == 0)		return 0;	entry = drv->pmkid;	prev = NULL;	drv->pmkid = NULL;	while (entry) {		if (memcmp(entry->bssid, bssid, ETH_ALEN) == 0 &&		    memcmp(entry->pmkid, pmkid, 16) == 0) {			if (prev)				prev->next = entry->next;			else				drv->pmkid = entry->next;			free(entry);			break;		}		prev = entry;		entry = entry->next;	}	return wpa_driver_ndis_set_pmkid(drv);}static int wpa_driver_ndis_flush_pmkid(void *priv){	struct wpa_driver_ndis_data *drv = priv;	NDIS_802_11_PMKID p;	struct ndis_pmkid_entry *pmkid, *prev;	if (drv->no_of_pmkid == 0)		return 0;	pmkid = drv->pmkid;	drv->pmkid = NULL;	while (pmkid) {		prev = pmkid;		pmkid = pmkid->next;		free(prev);	}	memset(&p, 0, sizeof(p));	p.Length = 8;	p.BSSIDInfoCount = 0;	wpa_hexdump(MSG_MSGDUMP, "NDIS: OID_802_11_PMKID (flush)",		    (char *) &p, 8);	return ndis_set_oid(drv, OID_802_11_PMKID, (char *) &p, 8);}static int wpa_driver_ndis_get_associnfo(struct wpa_driver_ndis_data *drv){	char buf[512], *pos;	NDIS_802_11_ASSOCIATION_INFORMATION *ai;	int len, i;	union wpa_event_data data;	NDIS_802_11_BSSID_LIST_EX *b;	size_t blen;	len = ndis_get_oid(drv, OID_802_11_ASSOCIATION_INFORMATION, buf,			   sizeof(buf));	if (len < 0) {		wpa_printf(MSG_DEBUG, "NDIS: failed to get association "			   "information");		return -1;	}	if (len > sizeof(buf)) {		/* Some drivers seem to be producing incorrect length for this		 * data. Limit the length to the current buffer size to avoid		 * crashing in hexdump. The data seems to be otherwise valid,		 * so better try to use it. */		wpa_printf(MSG_DEBUG, "NDIS: ignored bogus association "			   "information length %d", len);		len = ndis_get_oid(drv, OID_802_11_ASSOCIATION_INFORMATION,				   buf, sizeof(buf));		if (len < -1) {			wpa_printf(MSG_DEBUG, "NDIS: re-reading association "				   "information failed");			return -1;		}		if (len > sizeof(buf)) {			wpa_printf(MSG_DEBUG, "NDIS: ignored bogus association"				   " information length %d (re-read)", len);			len = sizeof(buf);		}	}	wpa_hexdump(MSG_MSGDUMP, "NDIS: association information", buf, len);	if (len < sizeof(*ai)) {		wpa_printf(MSG_DEBUG, "NDIS: too short association "			   "information");		return -1;	}	ai = (NDIS_802_11_ASSOCIATION_INFORMATION *) buf;	wpa_printf(MSG_DEBUG, "NDIS: ReqFixed=0x%x RespFixed=0x%x off_req=%d "		   "off_resp=%d len_req=%d len_resp=%d",		   ai->AvailableRequestFixedIEs, ai->AvailableResponseFixedIEs,		   (int) ai->OffsetRequestIEs, (int) ai->OffsetResponseIEs,		   (int) ai->RequestIELength, (int) ai->ResponseIELength);	if (ai->OffsetRequestIEs + ai->RequestIELength > len ||	    ai->OffsetResponseIEs + ai->ResponseIELength > len) {		wpa_printf(MSG_DEBUG, "NDIS: association information - "			   "IE overflow");		return -1;	}	wpa_hexdump(MSG_MSGDUMP, "NDIS: Request IEs", 		    buf + ai->OffsetRequestIEs, ai->RequestIELength);	wpa_hexdump(MSG_MSGDUMP, "NDIS: Response IEs", 		    buf + ai->OffsetResponseIEs, ai->ResponseIELength);	memset(&data, 0, sizeof(data));	data.assoc_info.req_ies = buf + ai->OffsetRequestIEs;	data.assoc_info.req_ies_len = ai->RequestIELength;	data.assoc_info.resp_ies = buf + ai->OffsetResponseIEs;	data.assoc_info.resp_ies_len = ai->ResponseIELength;	blen = 65535;	b = malloc(blen);	if (b == NULL)		goto skip_scan_results;	memset(b, 0, blen);	len = ndis_get_oid(drv, OID_802_11_BSSID_LIST, (char *) b, blen);	if (len < 0) {		wpa_printf(MSG_DEBUG, "NDIS: failed to get scan results");		free(b);		b = NULL;		goto skip_scan_results;	}	wpa_printf(MSG_DEBUG, "NDIS: %d BSSID items to process for AssocInfo",		   (unsigned int) b->NumberOfItems);	pos = (char *) &b->Bssid[0];	for (i = 0; i < b->NumberOfItems; i++) {		NDIS_WLAN_BSSID_EX *bss = (NDIS_WLAN_BSSID_EX *) pos;		if (memcmp(drv->bssid, bss->MacAddress, ETH_ALEN) == 0 &&		    bss->IELength > sizeof(NDIS_802_11_FIXED_IEs)) {			data.assoc_info.beacon_ies =				((u8 *) bss->IEs) +				sizeof(NDIS_802_11_FIXED_IEs);			data.assoc_info.beacon_ies_len =				bss->IELength - sizeof(NDIS_802_11_FIXED_IEs);			wpa_hexdump(MSG_MSGDUMP, "NDIS: Beacon IEs",				    data.assoc_info.beacon_ies,				    data.assoc_info.beacon_ies_len);			break;		}		pos += bss->Length;		if (pos > (char *) b + blen)			break;	}skip_scan_results:	wpa_supplicant_event(drv->ctx, EVENT_ASSOCINFO, &data);	free(b);	return 0;}static void wpa_driver_ndis_poll_timeout(void *eloop_ctx, void *timeout_ctx){	struct wpa_driver_ndis_data *drv = eloop_ctx;	u8 bssid[ETH_ALEN];	if (drv->wired)		return;	if (wpa_driver_ndis_get_bssid(drv, bssid)) {		/* Disconnected */		if (memcmp(drv->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN)		    != 0) {			memset(drv->bssid, 0, ETH_ALEN);			wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);		}	} else {		/* Connected */		if (memcmp(drv->bssid, bssid, ETH_ALEN) != 0) {			memcpy(drv->bssid, bssid, ETH_ALEN);			wpa_driver_ndis_get_associnfo(drv);			wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);		}	}	eloop_register_timeout(1, 0, wpa_driver_ndis_poll_timeout, drv, NULL);}static void wpa_driver_ndis_poll(void *priv){	struct wpa_driver_ndis_data *drv = priv;	eloop_cancel_timeout(wpa_driver_ndis_poll_timeout, drv, NULL);	wpa_driver_ndis_poll_timeout(drv, NULL);}/* Called when driver generates Media Connect Event by calling * NdisMIndicateStatus() with NDIS_STATUS_MEDIA_CONNECT */void wpa_driver_ndis_event_connect(struct wpa_driver_ndis_data *drv){	wpa_printf(MSG_DEBUG, "NDIS: Media Connect Event");	if (wpa_driver_ndis_get_bssid(drv, drv->bssid) == 0) {		wpa_driver_ndis_get_associnfo(drv);		wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);	}}/* Called when driver generates Media Disconnect Event by calling * NdisMIndicateStatus() with NDIS_STATUS_MEDIA_DISCONNECT */void wpa_driver_ndis_event_disconnect(struct wpa_driver_ndis_data *drv){	wpa_printf(MSG_DEBUG, "NDIS: Media Disconnect Event");	memset(drv->bssid, 0, ETH_ALEN);	wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);}static void wpa_driver_ndis_event_auth(struct wpa_driver_ndis_data *drv,				       const u8 *data, size_t data_len){	NDIS_802_11_AUTHENTICATION_REQUEST *req;	int pairwise = 0, group = 0;	union wpa_event_data event;	if (data_len < sizeof(*req)) {		wpa_printf(MSG_DEBUG, "NDIS: Too short Authentication Request "

⌨️ 快捷键说明

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