📄 driver_ndis.c
字号:
const u8 *data, size_t data_len){ NDIS_802_11_PMKID_CANDIDATE_LIST *pmkid; size_t 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; } os_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); os_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; }}/* Called when an adapter is added */void wpa_driver_ndis_event_adapter_arrival(struct wpa_driver_ndis_data *drv){ union wpa_event_data event; int i; wpa_printf(MSG_DEBUG, "NDIS: Notify Adapter Arrival"); for (i = 0; i < 30; i++) { /* Re-open Packet32/NDISUIO connection */ wpa_driver_ndis_adapter_close(drv); if (wpa_driver_ndis_adapter_init(drv) < 0 || wpa_driver_ndis_adapter_open(drv) < 0) { wpa_printf(MSG_DEBUG, "NDIS: Driver re-initialization " "(%d) failed", i); os_sleep(1, 0); } else { wpa_printf(MSG_DEBUG, "NDIS: Driver re-initialized"); break; } } os_memset(&event, 0, sizeof(event)); os_strlcpy(event.interface_status.ifname, drv->ifname, sizeof(event.interface_status.ifname)); event.interface_status.ievent = EVENT_INTERFACE_ADDED; wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);}/* Called when an adapter is removed */void wpa_driver_ndis_event_adapter_removal(struct wpa_driver_ndis_data *drv){ union wpa_event_data event; wpa_printf(MSG_DEBUG, "NDIS: Notify Adapter Removal"); os_memset(&event, 0, sizeof(event)); os_strlcpy(event.interface_status.ifname, drv->ifname, sizeof(event.interface_status.ifname)); event.interface_status.ievent = EVENT_INTERFACE_REMOVED; wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);}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; size_t i; NDIS_802_11_CAPABILITY *c; drv->capa.flags = WPA_DRIVER_FLAGS_DRIVER_IE; 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", (u8 *) 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->NoOfAuthEncryptPairsSupported); drv->has_capability = 1; drv->no_of_pmkid = c->NoOfPMKIDs; for (i = 0; i < c->NoOfAuthEncryptPairsSupported; 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; os_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;}#ifdef _WIN32_WCE#define NDISUIO_MSG_SIZE (sizeof(NDISUIO_DEVICE_NOTIFICATION) + 512)static void ndisuio_notification_receive(void *eloop_data, void *user_ctx){ struct wpa_driver_ndis_data *drv = eloop_data; NDISUIO_DEVICE_NOTIFICATION *hdr; u8 buf[NDISUIO_MSG_SIZE]; DWORD len, flags; if (!ReadMsgQueue(drv->event_queue, buf, NDISUIO_MSG_SIZE, &len, 0, &flags)) { wpa_printf(MSG_DEBUG, "ndisuio_notification_receive: " "ReadMsgQueue failed: %d", (int) GetLastError()); return; } if (len < sizeof(NDISUIO_DEVICE_NOTIFICATION)) { wpa_printf(MSG_DEBUG, "ndisuio_notification_receive: " "Too short message (len=%d)", (int) len); return; } hdr = (NDISUIO_DEVICE_NOTIFICATION *) buf; wpa_printf(MSG_DEBUG, "NDIS: Notification received: len=%d type=0x%x", (int) len, hdr->dwNotificationType); switch (hdr->dwNotificationType) {#ifdef NDISUIO_NOTIFICATION_ADAPTER_ARRIVAL case NDISUIO_NOTIFICATION_ADAPTER_ARRIVAL: wpa_printf(MSG_DEBUG, "NDIS: ADAPTER_ARRIVAL"); wpa_driver_ndis_event_adapter_arrival(drv); break;#endif#ifdef NDISUIO_NOTIFICATION_ADAPTER_REMOVAL case NDISUIO_NOTIFICATION_ADAPTER_REMOVAL: wpa_printf(MSG_DEBUG, "NDIS: ADAPTER_REMOVAL"); wpa_driver_ndis_event_adapter_removal(drv); break;#endif case NDISUIO_NOTIFICATION_MEDIA_CONNECT: wpa_printf(MSG_DEBUG, "NDIS: MEDIA_CONNECT"); SetEvent(drv->connected_event); wpa_driver_ndis_event_connect(drv); break; case NDISUIO_NOTIFICATION_MEDIA_DISCONNECT: ResetEvent(drv->connected_event); wpa_printf(MSG_DEBUG, "NDIS: MEDIA_DISCONNECT"); wpa_driver_ndis_event_disconnect(drv); break; case NDISUIO_NOTIFICATION_MEDIA_SPECIFIC_NOTIFICATION: wpa_printf(MSG_DEBUG, "NDIS: MEDIA_SPECIFIC_NOTIFICATION");#if _WIN32_WCE == 420 || _WIN32_WCE == 0x420 wpa_driver_ndis_event_media_specific( drv, hdr->pvStatusBuffer, hdr->uiStatusBufferSize);#else wpa_driver_ndis_event_media_specific( drv, ((const u8 *) hdr) + hdr->uiOffsetToStatusBuffer, (size_t) hdr->uiStatusBufferSize);#endif break; default: wpa_printf(MSG_DEBUG, "NDIS: Unknown notification type 0x%x", hdr->dwNotificationType); break; }}static void ndisuio_notification_deinit(struct wpa_driver_ndis_data *drv){ NDISUIO_REQUEST_NOTIFICATION req; memset(&req, 0, sizeof(req)); req.hMsgQueue = drv->event_queue; req.dwNotificationTypes = 0; if (!DeviceIoControl(drv->ndisuio, IOCTL_NDISUIO_REQUEST_NOTIFICATION, &req, sizeof(req), NULL, 0, NULL, NULL)) { wpa_printf(MSG_INFO, "ndisuio_notification_deinit: " "IOCTL_NDISUIO_REQUEST_NOTIFICATION failed: %d", (int) GetLastError()); } if (!DeviceIoControl(drv->ndisuio, IOCTL_NDISUIO_CANCEL_NOTIFICATION, NULL, 0, NULL, 0, NULL, NULL)) { wpa_printf(MSG_INFO, "ndisuio_notification_deinit: " "IOCTL_NDISUIO_CANCEL_NOTIFICATION failed: %d", (int) GetLastError()); } if (drv->event_queue) { eloop_unregister_event(drv->event_queue, sizeof(drv->event_queue)); CloseHandle(drv->event_queue); drv->event_queue = NULL; } if (drv->connected_event) { CloseHandle(drv->connected_event); drv->connected_event = NULL; }}static int ndisuio_notification_init(struct wpa_driver_ndis_data *drv){ MSGQUEUEOPTIONS opt; NDISUIO_REQUEST_NOTIFICATION req; drv->connected_event = CreateEvent(NULL, TRUE, FALSE, TEXT("WpaSupplicantConnected")); if (drv->connected_event == NULL) { wpa_printf(MSG_INFO, "ndisuio_notification_init: " "CreateEvent failed: %d", (int) GetLastError()); return -1; } memset(&opt, 0, sizeof(opt)); opt.dwSize = sizeof(opt); opt.dwMaxMessages = 5; opt.cbMaxMessage = NDISUIO_MSG_SIZE; opt.bReadAccess = TRUE; drv->event_queue = CreateMsgQueue(NULL, &opt); if (drv->event_queue == NULL) { wpa_printf(MSG_INFO, "ndisuio_notification_init: " "CreateMsgQueue failed: %d", (int) GetLastError()); ndisuio_notification_deinit(drv); return -1; } memset(&req, 0, sizeof(req)); req.hMsgQueue = drv->event_queue; req.dwNotificationTypes =#ifdef NDISUIO_NOTIFICATION_ADAPTER_ARRIVAL NDISUIO_NOTIFICATION_ADAPTER_ARRIVAL |#endif#ifdef NDISUIO_NOTIFICATION_ADAPTER_REMOVAL NDISUIO_NOTIFICATION_ADAPTER_REMOVAL |#endif NDISUIO_NOTIFICATION_MEDIA_CONNECT | NDISUIO_NOTIFICATION_MEDIA_DISCONNECT | NDISUIO_NOTIFICATION_MEDIA_SPECIFIC_NOTIFICATION; if (!DeviceIoControl(drv->ndisuio, IOCTL_NDISUIO_REQUEST_NOTIFICATION, &req, sizeof(req), NULL, 0, NULL, NULL)) { wpa_printf(MSG_INFO, "ndisuio_notification_init: " "IOCTL_NDISUIO_REQUEST_NOTIFICATION failed: %d", (int) GetLastError()); ndisuio_notification_deinit(drv); return -1; } eloop_register_event(drv->event_queue, sizeof(drv->event_queue), ndisuio_notification_receive, drv, NULL); return 0;}#endif /* _WIN32_WCE */static int wpa_driver_ndis_get_names(struct wpa_driver_ndis_data *drv){#ifdef CONFIG_USE_NDISUIO NDISUIO_QUERY_BINDING *b; size_t blen = sizeof(*b) + 1024; int i, error, found = 0; DWORD written; char name[256], desc[256], *dpos; WCHAR *pos; size_t j, len, dlen; b = os_malloc(blen); if (b == NULL) return -1; for (i = 0; ; i++) { os_memset(b, 0, blen); b->BindingIndex = i; if (!DeviceIoControl(drv->ndisuio, IOCTL_NDISUIO_QUERY_BINDING, b, sizeof(NDISUIO_QUERY_BINDING), b, blen, &written, NULL)) { error = (int) GetLastError(); if (error == ERROR_NO_MORE_ITEMS) break; wpa_printf(MSG_DEBUG, "IOCTL_NDISUIO_QUERY_BINDING " "failed: %d", error); break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -