📄 driver_ndis.c
字号:
/* * WPA Supplicant - Windows/NDIS driver interface * Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Alternatively, this software may be distributed under the terms of BSD * license. * * See README and COPYING for more details. */#include <stdlib.h>#include <Packet32.h>#include <stdio.h>#include <string.h>#include <sys/unistd.h>#include <ntddndis.h>#include "common.h"#include "driver.h"#include "wpa_supplicant.h"#include "l2_packet.h"#include "eloop.h"#include "wpa.h"#include "driver_ndis.h"int wpa_driver_register_event_cb(struct wpa_driver_ndis_data *drv);static void wpa_driver_ndis_poll(void *drv);/* FIX: to be removed once this can be compiled with the complete NDIS * header files */#ifndef OID_802_11_BSSID#define OID_802_11_BSSID 0x0d010101#define OID_802_11_SSID 0x0d010102#define OID_802_11_INFRASTRUCTURE_MODE 0x0d010108#define OID_802_11_ADD_WEP 0x0D010113#define OID_802_11_REMOVE_WEP 0x0D010114#define OID_802_11_DISASSOCIATE 0x0D010115#define OID_802_11_BSSID_LIST 0x0d010217#define OID_802_11_AUTHENTICATION_MODE 0x0d010118#define OID_802_11_PRIVACY_FILTER 0x0d010119#define OID_802_11_BSSID_LIST_SCAN 0x0d01011A#define OID_802_11_WEP_STATUS 0x0d01011B#define OID_802_11_ENCRYPTION_STATUS OID_802_11_WEP_STATUS#define OID_802_11_ADD_KEY 0x0d01011D#define OID_802_11_REMOVE_KEY 0x0d01011E#define OID_802_11_ASSOCIATION_INFORMATION 0x0d01011F#define OID_802_11_TEST 0x0d010120#define OID_802_11_CAPABILITY 0x0d010122#define OID_802_11_PMKID 0x0d010123#define NDIS_802_11_LENGTH_SSID 32#define NDIS_802_11_LENGTH_RATES 8#define NDIS_802_11_LENGTH_RATES_EX 16typedef UCHAR NDIS_802_11_MAC_ADDRESS[6];typedef struct NDIS_802_11_SSID { ULONG SsidLength; UCHAR Ssid[NDIS_802_11_LENGTH_SSID];} NDIS_802_11_SSID;typedef LONG NDIS_802_11_RSSI;typedef enum NDIS_802_11_NETWORK_TYPE { Ndis802_11FH, Ndis802_11DS, Ndis802_11OFDM5, Ndis802_11OFDM24, Ndis802_11NetworkTypeMax} NDIS_802_11_NETWORK_TYPE;typedef struct NDIS_802_11_CONFIGURATION_FH { ULONG Length; ULONG HopPattern; ULONG HopSet; ULONG DwellTime;} NDIS_802_11_CONFIGURATION_FH;typedef struct NDIS_802_11_CONFIGURATION { ULONG Length; ULONG BeaconPeriod; ULONG ATIMWindow; ULONG DSConfig; NDIS_802_11_CONFIGURATION_FH FHConfig;} NDIS_802_11_CONFIGURATION;typedef enum NDIS_802_11_NETWORK_INFRASTRUCTURE { Ndis802_11IBSS, Ndis802_11Infrastructure, Ndis802_11AutoUnknown, Ndis802_11InfrastructureMax} NDIS_802_11_NETWORK_INFRASTRUCTURE;typedef enum NDIS_802_11_AUTHENTICATION_MODE { Ndis802_11AuthModeOpen, Ndis802_11AuthModeShared, Ndis802_11AuthModeAutoSwitch, Ndis802_11AuthModeWPA, Ndis802_11AuthModeWPAPSK, Ndis802_11AuthModeWPANone, Ndis802_11AuthModeWPA2, Ndis802_11AuthModeWPA2PSK, Ndis802_11AuthModeMax} NDIS_802_11_AUTHENTICATION_MODE;typedef enum NDIS_802_11_WEP_STATUS { Ndis802_11WEPEnabled, Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled, Ndis802_11WEPDisabled, Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled, Ndis802_11WEPKeyAbsent, Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent, Ndis802_11WEPNotSupported, Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported, Ndis802_11Encryption2Enabled, Ndis802_11Encryption2KeyAbsent, Ndis802_11Encryption3Enabled, Ndis802_11Encryption3KeyAbsent} NDIS_802_11_WEP_STATUS, NDIS_802_11_ENCRYPTION_STATUS;typedef enum NDIS_802_11_PRIVACY_FILTER { Ndis802_11PrivFilterAcceptAll, Ndis802_11PrivFilter8021xWEP} NDIS_802_11_PRIVACY_FILTER;typedef UCHAR NDIS_802_11_RATES[NDIS_802_11_LENGTH_RATES];typedef UCHAR NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX];typedef struct NDIS_WLAN_BSSID_EX { ULONG Length; NDIS_802_11_MAC_ADDRESS MacAddress; /* BSSID */ UCHAR Reserved[2]; NDIS_802_11_SSID Ssid; ULONG Privacy; NDIS_802_11_RSSI Rssi; NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; NDIS_802_11_CONFIGURATION Configuration; NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode; NDIS_802_11_RATES_EX SupportedRates; ULONG IELength; UCHAR IEs[1];} NDIS_WLAN_BSSID_EX;typedef struct NDIS_802_11_BSSID_LIST_EX { ULONG NumberOfItems; NDIS_WLAN_BSSID_EX Bssid[1];} NDIS_802_11_BSSID_LIST_EX;typedef struct NDIS_802_11_FIXED_IEs { UCHAR Timestamp[8]; USHORT BeaconInterval; USHORT Capabilities;} NDIS_802_11_FIXED_IEs;typedef struct NDIS_802_11_WEP { ULONG Length; ULONG KeyIndex; ULONG KeyLength; UCHAR KeyMaterial[1];} NDIS_802_11_WEP;typedef ULONG NDIS_802_11_KEY_INDEX;typedef ULONGLONG NDIS_802_11_KEY_RSC;typedef struct NDIS_802_11_KEY { ULONG Length; ULONG KeyIndex; ULONG KeyLength; NDIS_802_11_MAC_ADDRESS BSSID; NDIS_802_11_KEY_RSC KeyRSC; UCHAR KeyMaterial[1];} NDIS_802_11_KEY;typedef struct NDIS_802_11_REMOVE_KEY { ULONG Length; ULONG KeyIndex; NDIS_802_11_MAC_ADDRESS BSSID;} NDIS_802_11_REMOVE_KEY;typedef struct NDIS_802_11_AI_REQFI { USHORT Capabilities; USHORT ListenInterval; NDIS_802_11_MAC_ADDRESS CurrentAPAddress;} NDIS_802_11_AI_REQFI;typedef struct NDIS_802_11_AI_RESFI { USHORT Capabilities; USHORT StatusCode; USHORT AssociationId;} NDIS_802_11_AI_RESFI;typedef struct NDIS_802_11_ASSOCIATION_INFORMATION { ULONG Length; USHORT AvailableRequestFixedIEs; NDIS_802_11_AI_REQFI RequestFixedIEs; ULONG RequestIELength; ULONG OffsetRequestIEs; USHORT AvailableResponseFixedIEs; NDIS_802_11_AI_RESFI ResponseFixedIEs; ULONG ResponseIELength; ULONG OffsetResponseIEs;} NDIS_802_11_ASSOCIATION_INFORMATION;typedef struct NDIS_802_11_AUTHENTICATION_ENCRYPTION { NDIS_802_11_AUTHENTICATION_MODE AuthModeSupported; NDIS_802_11_ENCRYPTION_STATUS EncryptStatusSupported;} NDIS_802_11_AUTHENTICATION_ENCRYPTION;typedef struct NDIS_802_11_CAPABILITY { ULONG Length; ULONG Version; ULONG NoOfPMKIDs; ULONG NoOfAuthEncryptPairSupported; NDIS_802_11_AUTHENTICATION_ENCRYPTION AuthenticationEncryptionSupported[1];} NDIS_802_11_CAPABILITY;typedef UCHAR NDIS_802_11_PMKID_VALUE[16];typedef struct BSSID_INFO { NDIS_802_11_MAC_ADDRESS BSSID; NDIS_802_11_PMKID_VALUE PMKID;} BSSID_INFO;typedef struct NDIS_802_11_PMKID { ULONG Length; ULONG BSSIDInfoCount; BSSID_INFO BSSIDInfo[1];} NDIS_802_11_PMKID;typedef enum NDIS_802_11_STATUS_TYPE { Ndis802_11StatusType_Authentication, Ndis802_11StatusType_PMKID_CandidateList = 2, Ndis802_11StatusTypeMax} NDIS_802_11_STATUS_TYPE;typedef struct NDIS_802_11_STATUS_INDICATION { NDIS_802_11_STATUS_TYPE StatusType;} NDIS_802_11_STATUS_INDICATION;typedef struct PMKID_CANDIDATE { NDIS_802_11_MAC_ADDRESS BSSID; ULONG Flags;} PMKID_CANDIDATE;#define NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01typedef struct NDIS_802_11_PMKID_CANDIDATE_LIST { ULONG Version; ULONG NumCandidates; PMKID_CANDIDATE CandidateList[1];} NDIS_802_11_PMKID_CANDIDATE_LIST;typedef struct NDIS_802_11_AUTHENTICATION_REQUEST { ULONG Length; NDIS_802_11_MAC_ADDRESS Bssid; ULONG Flags;} NDIS_802_11_AUTHENTICATION_REQUEST;#define NDIS_802_11_AUTH_REQUEST_REAUTH 0x01#define NDIS_802_11_AUTH_REQUEST_KEYUPDATE 0x02#define NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR 0x06#define NDIS_802_11_AUTH_REQUEST_GROUP_ERROR 0x0E#endifstatic int ndis_get_oid(struct wpa_driver_ndis_data *drv, unsigned int oid, char *data, int len){ char *buf; PACKET_OID_DATA *o; int ret; buf = malloc(sizeof(*o) + len); if (buf == NULL) return -1; memset(buf, 0, sizeof(*o) + len); o = (PACKET_OID_DATA *) buf; o->Oid = oid; o->Length = len; if (!PacketRequest(drv->adapter, FALSE, o)) { wpa_printf(MSG_DEBUG, "%s: oid=0x%x len (%d) failed", __func__, oid, len); free(buf); return -1; } if (o->Length > len) { wpa_printf(MSG_DEBUG, "%s: oid=0x%x Length (%d) > len (%d)", __func__, oid, (unsigned int) o->Length, len); free(buf); return -1; } memcpy(data, o->Data, o->Length); ret = o->Length; free(buf); return ret;}static int ndis_set_oid(struct wpa_driver_ndis_data *drv, unsigned int oid, char *data, int len){ char *buf; PACKET_OID_DATA *o; buf = malloc(sizeof(*o) + len); if (buf == NULL) return -1; memset(buf, 0, sizeof(*o) + len); o = (PACKET_OID_DATA *) buf; o->Oid = oid; o->Length = len; if (data) 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); free(buf); return -1; } free(buf); return 0;}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; } 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; memset(&buf, 0, sizeof(buf)); buf.SsidLength = ssid_len; 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_register_timeout(3, 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 && memcmp(pos + 2, "\x00\x50\xf2\x01", 4) == 0) { memcpy(res->wpa_ie, pos, ielen); res->wpa_ie_len = ielen; } else if (pos[0] == RSN_INFO_ELEM) { 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; int len, count, i, j; char *pos; blen = 65535; b = malloc(blen);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -