📄 driver_ndis.c
字号:
"Event (len=%d)", data_len); return; } req = (NDIS_802_11_AUTHENTICATION_REQUEST *) data; wpa_printf(MSG_DEBUG, "NDIS: Authentication Request Event: " "Bssid " MACSTR " Flags 0x%x", MAC2STR(req->Bssid), (int) req->Flags); if ((req->Flags & NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR) == NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR) pairwise = 1; else if ((req->Flags & NDIS_802_11_AUTH_REQUEST_GROUP_ERROR) == NDIS_802_11_AUTH_REQUEST_GROUP_ERROR) group = 1; if (pairwise || group) { memset(&event, 0, sizeof(event)); event.michael_mic_failure.unicast = pairwise; wpa_supplicant_event(drv->ctx, EVENT_MICHAEL_MIC_FAILURE, &event); }}static void wpa_driver_ndis_event_pmkid(struct wpa_driver_ndis_data *drv, const u8 *data, size_t data_len){ NDIS_802_11_PMKID_CANDIDATE_LIST *pmkid; int i; union wpa_event_data event; if (data_len < 8) { wpa_printf(MSG_DEBUG, "NDIS: Too short PMKID Candidate List " "Event (len=%d)", data_len); return; } pmkid = (NDIS_802_11_PMKID_CANDIDATE_LIST *) data; wpa_printf(MSG_DEBUG, "NDIS: PMKID Candidate List Event - Version %d " "NumCandidates %d", (int) pmkid->Version, (int) pmkid->NumCandidates); if (pmkid->Version != 1) { wpa_printf(MSG_DEBUG, "NDIS: Unsupported PMKID Candidate List " "Version %d", (int) pmkid->Version); return; } if (data_len < 8 + pmkid->NumCandidates * sizeof(PMKID_CANDIDATE)) { wpa_printf(MSG_DEBUG, "NDIS: PMKID Candidate List underflow"); return; } memset(&event, 0, sizeof(event)); for (i = 0; i < pmkid->NumCandidates; i++) { PMKID_CANDIDATE *p = &pmkid->CandidateList[i]; wpa_printf(MSG_DEBUG, "NDIS: %d: " MACSTR " Flags 0x%x", i, MAC2STR(p->BSSID), (int) p->Flags); memcpy(event.pmkid_candidate.bssid, p->BSSID, ETH_ALEN); event.pmkid_candidate.index = i; event.pmkid_candidate.preauth = p->Flags & NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; wpa_supplicant_event(drv->ctx, EVENT_PMKID_CANDIDATE, &event); }}/* Called when driver calls NdisMIndicateStatus() with * NDIS_STATUS_MEDIA_SPECIFIC_INDICATION */void wpa_driver_ndis_event_media_specific(struct wpa_driver_ndis_data *drv, const u8 *data, size_t data_len){ NDIS_802_11_STATUS_INDICATION *status; if (data == NULL || data_len < sizeof(*status)) return; wpa_hexdump(MSG_DEBUG, "NDIS: Media Specific Indication", data, data_len); status = (NDIS_802_11_STATUS_INDICATION *) data; data += sizeof(status); data_len -= sizeof(status); switch (status->StatusType) { case Ndis802_11StatusType_Authentication: wpa_driver_ndis_event_auth(drv, data, data_len); break; case Ndis802_11StatusType_PMKID_CandidateList: wpa_driver_ndis_event_pmkid(drv, data, data_len); break; default: wpa_printf(MSG_DEBUG, "NDIS: Unknown StatusType %d", (int) status->StatusType); break; }}static voidwpa_driver_ndis_get_wpa_capability(struct wpa_driver_ndis_data *drv){ wpa_printf(MSG_DEBUG, "NDIS: verifying driver WPA capability"); if (ndis_set_auth_mode(drv, Ndis802_11AuthModeWPA) == 0 && ndis_get_auth_mode(drv) == Ndis802_11AuthModeWPA) { wpa_printf(MSG_DEBUG, "NDIS: WPA key management supported"); drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA; } if (ndis_set_auth_mode(drv, Ndis802_11AuthModeWPAPSK) == 0 && ndis_get_auth_mode(drv) == Ndis802_11AuthModeWPAPSK) { wpa_printf(MSG_DEBUG, "NDIS: WPA-PSK key management " "supported"); drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK; } if (ndis_set_encr_status(drv, Ndis802_11Encryption3Enabled) == 0 && ndis_get_encr_status(drv) == Ndis802_11Encryption3KeyAbsent) { wpa_printf(MSG_DEBUG, "NDIS: CCMP encryption supported"); drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP; } if (ndis_set_encr_status(drv, Ndis802_11Encryption2Enabled) == 0 && ndis_get_encr_status(drv) == Ndis802_11Encryption2KeyAbsent) { wpa_printf(MSG_DEBUG, "NDIS: TKIP encryption supported"); drv->capa.enc |= WPA_DRIVER_CAPA_ENC_TKIP; } if (ndis_set_encr_status(drv, Ndis802_11Encryption1Enabled) == 0 && ndis_get_encr_status(drv) == Ndis802_11Encryption1KeyAbsent) { wpa_printf(MSG_DEBUG, "NDIS: WEP encryption supported"); drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP40 | WPA_DRIVER_CAPA_ENC_WEP104; } if (ndis_set_auth_mode(drv, Ndis802_11AuthModeShared) == 0 && ndis_get_auth_mode(drv) == Ndis802_11AuthModeShared) { drv->capa.auth |= WPA_DRIVER_AUTH_SHARED; } if (ndis_set_auth_mode(drv, Ndis802_11AuthModeOpen) == 0 && ndis_get_auth_mode(drv) == Ndis802_11AuthModeOpen) { drv->capa.auth |= WPA_DRIVER_AUTH_OPEN; } ndis_set_encr_status(drv, Ndis802_11EncryptionDisabled); /* Could also verify OID_802_11_ADD_KEY error reporting and * support for OID_802_11_ASSOCIATION_INFORMATION. */ if (drv->capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA && drv->capa.enc & (WPA_DRIVER_CAPA_ENC_TKIP | WPA_DRIVER_CAPA_ENC_CCMP)) { wpa_printf(MSG_DEBUG, "NDIS: driver supports WPA"); drv->has_capability = 1; } else { wpa_printf(MSG_DEBUG, "NDIS: no WPA support found"); } wpa_printf(MSG_DEBUG, "NDIS: driver capabilities: key_mgmt 0x%x " "enc 0x%x auth 0x%x", drv->capa.key_mgmt, drv->capa.enc, drv->capa.auth);}static void wpa_driver_ndis_get_capability(struct wpa_driver_ndis_data *drv){ char buf[512]; int len, i; NDIS_802_11_CAPABILITY *c; drv->capa.flags = WPA_DRIVER_FLAGS_DRIVER_IE | WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC; len = ndis_get_oid(drv, OID_802_11_CAPABILITY, buf, sizeof(buf)); if (len < 0) { wpa_driver_ndis_get_wpa_capability(drv); return; } wpa_hexdump(MSG_MSGDUMP, "OID_802_11_CAPABILITY", buf, len); c = (NDIS_802_11_CAPABILITY *) buf; if (len < sizeof(*c) || c->Version != 2) { wpa_printf(MSG_DEBUG, "NDIS: unsupported " "OID_802_11_CAPABILITY data"); return; } wpa_printf(MSG_DEBUG, "NDIS: Driver supports OID_802_11_CAPABILITY - " "NoOfPMKIDs %d NoOfAuthEncrPairs %d", (int) c->NoOfPMKIDs, (int) c->NoOfAuthEncryptPairSupported); drv->has_capability = 1; drv->no_of_pmkid = c->NoOfPMKIDs; for (i = 0; i < c->NoOfAuthEncryptPairSupported; i++) { NDIS_802_11_AUTHENTICATION_ENCRYPTION *ae; ae = &c->AuthenticationEncryptionSupported[i]; if ((char *) (ae + 1) > buf + len) { wpa_printf(MSG_DEBUG, "NDIS: auth/encr pair list " "overflow"); break; } wpa_printf(MSG_MSGDUMP, "NDIS: %d - auth %d encr %d", i, (int) ae->AuthModeSupported, (int) ae->EncryptStatusSupported); switch (ae->AuthModeSupported) { case Ndis802_11AuthModeOpen: drv->capa.auth |= WPA_DRIVER_AUTH_OPEN; break; case Ndis802_11AuthModeShared: drv->capa.auth |= WPA_DRIVER_AUTH_SHARED; break; case Ndis802_11AuthModeWPA: drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA; break; case Ndis802_11AuthModeWPAPSK: drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK; break; case Ndis802_11AuthModeWPA2: drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA2; break; case Ndis802_11AuthModeWPA2PSK: drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK; break; case Ndis802_11AuthModeWPANone: drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE; break; default: break; } switch (ae->EncryptStatusSupported) { case Ndis802_11Encryption1Enabled: drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP40; drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP104; break; case Ndis802_11Encryption2Enabled: drv->capa.enc |= WPA_DRIVER_CAPA_ENC_TKIP; break; case Ndis802_11Encryption3Enabled: drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP; break; default: break; } } wpa_printf(MSG_DEBUG, "NDIS: driver capabilities: key_mgmt 0x%x " "enc 0x%x auth 0x%x", drv->capa.key_mgmt, drv->capa.enc, drv->capa.auth);}static int wpa_driver_ndis_get_capa(void *priv, struct wpa_driver_capa *capa){ struct wpa_driver_ndis_data *drv = priv; if (!drv->has_capability) return -1; memcpy(capa, &drv->capa, sizeof(*capa)); return 0;}static const char * wpa_driver_ndis_get_ifname(void *priv){ struct wpa_driver_ndis_data *drv = priv; return drv->ifname;}static const u8 * wpa_driver_ndis_get_mac_addr(void *priv){ struct wpa_driver_ndis_data *drv = priv; return drv->own_addr;}static int wpa_driver_ndis_get_names(struct wpa_driver_ndis_data *drv){ PTSTR names, pos, pos2; ULONG len; BOOLEAN res; const int MAX_ADAPTERS = 32; char *name[MAX_ADAPTERS]; char *desc[MAX_ADAPTERS]; int num_name, num_desc, i, found_name, found_desc; size_t dlen; wpa_printf(MSG_DEBUG, "NDIS: Packet.dll version: %s", PacketGetVersion()); len = 8192; names = malloc(len); if (names == NULL) return -1; memset(names, 0, len); res = PacketGetAdapterNames(names, &len); if (!res && len > 8192) { free(names); names = malloc(len); if (names == NULL) return -1; memset(names, 0, len); res = PacketGetAdapterNames(names, &len); } if (!res) { wpa_printf(MSG_ERROR, "NDIS: Failed to get adapter list " "(PacketGetAdapterNames)"); free(names); return -1; } /* wpa_hexdump_ascii(MSG_DEBUG, "NDIS: AdapterNames", names, len); */ if (names[0] && names[1] == '\0' && names[2] && names[3] == '\0') { wpa_printf(MSG_DEBUG, "NDIS: Looks like adapter names are in " "UNICODE"); /* Convert to ASCII */ pos2 = pos = names; while (pos2 < names + len) { if (pos2[0] == '\0' && pos2[1] == '\0' && pos2[2] == '\0' && pos2[3] == '\0') { pos2 += 4; break; } *pos++ = pos2[0]; pos2 += 2; } memcpy(pos + 2, names, pos - names); pos += 2; } else pos = names; num_name = 0; while (pos < names + len) { name[num_name] = pos; while (*pos && pos < names + len) pos++; if (pos + 1 >= names + len) { free(names); return -1; } pos++; num_name++; if (num_name >= MAX_ADAPTERS) { wpa_printf(MSG_DEBUG, "NDIS: Too many adapters"); free(names); return -1; } if (*pos == '\0') { wpa_printf(MSG_DEBUG, "NDIS: %d adapter names found", num_name); pos++; break; } } num_desc = 0; while (pos < names + len) { desc[num_desc] = pos; while (*pos && pos < names + len) pos++; if (pos + 1 >= names + len) { free(names); return -1; } pos++; num_desc++; if (num_desc >= MAX_ADAPTERS) { wpa_printf(MSG_DEBUG, "NDIS: Too many adapter " "descriptions"); free(names); return -1; } if (*pos == '\0') { wpa_printf(MSG_DEBUG, "NDIS: %d adapter descriptions " "found", num_name); pos++; break; } } /* * Windows 98 with Packet.dll 3.0 alpha3 does not include adapter * descriptions. Fill in dummy descriptors to work around this. */ while (num_desc < num_name) desc[num_desc++] = "dummy description"; if (num_name != num_desc) { wpa_printf(MSG_DEBUG, "NDIS: mismatch in adapter name and " "description counts (%d != %d)", num_name, num_desc); free(names); return -1; } found_name = found_desc = -1; for (i = 0; i < num_name; i++) { wpa_printf(MSG_DEBUG, "NDIS: %d - %s - %s", i, name[i], desc[i]); if (found_name == -1 && strcmp(name[i], drv->ifname) == 0) { found_name = i; } if (found_desc == -1 && strncmp(desc[i], drv->ifname, strlen(drv->ifname)) == 0) { found_desc = i; } } if (found_name < 0 && found_desc >= 0) { wpa_printf(MSG_DEBUG, "NDIS: Matched interface '%s' based on " "description '%s'", name[found_desc], desc[found_desc]); found_name = found_desc; strncpy(drv->ifname, name[found_desc], sizeof(drv->ifname)); } if (found_name < 0) { wpa_printf(MSG_DEBUG, "NDIS: Could not find interface '%s'", drv->ifname); free(names); return -1; } i = found_name; pos = strchr(desc[i], '('); if (pos) { dlen = pos - desc[i]; pos--; if (pos > desc[i] && *pos == ' ') dlen--; } else { dlen = strlen(desc[i]); } drv->adapter_desc = malloc(dlen + 1); if (drv->adapter_desc) { memcpy(drv->adapter_desc, desc[i], dlen); drv->adapter_desc[dlen] = '\0'; } free(names); if (drv->adapter_desc == NULL) return -1; wpa_printf(MSG_DEBUG, "NDIS: Adapter description prefix '%s'", drv->adapter_desc); return 0;}static void * wpa_driver_ndis_init(void *ctx, const char *ifname){ struct wpa_driver_ndis_data *drv; u32 mode; drv = malloc(sizeof(*drv)); if (drv == NULL) return NULL; memset(drv, 0, sizeof(*drv)); drv->ctx = ctx; strncpy(drv->ifname, ifname, sizeof(drv->ifname)); drv->event_sock = -1; if (wpa_driver_ndis_get_names(drv) < 0) { free(drv); return NULL; } drv->adapter = PacketOpenAdapter(drv->ifname); if (drv->adapter == NULL) { wpa_printf(MSG_DEBUG, "NDIS: PacketOpenAdapter failed for " "'%s'", drv->ifname); free(drv); return NULL; } if (ndis_get_oid(drv, OID_802_3_CURRENT_ADDRESS, drv->own_addr, ETH_ALEN) < 0) { wpa_printf(MSG_DEBUG, "NDIS: Get OID_802_3_CURRENT_ADDRESS " "failed"); PacketCloseAdapter(drv->adapter); free(drv); return NULL; } wpa_driver_ndis_get_capability(drv); /* Make sure that the driver does not have any obsolete PMKID entries. */ wpa_driver_ndis_flush_pmkid(drv); eloop_register_timeout(1, 0, wpa_driver_ndis_poll_timeout, drv, NULL); wpa_driver_register_event_cb(drv); /* Set mode here in case card was configured for ad-hoc mode * previously. */ 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 (!drv->has_capability && drv->capa.enc == 0) { wpa_printf(MSG_DEBUG, "NDIS: Driver did not provide " "any wireless capabilities - assume it is " "a wired interface"); drv->wired = 1; } } return drv;}static void wpa_driver_ndis_deinit(void *priv){ struct wpa_driver_ndis_data *drv = priv; eloop_cancel_timeout(wpa_driver_ndis_poll_timeout, drv, NULL); wpa_driver_ndis_flush_pmkid(drv); wpa_driver_ndis_disconnect(drv); if (wpa_driver_ndis_radio_off(drv) < 0) { wpa_printf(MSG_DEBUG, "NDIS: failed to disassociate and turn " "radio off"); } if (drv->event_sock >= 0) { eloop_unregister_read_sock(drv->event_sock); close(drv->event_sock); } if (drv->adapter) PacketCloseAdapter(drv->adapter); free(drv->adapter_desc); free(drv);}const struct wpa_driver_ops wpa_driver_ndis_ops = { .name = "ndis", .desc = "Windows NDIS driver", .init = wpa_driver_ndis_init, .deinit = wpa_driver_ndis_deinit, .set_wpa = wpa_driver_ndis_set_wpa, .scan = wpa_driver_ndis_scan, .get_scan_results = wpa_driver_ndis_get_scan_results, .get_bssid = wpa_driver_ndis_get_bssid, .get_ssid = wpa_driver_ndis_get_ssid, .set_key = wpa_driver_ndis_set_key, .associate = wpa_driver_ndis_associate, .deauthenticate = wpa_driver_ndis_deauthenticate, .disassociate = wpa_driver_ndis_disassociate, .poll = wpa_driver_ndis_poll, .add_pmkid = wpa_driver_ndis_add_pmkid, .remove_pmkid = wpa_driver_ndis_remove_pmkid, .flush_pmkid = wpa_driver_ndis_flush_pmkid, .get_capa = wpa_driver_ndis_get_capa, .get_ifname = wpa_driver_ndis_get_ifname, .get_mac_addr = wpa_driver_ndis_get_mac_addr,};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -