📄 driver_ndis.c
字号:
os_snprintf(txt, sizeof(txt), "NDIS: Set OID %08x", oid); wpa_hexdump_key(MSG_MSGDUMP, txt, data, len); buflen = sizeof(*o) + len; reallen = buflen - sizeof(o->Data); o = os_zalloc(buflen); if (o == NULL) return -1; o->Oid = oid;#ifdef _WIN32_WCE o->ptcDeviceName = drv->adapter_name;#endif /* _WIN32_WCE */ if (data) os_memcpy(o->Data, data, len); if (!DeviceIoControl(drv->ndisuio, IOCTL_NDISUIO_SET_OID_VALUE, o, reallen, NULL, 0, &written, NULL)) { wpa_printf(MSG_DEBUG, "NDIS: IOCTL_NDISUIO_SET_OID_VALUE " "(oid=%08x) failed: %d", oid, (int) GetLastError()); os_free(o); return -1; } os_free(o); return 0;#else /* CONFIG_USE_NDISUIO */ char *buf; PACKET_OID_DATA *o; char txt[50]; os_snprintf(txt, sizeof(txt), "NDIS: Set OID %08x", oid); wpa_hexdump_key(MSG_MSGDUMP, txt, data, len); buf = os_zalloc(sizeof(*o) + len); if (buf == NULL) return -1; o = (PACKET_OID_DATA *) buf; o->Oid = oid; o->Length = len; if (data) os_memcpy(o->Data, data, len); if (!PacketRequest(drv->adapter, TRUE, o)) { wpa_printf(MSG_DEBUG, "%s: oid=0x%x len (%d) failed", __func__, oid, len); os_free(buf); return -1; } os_free(buf); return 0;#endif /* CONFIG_USE_NDISUIO */}static int ndis_set_auth_mode(struct wpa_driver_ndis_data *drv, int mode){ u32 auth_mode = mode; if (ndis_set_oid(drv, OID_802_11_AUTHENTICATION_MODE, (char *) &auth_mode, sizeof(auth_mode)) < 0) { wpa_printf(MSG_DEBUG, "NDIS: Failed to set " "OID_802_11_AUTHENTICATION_MODE (%d)", (int) auth_mode); return -1; } return 0;}static int ndis_get_auth_mode(struct wpa_driver_ndis_data *drv){ u32 auth_mode; int res; res = ndis_get_oid(drv, OID_802_11_AUTHENTICATION_MODE, (char *) &auth_mode, sizeof(auth_mode)); if (res != sizeof(auth_mode)) { wpa_printf(MSG_DEBUG, "NDIS: Failed to get " "OID_802_11_AUTHENTICATION_MODE"); return -1; } return auth_mode;}static int ndis_set_encr_status(struct wpa_driver_ndis_data *drv, int encr){ u32 encr_status = encr; if (ndis_set_oid(drv, OID_802_11_ENCRYPTION_STATUS, (char *) &encr_status, sizeof(encr_status)) < 0) { wpa_printf(MSG_DEBUG, "NDIS: Failed to set " "OID_802_11_ENCRYPTION_STATUS (%d)", encr); return -1; } return 0;}static int ndis_get_encr_status(struct wpa_driver_ndis_data *drv){ u32 encr; int res; res = ndis_get_oid(drv, OID_802_11_ENCRYPTION_STATUS, (char *) &encr, sizeof(encr)); if (res != sizeof(encr)) { wpa_printf(MSG_DEBUG, "NDIS: Failed to get " "OID_802_11_ENCRYPTION_STATUS"); return -1; } return encr;}static int wpa_driver_ndis_get_bssid(void *priv, u8 *bssid){ struct wpa_driver_ndis_data *drv = priv; if (drv->wired) { /* * Report PAE group address as the "BSSID" for wired * connection. */ bssid[0] = 0x01; bssid[1] = 0x80; bssid[2] = 0xc2; bssid[3] = 0x00; bssid[4] = 0x00; bssid[5] = 0x03; return 0; } return ndis_get_oid(drv, OID_802_11_BSSID, bssid, ETH_ALEN) < 0 ? -1 : 0;}static int wpa_driver_ndis_get_ssid(void *priv, u8 *ssid){ struct wpa_driver_ndis_data *drv = priv; NDIS_802_11_SSID buf; int res; res = ndis_get_oid(drv, OID_802_11_SSID, (char *) &buf, sizeof(buf)); if (res < 4) { wpa_printf(MSG_DEBUG, "NDIS: Failed to get SSID"); if (drv->wired) { wpa_printf(MSG_DEBUG, "NDIS: Allow get_ssid failure " "with a wired interface"); return 0; } return -1; } os_memcpy(ssid, buf.Ssid, buf.SsidLength); return buf.SsidLength;}static int wpa_driver_ndis_set_ssid(struct wpa_driver_ndis_data *drv, const u8 *ssid, size_t ssid_len){ NDIS_802_11_SSID buf; os_memset(&buf, 0, sizeof(buf)); buf.SsidLength = ssid_len; os_memcpy(buf.Ssid, ssid, ssid_len); /* * Make sure radio is marked enabled here so that scan request will not * force SSID to be changed to a random one in order to enable radio at * that point. */ drv->radio_enabled = 1; return ndis_set_oid(drv, OID_802_11_SSID, (char *) &buf, sizeof(buf));}/* Disconnect using OID_802_11_DISASSOCIATE. This will also turn the radio off. */static int wpa_driver_ndis_radio_off(struct wpa_driver_ndis_data *drv){ drv->radio_enabled = 0; return ndis_set_oid(drv, OID_802_11_DISASSOCIATE, " ", 4);}/* Disconnect by setting SSID to random (i.e., likely not used). */static int wpa_driver_ndis_disconnect(struct wpa_driver_ndis_data *drv){ char ssid[32]; int i; for (i = 0; i < 32; i++) ssid[i] = rand() & 0xff; return wpa_driver_ndis_set_ssid(drv, ssid, 32);}static int wpa_driver_ndis_deauthenticate(void *priv, const u8 *addr, int reason_code){ struct wpa_driver_ndis_data *drv = priv; return wpa_driver_ndis_disconnect(drv);}static int wpa_driver_ndis_disassociate(void *priv, const u8 *addr, int reason_code){ struct wpa_driver_ndis_data *drv = priv; return wpa_driver_ndis_disconnect(drv);}static int wpa_driver_ndis_set_wpa(void *priv, int enabled){ wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled); return 0;}static void wpa_driver_ndis_scan_timeout(void *eloop_ctx, void *timeout_ctx){ wpa_printf(MSG_DEBUG, "Scan timeout - try to get results"); wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);}static int wpa_driver_ndis_scan(void *priv, const u8 *ssid, size_t ssid_len){ struct wpa_driver_ndis_data *drv = priv; int res; if (!drv->radio_enabled) { wpa_printf(MSG_DEBUG, "NDIS: turning radio on before the first" " scan"); if (wpa_driver_ndis_disconnect(drv) < 0) { wpa_printf(MSG_DEBUG, "NDIS: failed to enable radio"); } drv->radio_enabled = 1; } res = ndis_set_oid(drv, OID_802_11_BSSID_LIST_SCAN, " ", 4); eloop_cancel_timeout(wpa_driver_ndis_scan_timeout, drv, drv->ctx); eloop_register_timeout(7, 0, wpa_driver_ndis_scan_timeout, drv, drv->ctx); return res;}static void wpa_driver_ndis_get_ies(struct wpa_scan_result *res, u8 *ie, size_t ie_len){ u8 *pos = ie; u8 *end = ie + ie_len; if (ie_len < sizeof(NDIS_802_11_FIXED_IEs)) return; pos += sizeof(NDIS_802_11_FIXED_IEs); /* wpa_hexdump(MSG_MSGDUMP, "IEs", pos, end - pos); */ while (pos + 1 < end && pos + 2 + pos[1] <= end) { u8 ielen = 2 + pos[1]; if (ielen > SSID_MAX_WPA_IE_LEN) { pos += ielen; continue; } if (pos[0] == GENERIC_INFO_ELEM && pos[1] >= 4 && os_memcmp(pos + 2, "\x00\x50\xf2\x01", 4) == 0) { os_memcpy(res->wpa_ie, pos, ielen); res->wpa_ie_len = ielen; } else if (pos[0] == RSN_INFO_ELEM) { os_memcpy(res->rsn_ie, pos, ielen); res->rsn_ie_len = ielen; } pos += ielen; }}static int wpa_driver_ndis_get_scan_results(void *priv, struct wpa_scan_result *results, size_t max_size){ struct wpa_driver_ndis_data *drv = priv; NDIS_802_11_BSSID_LIST_EX *b; size_t blen, count, i; int len, j; char *pos; blen = 65535; b = os_zalloc(blen); if (b == NULL) return -1; 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"); os_free(b); return -1; } count = b->NumberOfItems; if (count > max_size) count = max_size; os_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; os_memcpy(results[i].bssid, bss->MacAddress, ETH_ALEN); os_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; if (bss->InfrastructureMode == Ndis802_11IBSS) results[i].caps |= IEEE80211_CAP_IBSS; else if (bss->InfrastructureMode == Ndis802_11Infrastructure) results[i].caps |= IEEE80211_CAP_ESS; 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; } } if (((char *) bss->IEs) + bss->IELength > (char *) b + blen) { /* * Some NDIS drivers have been reported to include an * entry with an invalid IELength in scan results and * this has crashed wpa_supplicant, so validate the * returned value before using it. */ wpa_printf(MSG_DEBUG, "NDIS: skipped invalid scan " "result IE (BSSID=" MACSTR ") IELength=%d", MAC2STR(results[i].bssid), (int) bss->IELength); break; } wpa_driver_ndis_get_ies(&results[i], bss->IEs, bss->IELength); pos += bss->Length; if (pos > (char *) b + blen) break; } os_free(b); return (int) 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; os_memset(&rkey, 0, sizeof(rkey)); rkey.Length = sizeof(rkey); rkey.KeyIndex = key_idx; if (pairwise) rkey.KeyIndex |= 1 << 30; os_memcpy(rkey.BSSID, bssid, ETH_ALEN); res = ndis_set_oid(drv, OID_802_11_REMOVE_KEY, (char *) &rkey, sizeof(rkey)); if (!pairwise) { index = key_idx; res2 = ndis_set_oid(drv, OID_802_11_REMOVE_WEP, (char *) &index, sizeof(index)); } else res2 = 0; if (res < 0 && res2 < 0) return -1; 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 = os_zalloc(len); if (wep == NULL) return -1; 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; os_memcpy(wep->KeyMaterial, key, key_len); wpa_hexdump_key(MSG_MSGDUMP, "NDIS: OID_802_11_ADD_WEP", (char *) wep, len); res = ndis_set_oid(drv, OID_802_11_ADD_WEP, (char *) wep, len); os_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, i; NDIS_802_11_KEY *nkey; int res, pairwise; u8 bssid[ETH_ALEN]; if (addr == NULL || os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0) { /* Group Key */ pairwise = 0; if (wpa_driver_ndis_get_bssid(drv, bssid) < 0) os_memset(bssid, 0xff, ETH_ALEN); } else { /* Pairwise Key */ pairwise = 1; os_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 = os_zalloc(len); if (nkey == NULL) return -1; 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; os_memcpy(nkey->BSSID, bssid, ETH_ALEN); if (seq && seq_len) { for (i = 0; i < seq_len; i++) nkey->KeyRSC |= (ULONGLONG) seq[i] << (i * 8); } if (alg == WPA_ALG_TKIP && key_len == 32) { os_memcpy(nkey->KeyMaterial, key, 16); os_memcpy(nkey->KeyMaterial + 16, key + 24, 8); os_memcpy(nkey->KeyMaterial + 24, key + 16, 8); } else { os_memcpy(nkey->KeyMaterial, key, key_len); } wpa_hexdump_key(MSG_MSGDUMP, "NDIS: OID_802_11_ADD_KEY", (char *) nkey, len); res = ndis_set_oid(drv, OID_802_11_ADD_KEY, (char *) nkey, len); os_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; drv->mode = params->mode;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -