📄 driver_ndis.c
字号:
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", 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; } pos = (WCHAR *) ((char *) b + b->DeviceNameOffset); len = b->DeviceNameLength; if (len >= sizeof(name)) len = sizeof(name) - 1; for (j = 0; j < len; j++) name[j] = (char) pos[j]; name[len] = '\0'; pos = (WCHAR *) ((char *) b + b->DeviceDescrOffset); len = b->DeviceDescrLength; if (len >= sizeof(desc)) len = sizeof(desc) - 1; for (j = 0; j < len; j++) desc[j] = (char) pos[j]; desc[len] = '\0'; wpa_printf(MSG_DEBUG, "NDIS: %d - %s - %s", i, name, desc); if (os_strstr(name, drv->ifname)) { wpa_printf(MSG_DEBUG, "NDIS: Interface name match"); found = 1; break; } if (os_strncmp(desc, drv->ifname, os_strlen(drv->ifname)) == 0) { wpa_printf(MSG_DEBUG, "NDIS: Interface description " "match"); found = 1; break; } } if (!found) { wpa_printf(MSG_DEBUG, "NDIS: Could not find interface '%s'", drv->ifname); os_free(b); return -1; } os_strlcpy(drv->ifname, os_strncmp(name, "\\DEVICE\\", 8) == 0 ? name + 8 : name, sizeof(drv->ifname));#ifdef _WIN32_WCE drv->adapter_name = wpa_strdup_tchar(drv->ifname); if (drv->adapter_name == NULL) { wpa_printf(MSG_ERROR, "NDIS: Failed to allocate memory for " "adapter name"); os_free(b); return -1; }#endif /* _WIN32_WCE */ dpos = os_strstr(desc, " - ");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -