18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPA Supplicant - Windows/NDIS driver interface 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef __CYGWIN__ 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Avoid some header file conflicts by not including standard headers for 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * cygwin builds when Packet32.h is included. */ 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "build_config.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint close(int fd); 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* __CYGWIN__ */ 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* __CYGWIN__ */ 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_USE_NDISUIO 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <winsock2.h> 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_USE_NDISUIO */ 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <Packet32.h> 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_USE_NDISUIO */ 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef __MINGW32_VERSION 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <ddk/ntddndis.h> 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* __MINGW32_VERSION */ 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <ntddndis.h> 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* __MINGW32_VERSION */ 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef _WIN32_WCE 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <winioctl.h> 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <nuiouser.h> 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <devload.h> 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "driver.h" 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h" 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h" 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "driver_ndis.h" 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_driver_register_event_cb(struct wpa_driver_ndis_data *drv); 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_NDIS_EVENTS_INTEGRATED 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_driver_ndis_event_pipe_cb(void *eloop_data, void *user_data); 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NDIS_EVENTS_INTEGRATED */ 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_driver_ndis_deinit(void *priv); 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_driver_ndis_poll(void *drv); 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_driver_ndis_poll_timeout(void *eloop_ctx, void *timeout_ctx); 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_adapter_init(struct wpa_driver_ndis_data *drv); 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_adapter_open(struct wpa_driver_ndis_data *drv); 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_driver_ndis_adapter_close(struct wpa_driver_ndis_data *drv); 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const u8 pae_group_addr[ETH_ALEN] = 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 }; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* FIX: to be removed once this can be compiled with the complete NDIS 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * header files */ 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OID_802_11_BSSID 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define OID_802_11_BSSID 0x0d010101 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define OID_802_11_SSID 0x0d010102 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define OID_802_11_INFRASTRUCTURE_MODE 0x0d010108 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define OID_802_11_ADD_WEP 0x0D010113 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define OID_802_11_REMOVE_WEP 0x0D010114 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define OID_802_11_DISASSOCIATE 0x0D010115 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define OID_802_11_BSSID_LIST 0x0d010217 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define OID_802_11_AUTHENTICATION_MODE 0x0d010118 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define OID_802_11_PRIVACY_FILTER 0x0d010119 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define OID_802_11_BSSID_LIST_SCAN 0x0d01011A 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define OID_802_11_WEP_STATUS 0x0d01011B 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define OID_802_11_ENCRYPTION_STATUS OID_802_11_WEP_STATUS 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define OID_802_11_ADD_KEY 0x0d01011D 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define OID_802_11_REMOVE_KEY 0x0d01011E 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define OID_802_11_ASSOCIATION_INFORMATION 0x0d01011F 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define OID_802_11_TEST 0x0d010120 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define OID_802_11_CAPABILITY 0x0d010122 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define OID_802_11_PMKID 0x0d010123 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define NDIS_802_11_LENGTH_SSID 32 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define NDIS_802_11_LENGTH_RATES 8 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define NDIS_802_11_LENGTH_RATES_EX 16 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef UCHAR NDIS_802_11_MAC_ADDRESS[6]; 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct NDIS_802_11_SSID { 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG SsidLength; 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt UCHAR Ssid[NDIS_802_11_LENGTH_SSID]; 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_SSID; 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef LONG NDIS_802_11_RSSI; 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef enum NDIS_802_11_NETWORK_TYPE { 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11FH, 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11DS, 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11OFDM5, 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11OFDM24, 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11NetworkTypeMax 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_NETWORK_TYPE; 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct NDIS_802_11_CONFIGURATION_FH { 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG Length; 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG HopPattern; 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG HopSet; 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG DwellTime; 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_CONFIGURATION_FH; 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct NDIS_802_11_CONFIGURATION { 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG Length; 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG BeaconPeriod; 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG ATIMWindow; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG DSConfig; 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_CONFIGURATION_FH FHConfig; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_CONFIGURATION; 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef enum NDIS_802_11_NETWORK_INFRASTRUCTURE { 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11IBSS, 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11Infrastructure, 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11AutoUnknown, 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11InfrastructureMax 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_NETWORK_INFRASTRUCTURE; 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef enum NDIS_802_11_AUTHENTICATION_MODE { 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11AuthModeOpen, 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11AuthModeShared, 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11AuthModeAutoSwitch, 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11AuthModeWPA, 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11AuthModeWPAPSK, 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11AuthModeWPANone, 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11AuthModeWPA2, 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11AuthModeWPA2PSK, 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11AuthModeMax 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_AUTHENTICATION_MODE; 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef enum NDIS_802_11_WEP_STATUS { 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11WEPEnabled, 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled, 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11WEPDisabled, 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled, 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11WEPKeyAbsent, 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent, 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11WEPNotSupported, 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported, 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11Encryption2Enabled, 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11Encryption2KeyAbsent, 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11Encryption3Enabled, 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11Encryption3KeyAbsent 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_WEP_STATUS, NDIS_802_11_ENCRYPTION_STATUS; 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef enum NDIS_802_11_PRIVACY_FILTER { 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11PrivFilterAcceptAll, 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11PrivFilter8021xWEP 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_PRIVACY_FILTER; 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef UCHAR NDIS_802_11_RATES[NDIS_802_11_LENGTH_RATES]; 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef UCHAR NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX]; 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct NDIS_WLAN_BSSID_EX { 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG Length; 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_MAC_ADDRESS MacAddress; /* BSSID */ 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt UCHAR Reserved[2]; 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_SSID Ssid; 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG Privacy; 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_RSSI Rssi; 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_NETWORK_TYPE NetworkTypeInUse; 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_CONFIGURATION Configuration; 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode; 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_RATES_EX SupportedRates; 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG IELength; 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt UCHAR IEs[1]; 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_WLAN_BSSID_EX; 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct NDIS_802_11_BSSID_LIST_EX { 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG NumberOfItems; 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_WLAN_BSSID_EX Bssid[1]; 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_BSSID_LIST_EX; 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct NDIS_802_11_FIXED_IEs { 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt UCHAR Timestamp[8]; 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt USHORT BeaconInterval; 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt USHORT Capabilities; 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_FIXED_IEs; 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct NDIS_802_11_WEP { 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG Length; 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG KeyIndex; 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG KeyLength; 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt UCHAR KeyMaterial[1]; 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_WEP; 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef ULONG NDIS_802_11_KEY_INDEX; 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef ULONGLONG NDIS_802_11_KEY_RSC; 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct NDIS_802_11_KEY { 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG Length; 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG KeyIndex; 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG KeyLength; 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_MAC_ADDRESS BSSID; 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_KEY_RSC KeyRSC; 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt UCHAR KeyMaterial[1]; 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_KEY; 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct NDIS_802_11_REMOVE_KEY { 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG Length; 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG KeyIndex; 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_MAC_ADDRESS BSSID; 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_REMOVE_KEY; 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct NDIS_802_11_AI_REQFI { 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt USHORT Capabilities; 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt USHORT ListenInterval; 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_MAC_ADDRESS CurrentAPAddress; 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_AI_REQFI; 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct NDIS_802_11_AI_RESFI { 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt USHORT Capabilities; 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt USHORT StatusCode; 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt USHORT AssociationId; 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_AI_RESFI; 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct NDIS_802_11_ASSOCIATION_INFORMATION { 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG Length; 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt USHORT AvailableRequestFixedIEs; 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_AI_REQFI RequestFixedIEs; 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG RequestIELength; 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG OffsetRequestIEs; 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt USHORT AvailableResponseFixedIEs; 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_AI_RESFI ResponseFixedIEs; 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG ResponseIELength; 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG OffsetResponseIEs; 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_ASSOCIATION_INFORMATION; 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct NDIS_802_11_AUTHENTICATION_ENCRYPTION { 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_AUTHENTICATION_MODE AuthModeSupported; 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_ENCRYPTION_STATUS EncryptStatusSupported; 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_AUTHENTICATION_ENCRYPTION; 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct NDIS_802_11_CAPABILITY { 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG Length; 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG Version; 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG NoOfPMKIDs; 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG NoOfAuthEncryptPairsSupported; 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_AUTHENTICATION_ENCRYPTION 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AuthenticationEncryptionSupported[1]; 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_CAPABILITY; 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef UCHAR NDIS_802_11_PMKID_VALUE[16]; 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct BSSID_INFO { 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_MAC_ADDRESS BSSID; 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_PMKID_VALUE PMKID; 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} BSSID_INFO; 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct NDIS_802_11_PMKID { 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG Length; 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG BSSIDInfoCount; 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BSSID_INFO BSSIDInfo[1]; 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_PMKID; 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef enum NDIS_802_11_STATUS_TYPE { 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11StatusType_Authentication, 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11StatusType_PMKID_CandidateList = 2, 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt Ndis802_11StatusTypeMax 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_STATUS_TYPE; 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct NDIS_802_11_STATUS_INDICATION { 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_STATUS_TYPE StatusType; 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_STATUS_INDICATION; 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct PMKID_CANDIDATE { 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_MAC_ADDRESS BSSID; 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG Flags; 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} PMKID_CANDIDATE; 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct NDIS_802_11_PMKID_CANDIDATE_LIST { 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG Version; 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG NumCandidates; 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PMKID_CANDIDATE CandidateList[1]; 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_PMKID_CANDIDATE_LIST; 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct NDIS_802_11_AUTHENTICATION_REQUEST { 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG Length; 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_MAC_ADDRESS Bssid; 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG Flags; 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_AUTHENTICATION_REQUEST; 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define NDIS_802_11_AUTH_REQUEST_REAUTH 0x01 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define NDIS_802_11_AUTH_REQUEST_KEYUPDATE 0x02 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR 0x06 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define NDIS_802_11_AUTH_REQUEST_GROUP_ERROR 0x0E 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OID_802_11_BSSID */ 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OID_802_11_PMKID 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Platform SDK for XP did not include WPA2, so add needed definitions */ 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define OID_802_11_CAPABILITY 0x0d010122 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define OID_802_11_PMKID 0x0d010123 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define Ndis802_11AuthModeWPA2 6 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define Ndis802_11AuthModeWPA2PSK 7 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define Ndis802_11StatusType_PMKID_CandidateList 2 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct NDIS_802_11_AUTHENTICATION_ENCRYPTION { 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_AUTHENTICATION_MODE AuthModeSupported; 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_ENCRYPTION_STATUS EncryptStatusSupported; 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_AUTHENTICATION_ENCRYPTION; 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct NDIS_802_11_CAPABILITY { 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG Length; 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG Version; 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG NoOfPMKIDs; 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG NoOfAuthEncryptPairsSupported; 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_AUTHENTICATION_ENCRYPTION 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt AuthenticationEncryptionSupported[1]; 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_CAPABILITY; 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef UCHAR NDIS_802_11_PMKID_VALUE[16]; 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct BSSID_INFO { 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_MAC_ADDRESS BSSID; 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_PMKID_VALUE PMKID; 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} BSSID_INFO; 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct NDIS_802_11_PMKID { 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG Length; 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG BSSIDInfoCount; 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BSSID_INFO BSSIDInfo[1]; 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_PMKID; 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct PMKID_CANDIDATE { 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_MAC_ADDRESS BSSID; 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG Flags; 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} PMKID_CANDIDATE; 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct NDIS_802_11_PMKID_CANDIDATE_LIST { 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG Version; 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG NumCandidates; 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PMKID_CANDIDATE CandidateList[1]; 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDIS_802_11_PMKID_CANDIDATE_LIST; 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OID_802_11_CAPABILITY */ 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef OID_DOT11_CURRENT_OPERATION_MODE 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Native 802.11 OIDs */ 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define OID_DOT11_NDIS_START 0x0D010300 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define OID_DOT11_CURRENT_OPERATION_MODE (OID_DOT11_NDIS_START + 8) 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define OID_DOT11_SCAN_REQUEST (OID_DOT11_NDIS_START + 11) 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef enum _DOT11_BSS_TYPE { 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dot11_BSS_type_infrastructure = 1, 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dot11_BSS_type_independent = 2, 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dot11_BSS_type_any = 3 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} DOT11_BSS_TYPE, * PDOT11_BSS_TYPE; 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef UCHAR DOT11_MAC_ADDRESS[6]; 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef DOT11_MAC_ADDRESS * PDOT11_MAC_ADDRESS; 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef enum _DOT11_SCAN_TYPE { 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dot11_scan_type_active = 1, 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dot11_scan_type_passive = 2, 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dot11_scan_type_auto = 3, 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dot11_scan_type_forced = 0x80000000 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} DOT11_SCAN_TYPE, * PDOT11_SCAN_TYPE; 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct _DOT11_SCAN_REQUEST_V2 { 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DOT11_BSS_TYPE dot11BSSType; 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DOT11_MAC_ADDRESS dot11BSSID; 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DOT11_SCAN_TYPE dot11ScanType; 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BOOLEAN bRestrictedScan; 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG udot11SSIDsOffset; 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG uNumOfdot11SSIDs; 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BOOLEAN bUseRequestIE; 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG uRequestIDsOffset; 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG uNumOfRequestIDs; 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG uPhyTypeInfosOffset; 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG uNumOfPhyTypeInfos; 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG uIEsOffset; 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG uIEsLength; 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt UCHAR ucBuffer[1]; 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} DOT11_SCAN_REQUEST_V2, * PDOT11_SCAN_REQUEST_V2; 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* OID_DOT11_CURRENT_OPERATION_MODE */ 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_USE_NDISUIO 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef _WIN32_WCE 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef __MINGW32_VERSION 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef ULONG NDIS_OID; 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* __MINGW32_VERSION */ 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* from nuiouser.h */ 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define FSCTL_NDISUIO_BASE FILE_DEVICE_NETWORK 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define _NDISUIO_CTL_CODE(_Function, _Method, _Access) \ 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CTL_CODE(FSCTL_NDISUIO_BASE, _Function, _Method, _Access) 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define IOCTL_NDISUIO_OPEN_DEVICE \ 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _NDISUIO_CTL_CODE(0x200, METHOD_BUFFERED, \ 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FILE_READ_ACCESS | FILE_WRITE_ACCESS) 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define IOCTL_NDISUIO_QUERY_OID_VALUE \ 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _NDISUIO_CTL_CODE(0x201, METHOD_BUFFERED, \ 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FILE_READ_ACCESS | FILE_WRITE_ACCESS) 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define IOCTL_NDISUIO_SET_OID_VALUE \ 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _NDISUIO_CTL_CODE(0x205, METHOD_BUFFERED, \ 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FILE_READ_ACCESS | FILE_WRITE_ACCESS) 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define IOCTL_NDISUIO_SET_ETHER_TYPE \ 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _NDISUIO_CTL_CODE(0x202, METHOD_BUFFERED, \ 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FILE_READ_ACCESS | FILE_WRITE_ACCESS) 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define IOCTL_NDISUIO_QUERY_BINDING \ 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _NDISUIO_CTL_CODE(0x203, METHOD_BUFFERED, \ 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FILE_READ_ACCESS | FILE_WRITE_ACCESS) 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define IOCTL_NDISUIO_BIND_WAIT \ 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _NDISUIO_CTL_CODE(0x204, METHOD_BUFFERED, \ 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FILE_READ_ACCESS | FILE_WRITE_ACCESS) 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct _NDISUIO_QUERY_OID 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_OID Oid; 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt UCHAR Data[sizeof(ULONG)]; 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDISUIO_QUERY_OID, *PNDISUIO_QUERY_OID; 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct _NDISUIO_SET_OID 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_OID Oid; 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt UCHAR Data[sizeof(ULONG)]; 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDISUIO_SET_OID, *PNDISUIO_SET_OID; 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct _NDISUIO_QUERY_BINDING 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG BindingIndex; 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG DeviceNameOffset; 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG DeviceNameLength; 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG DeviceDescrOffset; 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG DeviceDescrLength; 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} NDISUIO_QUERY_BINDING, *PNDISUIO_QUERY_BINDING; 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_USE_NDISUIO */ 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ndis_get_oid(struct wpa_driver_ndis_data *drv, unsigned int oid, 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *data, size_t len) 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_USE_NDISUIO 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDISUIO_QUERY_OID *o; 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t buflen = sizeof(*o) + len; 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD written; 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t hdrlen; 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt o = os_zalloc(buflen); 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (o == NULL) 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt o->Oid = oid; 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef _WIN32_WCE 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt o->ptcDeviceName = drv->adapter_name; 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!DeviceIoControl(drv->ndisuio, IOCTL_NDISUIO_QUERY_OID_VALUE, 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt o, sizeof(NDISUIO_QUERY_OID), o, buflen, &written, 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL)) { 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: IOCTL_NDISUIO_QUERY_OID_VALUE " 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed (oid=%08x): %d", oid, (int) GetLastError()); 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(o); 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdrlen = sizeof(NDISUIO_QUERY_OID) - sizeof(o->Data); 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (written < hdrlen) { 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: query oid=%08x written (%d); " 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "too short", oid, (unsigned int) written); 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(o); 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt written -= hdrlen; 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (written > len) { 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: query oid=%08x written (%d) > " 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "len (%d)",oid, (unsigned int) written, len); 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(o); 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(data, o->Data, written); 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = written; 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(o); 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_USE_NDISUIO */ 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf; 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PACKET_OID_DATA *o; 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_zalloc(sizeof(*o) + len); 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt o = (PACKET_OID_DATA *) buf; 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt o->Oid = oid; 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt o->Length = len; 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!PacketRequest(drv->adapter, FALSE, o)) { 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: oid=0x%x len (%d) failed", 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__, oid, len); 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (o->Length > len) { 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: oid=0x%x Length (%d) > len (%d)", 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__, oid, (unsigned int) o->Length, len); 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(data, o->Data, o->Length); 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = o->Length; 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_USE_NDISUIO */ 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ndis_set_oid(struct wpa_driver_ndis_data *drv, unsigned int oid, 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *data, size_t len) 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_USE_NDISUIO 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDISUIO_SET_OID *o; 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t buflen, reallen; 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD written; 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char txt[50]; 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(txt, sizeof(txt), "NDIS: Set OID %08x", oid); 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_MSGDUMP, txt, (const u8 *) data, len); 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buflen = sizeof(*o) + len; 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reallen = buflen - sizeof(o->Data); 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt o = os_zalloc(buflen); 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (o == NULL) 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt o->Oid = oid; 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef _WIN32_WCE 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt o->ptcDeviceName = drv->adapter_name; 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data) 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(o->Data, data, len); 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!DeviceIoControl(drv->ndisuio, IOCTL_NDISUIO_SET_OID_VALUE, 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt o, reallen, NULL, 0, &written, NULL)) { 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: IOCTL_NDISUIO_SET_OID_VALUE " 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(oid=%08x) failed: %d", oid, (int) GetLastError()); 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(o); 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(o); 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_USE_NDISUIO */ 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf; 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PACKET_OID_DATA *o; 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char txt[50]; 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(txt, sizeof(txt), "NDIS: Set OID %08x", oid); 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_MSGDUMP, txt, (const u8 *) data, len); 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_zalloc(sizeof(*o) + len); 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt o = (PACKET_OID_DATA *) buf; 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt o->Oid = oid; 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt o->Length = len; 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data) 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(o->Data, data, len); 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!PacketRequest(drv->adapter, TRUE, o)) { 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: oid=0x%x len (%d) failed", 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__, oid, len); 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_USE_NDISUIO */ 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ndis_set_auth_mode(struct wpa_driver_ndis_data *drv, int mode) 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 auth_mode = mode; 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis_set_oid(drv, OID_802_11_AUTHENTICATION_MODE, 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (char *) &auth_mode, sizeof(auth_mode)) < 0) { 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Failed to set " 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "OID_802_11_AUTHENTICATION_MODE (%d)", 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) auth_mode); 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ndis_get_auth_mode(struct wpa_driver_ndis_data *drv) 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 auth_mode; 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = ndis_get_oid(drv, OID_802_11_AUTHENTICATION_MODE, 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (char *) &auth_mode, sizeof(auth_mode)); 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res != sizeof(auth_mode)) { 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Failed to get " 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "OID_802_11_AUTHENTICATION_MODE"); 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return auth_mode; 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ndis_set_encr_status(struct wpa_driver_ndis_data *drv, int encr) 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 encr_status = encr; 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis_set_oid(drv, OID_802_11_ENCRYPTION_STATUS, 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (char *) &encr_status, sizeof(encr_status)) < 0) { 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Failed to set " 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "OID_802_11_ENCRYPTION_STATUS (%d)", encr); 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ndis_get_encr_status(struct wpa_driver_ndis_data *drv) 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 encr; 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = ndis_get_oid(drv, OID_802_11_ENCRYPTION_STATUS, 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (char *) &encr, sizeof(encr)); 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res != sizeof(encr)) { 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Failed to get " 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "OID_802_11_ENCRYPTION_STATUS"); 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return encr; 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_get_bssid(void *priv, u8 *bssid) 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->wired) { 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Report PAE group address as the "BSSID" for wired 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * connection. 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(bssid, pae_group_addr, ETH_ALEN); 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ndis_get_oid(drv, OID_802_11_BSSID, (char *) bssid, ETH_ALEN) < 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0 ? -1 : 0; 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_get_ssid(void *priv, u8 *ssid) 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_SSID buf; 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = ndis_get_oid(drv, OID_802_11_SSID, (char *) &buf, sizeof(buf)); 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 4) { 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Failed to get SSID"); 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->wired) { 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Allow get_ssid failure " 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "with a wired interface"); 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ssid, buf.Ssid, buf.SsidLength); 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf.SsidLength; 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_set_ssid(struct wpa_driver_ndis_data *drv, 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ssid, size_t ssid_len) 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_SSID buf; 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&buf, 0, sizeof(buf)); 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf.SsidLength = ssid_len; 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(buf.Ssid, ssid, ssid_len); 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Make sure radio is marked enabled here so that scan request will not 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * force SSID to be changed to a random one in order to enable radio at 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * that point. 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->radio_enabled = 1; 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ndis_set_oid(drv, OID_802_11_SSID, (char *) &buf, sizeof(buf)); 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Disconnect using OID_802_11_DISASSOCIATE. This will also turn the radio off. 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_radio_off(struct wpa_driver_ndis_data *drv) 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->radio_enabled = 0; 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ndis_set_oid(drv, OID_802_11_DISASSOCIATE, " ", 4); 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Disconnect by setting SSID to random (i.e., likely not used). */ 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_disconnect(struct wpa_driver_ndis_data *drv) 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char ssid[32]; 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 32; i++) 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid[i] = rand() & 0xff; 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_driver_ndis_set_ssid(drv, (u8 *) ssid, 32); 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_deauthenticate(void *priv, const u8 *addr, 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int reason_code) 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_driver_ndis_disconnect(drv); 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_disassociate(void *priv, const u8 *addr, 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int reason_code) 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_driver_ndis_disconnect(drv); 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_driver_ndis_scan_timeout(void *eloop_ctx, void *timeout_ctx) 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Scan timeout - try to get results"); 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL); 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_scan_native80211( 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv, 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_scan_params *params) 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DOT11_SCAN_REQUEST_V2 req; 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&req, 0, sizeof(req)); 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req.dot11BSSType = dot11_BSS_type_any; 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(req.dot11BSSID, 0xff, ETH_ALEN); 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req.dot11ScanType = dot11_scan_type_auto; 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = ndis_set_oid(drv, OID_DOT11_SCAN_REQUEST, (char *) &req, 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(req)); 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_driver_ndis_scan_timeout, drv, drv->ctx); 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(7, 0, wpa_driver_ndis_scan_timeout, drv, 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->ctx); 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_scan(void *priv, 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_scan_params *params) 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->native80211) 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_driver_ndis_scan_native80211(drv, params); 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!drv->radio_enabled) { 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: turning radio on before the first" 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " scan"); 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_driver_ndis_disconnect(drv) < 0) { 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: failed to enable radio"); 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->radio_enabled = 1; 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = ndis_set_oid(drv, OID_802_11_BSSID_LIST_SCAN, " ", 4); 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_driver_ndis_scan_timeout, drv, drv->ctx); 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(7, 0, wpa_driver_ndis_scan_timeout, drv, 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->ctx); 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie) 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *end, *pos; 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (const u8 *) (res + 1); 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + res->ie_len; 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos + 1 < end) { 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 2 + pos[1] > end) 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[0] == ie) 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos; 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2 + pos[1]; 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_scan_res * wpa_driver_ndis_add_scan_ssid( 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_res *r, NDIS_802_11_SSID *ssid) 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_res *nr; 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos; 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_scan_get_ie(r, WLAN_EID_SSID)) 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return r; /* SSID IE already present */ 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->SsidLength == 0 || ssid->SsidLength > 32) 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return r; /* No valid SSID inside scan data */ 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nr = os_realloc(r, sizeof(*r) + r->ie_len + 2 + ssid->SsidLength); 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (nr == NULL) 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return r; 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = ((u8 *) (nr + 1)) + nr->ie_len; 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = WLAN_EID_SSID; 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = ssid->SsidLength; 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, ssid->Ssid, ssid->SsidLength); 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nr->ie_len += 2 + ssid->SsidLength; 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return nr; 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_scan_results * wpa_driver_ndis_get_scan_results(void *priv) 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_BSSID_LIST_EX *b; 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t blen, count, i; 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len; 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pos; 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_results *results; 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_res *r; 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt blen = 65535; 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b = os_zalloc(blen); 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (b == NULL) 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = ndis_get_oid(drv, OID_802_11_BSSID_LIST, (char *) b, blen); 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 0) { 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: failed to get scan results"); 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(b); 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count = b->NumberOfItems; 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt results = os_zalloc(sizeof(*results)); 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (results == NULL) { 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(b); 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt results->res = os_zalloc(count * sizeof(struct wpa_scan_res *)); 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (results->res == NULL) { 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(results); 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(b); 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (char *) &b->Bssid[0]; 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < count; i++) { 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_WLAN_BSSID_EX *bss = (NDIS_WLAN_BSSID_EX *) pos; 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_FIXED_IEs *fixed; 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bss->IELength < sizeof(NDIS_802_11_FIXED_IEs)) { 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: too small IELength=%d", 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) bss->IELength); 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (((char *) bss->IEs) + bss->IELength > (char *) b + blen) { 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Some NDIS drivers have been reported to include an 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * entry with an invalid IELength in scan results and 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * this has crashed wpa_supplicant, so validate the 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * returned value before using it. 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: skipped invalid scan " 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "result IE (BSSID=" MACSTR ") IELength=%d", 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bss->MacAddress), 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) bss->IELength); 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = os_zalloc(sizeof(*r) + bss->IELength - 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(NDIS_802_11_FIXED_IEs)); 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (r == NULL) 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(r->bssid, bss->MacAddress, ETH_ALEN); 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r->level = (int) bss->Rssi; 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r->freq = bss->Configuration.DSConfig / 1000; 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fixed = (NDIS_802_11_FIXED_IEs *) bss->IEs; 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r->beacon_int = WPA_GET_LE16((u8 *) &fixed->BeaconInterval); 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r->caps = WPA_GET_LE16((u8 *) &fixed->Capabilities); 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r->tsf = WPA_GET_LE64(fixed->Timestamp); 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(r + 1, bss->IEs + sizeof(NDIS_802_11_FIXED_IEs), 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bss->IELength - sizeof(NDIS_802_11_FIXED_IEs)); 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r->ie_len = bss->IELength - sizeof(NDIS_802_11_FIXED_IEs); 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = wpa_driver_ndis_add_scan_ssid(r, &bss->Ssid); 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt results->res[results->num++] = r; 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += bss->Length; 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos > (char *) b + blen) 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(b); 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return results; 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_remove_key(struct wpa_driver_ndis_data *drv, 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int key_idx, const u8 *addr, 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *bssid, int pairwise) 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_REMOVE_KEY rkey; 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_KEY_INDEX index; 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res, res2; 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&rkey, 0, sizeof(rkey)); 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rkey.Length = sizeof(rkey); 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rkey.KeyIndex = key_idx; 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pairwise) 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rkey.KeyIndex |= 1 << 30; 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(rkey.BSSID, bssid, ETH_ALEN); 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = ndis_set_oid(drv, OID_802_11_REMOVE_KEY, (char *) &rkey, 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(rkey)); 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!pairwise) { 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt index = key_idx; 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res2 = ndis_set_oid(drv, OID_802_11_REMOVE_WEP, 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (char *) &index, sizeof(index)); 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res2 = 0; 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0 && res2 < 0) 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_add_wep(struct wpa_driver_ndis_data *drv, 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int pairwise, int key_idx, int set_tx, 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *key, size_t key_len) 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_WEP *wep; 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = 12 + key_len; 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wep = os_zalloc(len); 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wep == NULL) 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wep->Length = len; 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wep->KeyIndex = key_idx; 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (set_tx) 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wep->KeyIndex |= 1 << 31; 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if 0 /* Setting bit30 does not seem to work with some NDIS drivers */ 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pairwise) 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wep->KeyIndex |= 1 << 30; 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wep->KeyLength = key_len; 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wep->KeyMaterial, key, key_len); 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_MSGDUMP, "NDIS: OID_802_11_ADD_WEP", 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) wep, len); 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = ndis_set_oid(drv, OID_802_11_ADD_WEP, (char *) wep, len); 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wep); 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_set_key(const char *ifname, void *priv, 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum wpa_alg alg, const u8 *addr, 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int key_idx, int set_tx, 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *seq, size_t seq_len, 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *key, size_t key_len) 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, i; 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_KEY *nkey; 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res, pairwise; 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 bssid[ETH_ALEN]; 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (addr == NULL || is_broadcast_ether_addr(addr)) { 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Group Key */ 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pairwise = 0; 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_driver_ndis_get_bssid(drv, bssid) < 0) 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(bssid, 0xff, ETH_ALEN); 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Pairwise Key */ 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pairwise = 1; 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(bssid, addr, ETH_ALEN); 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (alg == WPA_ALG_NONE || key_len == 0) { 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_driver_ndis_remove_key(drv, key_idx, addr, bssid, 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pairwise); 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (alg == WPA_ALG_WEP) { 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_driver_ndis_add_wep(drv, pairwise, key_idx, set_tx, 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key, key_len); 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = 12 + 6 + 6 + 8 + key_len; 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nkey = os_zalloc(len); 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (nkey == NULL) 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nkey->Length = len; 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nkey->KeyIndex = key_idx; 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (set_tx) 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nkey->KeyIndex |= 1 << 31; 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pairwise) 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nkey->KeyIndex |= 1 << 30; 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (seq && seq_len) 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nkey->KeyIndex |= 1 << 29; 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nkey->KeyLength = key_len; 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(nkey->BSSID, bssid, ETH_ALEN); 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (seq && seq_len) { 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < seq_len; i++) 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nkey->KeyRSC |= (ULONGLONG) seq[i] << (i * 8); 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (alg == WPA_ALG_TKIP && key_len == 32) { 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(nkey->KeyMaterial, key, 16); 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(nkey->KeyMaterial + 16, key + 24, 8); 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(nkey->KeyMaterial + 24, key + 16, 8); 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(nkey->KeyMaterial, key, key_len); 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_MSGDUMP, "NDIS: OID_802_11_ADD_KEY", 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) nkey, len); 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = ndis_set_oid(drv, OID_802_11_ADD_KEY, (char *) nkey, len); 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(nkey); 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_driver_ndis_associate(void *priv, 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_associate_params *params) 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 auth_mode, encr, priv_mode, mode; 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->mode = params->mode; 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Note: Setting OID_802_11_INFRASTRUCTURE_MODE clears current keys, 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * so static WEP keys needs to be set again after this. */ 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->mode == IEEE80211_MODE_IBSS) { 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mode = Ndis802_11IBSS; 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Need to make sure that BSSID polling is enabled for 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * IBSS mode. */ 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_driver_ndis_poll_timeout, drv, NULL); 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(1, 0, wpa_driver_ndis_poll_timeout, 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv, NULL); 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mode = Ndis802_11Infrastructure; 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis_set_oid(drv, OID_802_11_INFRASTRUCTURE_MODE, 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (char *) &mode, sizeof(mode)) < 0) { 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Failed to set " 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "OID_802_11_INFRASTRUCTURE_MODE (%d)", 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) mode); 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Try to continue anyway */ 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->key_mgmt_suite == KEY_MGMT_NONE || 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->key_mgmt_suite == KEY_MGMT_802_1X_NO_WPA) { 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Re-set WEP keys if static WEP configuration is used. */ 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 4; i++) { 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!params->wep_key[i]) 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Re-setting static WEP " 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "key %d", i); 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_set_key(drv->ifname, drv, WPA_ALG_WEP, 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bcast, i, 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i == params->wep_tx_keyidx, 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, 0, params->wep_key[i], 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->wep_key_len[i]); 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->wpa_ie == NULL || params->wpa_ie_len == 0) { 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->auth_alg & WPA_AUTH_ALG_SHARED) { 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->auth_alg & WPA_AUTH_ALG_OPEN) 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_mode = Ndis802_11AuthModeAutoSwitch; 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_mode = Ndis802_11AuthModeShared; 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_mode = Ndis802_11AuthModeOpen; 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv_mode = Ndis802_11PrivFilterAcceptAll; 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (params->wpa_ie[0] == WLAN_EID_RSN) { 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv_mode = Ndis802_11PrivFilter8021xWEP; 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->key_mgmt_suite == KEY_MGMT_PSK) 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_mode = Ndis802_11AuthModeWPA2PSK; 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_mode = Ndis802_11AuthModeWPA2; 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (params->key_mgmt_suite == KEY_MGMT_WPS) { 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_mode = Ndis802_11AuthModeOpen; 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv_mode = Ndis802_11PrivFilterAcceptAll; 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->wps == WPS_MODE_PRIVACY) { 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 dummy_key[5] = { 0x11, 0x22, 0x33, 0x44, 0x55 }; 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Some NDIS drivers refuse to associate in open mode 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * configuration due to Privacy field mismatch, so use 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * a workaround to make the configuration look like 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * matching one for WPS provisioning. 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Set dummy WEP key as a " 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "workaround to allow driver to associate " 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for WPS"); 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_set_key(drv->ifname, drv, WPA_ALG_WEP, 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bcast, 0, 1, 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, 0, dummy_key, 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dummy_key)); 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv_mode = Ndis802_11PrivFilter8021xWEP; 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->key_mgmt_suite == KEY_MGMT_WPA_NONE) 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_mode = Ndis802_11AuthModeWPANone; 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (params->key_mgmt_suite == KEY_MGMT_PSK) 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_mode = Ndis802_11AuthModeWPAPSK; 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_mode = Ndis802_11AuthModeWPA; 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (params->pairwise_suite) { 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CIPHER_CCMP: 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr = Ndis802_11Encryption3Enabled; 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CIPHER_TKIP: 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr = Ndis802_11Encryption2Enabled; 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CIPHER_WEP40: 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CIPHER_WEP104: 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr = Ndis802_11Encryption1Enabled; 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CIPHER_NONE: 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->wps == WPS_MODE_PRIVACY) { 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr = Ndis802_11Encryption1Enabled; 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->group_suite == CIPHER_CCMP) 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr = Ndis802_11Encryption3Enabled; 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (params->group_suite == CIPHER_TKIP) 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr = Ndis802_11Encryption2Enabled; 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr = Ndis802_11EncryptionDisabled; 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->wps == WPS_MODE_PRIVACY) { 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr = Ndis802_11Encryption1Enabled; 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr = Ndis802_11EncryptionDisabled; 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt }; 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis_set_oid(drv, OID_802_11_PRIVACY_FILTER, 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (char *) &priv_mode, sizeof(priv_mode)) < 0) { 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Failed to set " 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "OID_802_11_PRIVACY_FILTER (%d)", 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) priv_mode); 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Try to continue anyway */ 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_set_auth_mode(drv, auth_mode); 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_set_encr_status(drv, encr); 11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->bssid) { 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_set_oid(drv, OID_802_11_BSSID, (char *) params->bssid, 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->oid_bssid_set = 1; 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (drv->oid_bssid_set) { 12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_set_oid(drv, OID_802_11_BSSID, "\xff\xff\xff\xff\xff\xff", 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->oid_bssid_set = 0; 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_driver_ndis_set_ssid(drv, params->ssid, params->ssid_len); 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_set_pmkid(struct wpa_driver_ndis_data *drv) 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len, count, i, ret; 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ndis_pmkid_entry *entry; 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_PMKID *p; 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count = 0; 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = drv->pmkid; 12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (entry) { 12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (count >= drv->no_of_pmkid) 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = entry->next; 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = 8 + count * sizeof(BSSID_INFO); 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = os_zalloc(len); 12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p == NULL) 12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p->Length = len; 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p->BSSIDInfoCount = count; 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = drv->pmkid; 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < count; i++) { 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&p->BSSIDInfo[i].BSSID, entry->bssid, ETH_ALEN); 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&p->BSSIDInfo[i].PMKID, entry->pmkid, 16); 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = entry->next; 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "NDIS: OID_802_11_PMKID", (u8 *) p, len); 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = ndis_set_oid(drv, OID_802_11_PMKID, (char *) p, len); 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p); 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_add_pmkid(void *priv, const u8 *bssid, 12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pmkid) 12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ndis_pmkid_entry *entry, *prev; 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->no_of_pmkid == 0) 12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = NULL; 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = drv->pmkid; 12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (entry) { 12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(entry->bssid, bssid, ETH_ALEN) == 0) 12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = entry; 12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = entry->next; 12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry) { 12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Replace existing entry for this BSSID and move it into the 12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * beginning of the list. */ 12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(entry->pmkid, pmkid, 16); 12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev) { 12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev->next = entry->next; 12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->next = drv->pmkid; 12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->pmkid = entry; 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = os_malloc(sizeof(*entry)); 12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry) { 12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(entry->bssid, bssid, ETH_ALEN); 12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(entry->pmkid, pmkid, 16); 12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->next = drv->pmkid; 12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->pmkid = entry; 12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_driver_ndis_set_pmkid(drv); 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_remove_pmkid(void *priv, const u8 *bssid, 12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pmkid) 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ndis_pmkid_entry *entry, *prev; 12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->no_of_pmkid == 0) 12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = drv->pmkid; 12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = NULL; 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (entry) { 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(entry->bssid, bssid, ETH_ALEN) == 0 && 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(entry->pmkid, pmkid, 16) == 0) { 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev) 12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev->next = entry->next; 13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->pmkid = entry->next; 13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(entry); 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = entry; 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = entry->next; 13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_driver_ndis_set_pmkid(drv); 13098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_flush_pmkid(void *priv) 13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_PMKID p; 13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ndis_pmkid_entry *pmkid, *prev; 13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int prev_authmode, ret; 13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->no_of_pmkid == 0) 13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmkid = drv->pmkid; 13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->pmkid = NULL; 13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pmkid) { 13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = pmkid; 13268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmkid = pmkid->next; 13278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(prev); 13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Some drivers may refuse OID_802_11_PMKID if authMode is not set to 13328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPA2, so change authMode temporarily, if needed. 13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev_authmode = ndis_get_auth_mode(drv); 13358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev_authmode != Ndis802_11AuthModeWPA2) 13368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_set_auth_mode(drv, Ndis802_11AuthModeWPA2); 13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&p, 0, sizeof(p)); 13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p.Length = 8; 13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p.BSSIDInfoCount = 0; 13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "NDIS: OID_802_11_PMKID (flush)", 13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) &p, 8); 13438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = ndis_set_oid(drv, OID_802_11_PMKID, (char *) &p, 8); 13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev_authmode != Ndis802_11AuthModeWPA2) 13468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_set_auth_mode(drv, prev_authmode); 13478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_get_associnfo(struct wpa_driver_ndis_data *drv) 13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[512], *pos; 13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_ASSOCIATION_INFORMATION *ai; 13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len; 13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union wpa_event_data data; 13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_BSSID_LIST_EX *b; 13598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t blen, i; 13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = ndis_get_oid(drv, OID_802_11_ASSOCIATION_INFORMATION, buf, 13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(buf)); 13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 0) { 13648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: failed to get association " 13658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "information"); 13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > sizeof(buf)) { 13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Some drivers seem to be producing incorrect length for this 13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * data. Limit the length to the current buffer size to avoid 13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * crashing in hexdump. The data seems to be otherwise valid, 13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * so better try to use it. */ 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: ignored bogus association " 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "information length %d", len); 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = ndis_get_oid(drv, OID_802_11_ASSOCIATION_INFORMATION, 13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf, sizeof(buf)); 13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < -1) { 13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: re-reading association " 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "information failed"); 13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > sizeof(buf)) { 13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: ignored bogus association" 13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " information length %d (re-read)", len); 13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(buf); 13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "NDIS: association information", 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) buf, len); 13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < sizeof(*ai)) { 13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: too short association " 13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "information"); 13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ai = (NDIS_802_11_ASSOCIATION_INFORMATION *) buf; 13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: ReqFixed=0x%x RespFixed=0x%x off_req=%d " 13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "off_resp=%d len_req=%d len_resp=%d", 13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ai->AvailableRequestFixedIEs, ai->AvailableResponseFixedIEs, 13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) ai->OffsetRequestIEs, (int) ai->OffsetResponseIEs, 14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) ai->RequestIELength, (int) ai->ResponseIELength); 14018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ai->OffsetRequestIEs + ai->RequestIELength > (unsigned) len || 14038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ai->OffsetResponseIEs + ai->ResponseIELength > (unsigned) len) { 14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: association information - " 14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "IE overflow"); 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "NDIS: Request IEs", 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) buf + ai->OffsetRequestIEs, ai->RequestIELength); 14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "NDIS: Response IEs", 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) buf + ai->OffsetResponseIEs, ai->ResponseIELength); 14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&data, 0, sizeof(data)); 14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data.assoc_info.req_ies = (u8 *) buf + ai->OffsetRequestIEs; 14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data.assoc_info.req_ies_len = ai->RequestIELength; 14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data.assoc_info.resp_ies = (u8 *) buf + ai->OffsetResponseIEs; 14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data.assoc_info.resp_ies_len = ai->ResponseIELength; 14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt blen = 65535; 14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b = os_zalloc(blen); 14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (b == NULL) 14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto skip_scan_results; 14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = ndis_get_oid(drv, OID_802_11_BSSID_LIST, (char *) b, blen); 14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 0) { 14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: failed to get scan results"); 14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(b); 14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b = NULL; 14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto skip_scan_results; 14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: %d BSSID items to process for AssocInfo", 14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned int) b->NumberOfItems); 14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (char *) &b->Bssid[0]; 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < b->NumberOfItems; i++) { 14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_WLAN_BSSID_EX *bss = (NDIS_WLAN_BSSID_EX *) pos; 14378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(drv->bssid, bss->MacAddress, ETH_ALEN) == 0 && 14388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bss->IELength > sizeof(NDIS_802_11_FIXED_IEs)) { 14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data.assoc_info.beacon_ies = 14408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ((u8 *) bss->IEs) + 14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(NDIS_802_11_FIXED_IEs); 14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data.assoc_info.beacon_ies_len = 14438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bss->IELength - sizeof(NDIS_802_11_FIXED_IEs); 14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "NDIS: Beacon IEs", 14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data.assoc_info.beacon_ies, 14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data.assoc_info.beacon_ies_len); 14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += bss->Length; 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos > (char *) b + blen) 14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtskip_scan_results: 14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_event(drv->ctx, EVENT_ASSOCINFO, &data); 14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(b); 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_driver_ndis_poll_timeout(void *eloop_ctx, void *timeout_ctx) 14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = eloop_ctx; 14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 bssid[ETH_ALEN]; 14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int poll; 14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->wired) 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_driver_ndis_get_bssid(drv, bssid)) { 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Disconnected */ 14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!is_zero_ether_addr(drv->bssid)) { 14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(drv->bssid, 0, ETH_ALEN); 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL); 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Connected */ 14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(drv->bssid, bssid, ETH_ALEN) != 0) { 14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(drv->bssid, bssid, ETH_ALEN); 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_get_associnfo(drv); 14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL); 14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* When using integrated NDIS event receiver, we can skip BSSID 14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * polling when using infrastructure network. However, when using 14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * IBSS mode, many driver do not seem to generate connection event, 14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * so we need to enable BSSID polling to figure out when IBSS network 14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * has been formed. 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt poll = drv->mode == IEEE80211_MODE_IBSS; 14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NDIS_EVENTS_INTEGRATED 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef _WIN32_WCE 14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt poll = 1; 14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NDIS_EVENTS_INTEGRATED */ 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (poll) { 15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(1, 0, wpa_driver_ndis_poll_timeout, 15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv, NULL); 15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_driver_ndis_poll(void *priv) 15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_driver_ndis_poll_timeout, drv, NULL); 15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_poll_timeout(drv, NULL); 15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Called when driver generates Media Connect Event by calling 15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * NdisMIndicateStatus() with NDIS_STATUS_MEDIA_CONNECT */ 15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_driver_ndis_event_connect(struct wpa_driver_ndis_data *drv) 15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Media Connect Event"); 15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_driver_ndis_get_bssid(drv, drv->bssid) == 0) { 15218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_get_associnfo(drv); 15228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL); 15238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Called when driver generates Media Disconnect Event by calling 15288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * NdisMIndicateStatus() with NDIS_STATUS_MEDIA_DISCONNECT */ 15298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_driver_ndis_event_disconnect(struct wpa_driver_ndis_data *drv) 15308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Media Disconnect Event"); 15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(drv->bssid, 0, ETH_ALEN); 15338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL); 15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_driver_ndis_event_auth(struct wpa_driver_ndis_data *drv, 15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t data_len) 15398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_AUTHENTICATION_REQUEST *req; 15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int pairwise = 0, group = 0; 15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union wpa_event_data event; 15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data_len < sizeof(*req)) { 15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Too short Authentication Request " 15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Event (len=%d)", data_len); 15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req = (NDIS_802_11_AUTHENTICATION_REQUEST *) data; 15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Authentication Request Event: " 15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Bssid " MACSTR " Flags 0x%x", 15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(req->Bssid), (int) req->Flags); 15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((req->Flags & NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR) == 15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR) 15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pairwise = 1; 15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if ((req->Flags & NDIS_802_11_AUTH_REQUEST_GROUP_ERROR) == 15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_AUTH_REQUEST_GROUP_ERROR) 15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group = 1; 15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pairwise || group) { 15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&event, 0, sizeof(event)); 15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt event.michael_mic_failure.unicast = pairwise; 15658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_event(drv->ctx, EVENT_MICHAEL_MIC_FAILURE, 15668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &event); 15678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_driver_ndis_event_pmkid(struct wpa_driver_ndis_data *drv, 15728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t data_len) 15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_PMKID_CANDIDATE_LIST *pmkid; 15758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union wpa_event_data event; 15778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data_len < 8) { 15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Too short PMKID Candidate List " 15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Event (len=%d)", data_len); 15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmkid = (NDIS_802_11_PMKID_CANDIDATE_LIST *) data; 15848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: PMKID Candidate List Event - Version %d " 15858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "NumCandidates %d", 15868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) pmkid->Version, (int) pmkid->NumCandidates); 15878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pmkid->Version != 1) { 15898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Unsupported PMKID Candidate List " 15908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Version %d", (int) pmkid->Version); 15918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data_len < 8 + pmkid->NumCandidates * sizeof(PMKID_CANDIDATE)) { 15958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: PMKID Candidate List underflow"); 15968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&event, 0, sizeof(event)); 16008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < pmkid->NumCandidates; i++) { 16018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PMKID_CANDIDATE *p = &pmkid->CandidateList[i]; 16028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: %d: " MACSTR " Flags 0x%x", 16038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i, MAC2STR(p->BSSID), (int) p->Flags); 16048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(event.pmkid_candidate.bssid, p->BSSID, ETH_ALEN); 16058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt event.pmkid_candidate.index = i; 16068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt event.pmkid_candidate.preauth = 16078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p->Flags & NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; 16088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_event(drv->ctx, EVENT_PMKID_CANDIDATE, 16098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &event); 16108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Called when driver calls NdisMIndicateStatus() with 16158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * NDIS_STATUS_MEDIA_SPECIFIC_INDICATION */ 16168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_driver_ndis_event_media_specific(struct wpa_driver_ndis_data *drv, 16178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t data_len) 16188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_STATUS_INDICATION *status; 16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data == NULL || data_len < sizeof(*status)) 16228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "NDIS: Media Specific Indication", 16258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data, data_len); 16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = (NDIS_802_11_STATUS_INDICATION *) data; 16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data += sizeof(status); 16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data_len -= sizeof(status); 16308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (status->StatusType) { 16328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Ndis802_11StatusType_Authentication: 16338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_event_auth(drv, data, data_len); 16348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Ndis802_11StatusType_PMKID_CandidateList: 16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_event_pmkid(drv, data, data_len); 16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Unknown StatusType %d", 16408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) status->StatusType); 16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Called when an adapter is added */ 16478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_driver_ndis_event_adapter_arrival(struct wpa_driver_ndis_data *drv) 16488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union wpa_event_data event; 16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 16518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Notify Adapter Arrival"); 16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 30; i++) { 16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Re-open Packet32/NDISUIO connection */ 16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_adapter_close(drv); 16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_driver_ndis_adapter_init(drv) < 0 || 16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_adapter_open(drv) < 0) { 16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Driver re-initialization " 16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(%d) failed", i); 16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_sleep(1, 0); 16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Driver re-initialized"); 16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&event, 0, sizeof(event)); 16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(event.interface_status.ifname, drv->ifname, 16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(event.interface_status.ifname)); 16718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt event.interface_status.ievent = EVENT_INTERFACE_ADDED; 16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event); 16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Called when an adapter is removed */ 16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_driver_ndis_event_adapter_removal(struct wpa_driver_ndis_data *drv) 16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union wpa_event_data event; 16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Notify Adapter Removal"); 16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&event, 0, sizeof(event)); 16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(event.interface_status.ifname, drv->ifname, 16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(event.interface_status.ifname)); 16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt event.interface_status.ievent = EVENT_INTERFACE_REMOVED; 16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event); 16878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void 16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_driver_ndis_get_wpa_capability(struct wpa_driver_ndis_data *drv) 16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: verifying driver WPA capability"); 16948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis_set_auth_mode(drv, Ndis802_11AuthModeWPA) == 0 && 16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_get_auth_mode(drv) == Ndis802_11AuthModeWPA) { 16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: WPA key management supported"); 16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA; 16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis_set_auth_mode(drv, Ndis802_11AuthModeWPAPSK) == 0 && 17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_get_auth_mode(drv) == Ndis802_11AuthModeWPAPSK) { 17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: WPA-PSK key management " 17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "supported"); 17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK; 17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis_set_encr_status(drv, Ndis802_11Encryption3Enabled) == 0 && 17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_get_encr_status(drv) == Ndis802_11Encryption3KeyAbsent) { 17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: CCMP encryption supported"); 17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP; 17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis_set_encr_status(drv, Ndis802_11Encryption2Enabled) == 0 && 17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_get_encr_status(drv) == Ndis802_11Encryption2KeyAbsent) { 17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: TKIP encryption supported"); 17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.enc |= WPA_DRIVER_CAPA_ENC_TKIP; 17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis_set_encr_status(drv, Ndis802_11Encryption1Enabled) == 0 && 17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_get_encr_status(drv) == Ndis802_11Encryption1KeyAbsent) { 17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: WEP encryption supported"); 17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP40 | 17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_DRIVER_CAPA_ENC_WEP104; 17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis_set_auth_mode(drv, Ndis802_11AuthModeShared) == 0 && 17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_get_auth_mode(drv) == Ndis802_11AuthModeShared) { 17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.auth |= WPA_DRIVER_AUTH_SHARED; 17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis_set_auth_mode(drv, Ndis802_11AuthModeOpen) == 0 && 17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_get_auth_mode(drv) == Ndis802_11AuthModeOpen) { 17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.auth |= WPA_DRIVER_AUTH_OPEN; 17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_set_encr_status(drv, Ndis802_11EncryptionDisabled); 17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Could also verify OID_802_11_ADD_KEY error reporting and 17408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * support for OID_802_11_ASSOCIATION_INFORMATION. */ 17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA && 17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.enc & (WPA_DRIVER_CAPA_ENC_TKIP | 17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_DRIVER_CAPA_ENC_CCMP)) { 17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: driver supports WPA"); 17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->has_capability = 1; 17478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: no WPA support found"); 17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: driver capabilities: key_mgmt 0x%x " 17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "enc 0x%x auth 0x%x", 17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.key_mgmt, drv->capa.enc, drv->capa.auth); 17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_driver_ndis_get_capability(struct wpa_driver_ndis_data *drv) 17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[512]; 17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len; 17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_CAPABILITY *c; 17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.flags = WPA_DRIVER_FLAGS_DRIVER_IE; 17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = ndis_get_oid(drv, OID_802_11_CAPABILITY, buf, sizeof(buf)); 17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 0) { 17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_get_wpa_capability(drv); 17698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "OID_802_11_CAPABILITY", (u8 *) buf, len); 17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c = (NDIS_802_11_CAPABILITY *) buf; 17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < sizeof(*c) || c->Version != 2) { 17758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: unsupported " 17768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "OID_802_11_CAPABILITY data"); 17778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Driver supports OID_802_11_CAPABILITY - " 17808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "NoOfPMKIDs %d NoOfAuthEncrPairs %d", 17818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) c->NoOfPMKIDs, 17828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) c->NoOfAuthEncryptPairsSupported); 17838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->has_capability = 1; 17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->no_of_pmkid = c->NoOfPMKIDs; 17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < c->NoOfAuthEncryptPairsSupported; i++) { 17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_AUTHENTICATION_ENCRYPTION *ae; 17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ae = &c->AuthenticationEncryptionSupported[i]; 17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((char *) (ae + 1) > buf + len) { 17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: auth/encr pair list " 17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "overflow"); 17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_MSGDUMP, "NDIS: %d - auth %d encr %d", 17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i, (int) ae->AuthModeSupported, 17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) ae->EncryptStatusSupported); 17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (ae->AuthModeSupported) { 17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Ndis802_11AuthModeOpen: 17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.auth |= WPA_DRIVER_AUTH_OPEN; 17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Ndis802_11AuthModeShared: 18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.auth |= WPA_DRIVER_AUTH_SHARED; 18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Ndis802_11AuthModeWPA: 18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA; 18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Ndis802_11AuthModeWPAPSK: 18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK; 18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Ndis802_11AuthModeWPA2: 18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA2; 18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Ndis802_11AuthModeWPA2PSK: 18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.key_mgmt |= 18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK; 18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Ndis802_11AuthModeWPANone: 18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.key_mgmt |= 18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE; 18198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (ae->EncryptStatusSupported) { 18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Ndis802_11Encryption1Enabled: 18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP40; 18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP104; 18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Ndis802_11Encryption2Enabled: 18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.enc |= WPA_DRIVER_CAPA_ENC_TKIP; 18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Ndis802_11Encryption3Enabled: 18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP; 18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: driver capabilities: key_mgmt 0x%x " 18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "enc 0x%x auth 0x%x", 18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.key_mgmt, drv->capa.enc, drv->capa.auth); 18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_get_capa(void *priv, struct wpa_driver_capa *capa) 18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!drv->has_capability) 18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(capa, &drv->capa, sizeof(*capa)); 18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * wpa_driver_ndis_get_ifname(void *priv) 18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return drv->ifname; 18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const u8 * wpa_driver_ndis_get_mac_addr(void *priv) 18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return drv->own_addr; 18668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef _WIN32_WCE 18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define NDISUIO_MSG_SIZE (sizeof(NDISUIO_DEVICE_NOTIFICATION) + 512) 18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ndisuio_notification_receive(void *eloop_data, void *user_ctx) 18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = eloop_data; 18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDISUIO_DEVICE_NOTIFICATION *hdr; 18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 buf[NDISUIO_MSG_SIZE]; 18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD len, flags; 18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ReadMsgQueue(drv->event_queue, buf, NDISUIO_MSG_SIZE, &len, 0, 18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &flags)) { 18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ndisuio_notification_receive: " 18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ReadMsgQueue failed: %d", (int) GetLastError()); 18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < sizeof(NDISUIO_DEVICE_NOTIFICATION)) { 18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ndisuio_notification_receive: " 18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Too short message (len=%d)", (int) len); 18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr = (NDISUIO_DEVICE_NOTIFICATION *) buf; 18948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Notification received: len=%d type=0x%x", 18958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) len, hdr->dwNotificationType); 18968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (hdr->dwNotificationType) { 18988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef NDISUIO_NOTIFICATION_ADAPTER_ARRIVAL 18998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case NDISUIO_NOTIFICATION_ADAPTER_ARRIVAL: 19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: ADAPTER_ARRIVAL"); 19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_event_adapter_arrival(drv); 19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef NDISUIO_NOTIFICATION_ADAPTER_REMOVAL 19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case NDISUIO_NOTIFICATION_ADAPTER_REMOVAL: 19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: ADAPTER_REMOVAL"); 19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_event_adapter_removal(drv); 19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case NDISUIO_NOTIFICATION_MEDIA_CONNECT: 19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: MEDIA_CONNECT"); 19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SetEvent(drv->connected_event); 19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_event_connect(drv); 19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case NDISUIO_NOTIFICATION_MEDIA_DISCONNECT: 19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ResetEvent(drv->connected_event); 19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: MEDIA_DISCONNECT"); 19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_event_disconnect(drv); 19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case NDISUIO_NOTIFICATION_MEDIA_SPECIFIC_NOTIFICATION: 19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: MEDIA_SPECIFIC_NOTIFICATION"); 19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if _WIN32_WCE == 420 || _WIN32_WCE == 0x420 19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_event_media_specific( 19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv, hdr->pvStatusBuffer, hdr->uiStatusBufferSize); 19258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else 19268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_event_media_specific( 19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv, ((const u8 *) hdr) + hdr->uiOffsetToStatusBuffer, 19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (size_t) hdr->uiStatusBufferSize); 19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Unknown notification type 0x%x", 19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->dwNotificationType); 19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ndisuio_notification_deinit(struct wpa_driver_ndis_data *drv) 19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDISUIO_REQUEST_NOTIFICATION req; 19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt memset(&req, 0, sizeof(req)); 19448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req.hMsgQueue = drv->event_queue; 19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req.dwNotificationTypes = 0; 19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!DeviceIoControl(drv->ndisuio, IOCTL_NDISUIO_REQUEST_NOTIFICATION, 19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &req, sizeof(req), NULL, 0, NULL, NULL)) { 19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "ndisuio_notification_deinit: " 19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "IOCTL_NDISUIO_REQUEST_NOTIFICATION failed: %d", 19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!DeviceIoControl(drv->ndisuio, IOCTL_NDISUIO_CANCEL_NOTIFICATION, 19558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, 0, NULL, 0, NULL, NULL)) { 19568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "ndisuio_notification_deinit: " 19578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "IOCTL_NDISUIO_CANCEL_NOTIFICATION failed: %d", 19588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->event_queue) { 19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_unregister_event(drv->event_queue, 19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(drv->event_queue)); 19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CloseHandle(drv->event_queue); 19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->event_queue = NULL; 19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->connected_event) { 19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CloseHandle(drv->connected_event); 19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->connected_event = NULL; 19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ndisuio_notification_init(struct wpa_driver_ndis_data *drv) 19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MSGQUEUEOPTIONS opt; 19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDISUIO_REQUEST_NOTIFICATION req; 19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->connected_event = 19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CreateEvent(NULL, TRUE, FALSE, TEXT("WpaSupplicantConnected")); 19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->connected_event == NULL) { 19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "ndisuio_notification_init: " 19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "CreateEvent failed: %d", 19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt memset(&opt, 0, sizeof(opt)); 19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt opt.dwSize = sizeof(opt); 19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt opt.dwMaxMessages = 5; 19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt opt.cbMaxMessage = NDISUIO_MSG_SIZE; 19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt opt.bReadAccess = TRUE; 19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->event_queue = CreateMsgQueue(NULL, &opt); 19968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->event_queue == NULL) { 19978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "ndisuio_notification_init: " 19988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "CreateMsgQueue failed: %d", 19998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 20008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndisuio_notification_deinit(drv); 20018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 20028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt memset(&req, 0, sizeof(req)); 20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req.hMsgQueue = drv->event_queue; 20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req.dwNotificationTypes = 20078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef NDISUIO_NOTIFICATION_ADAPTER_ARRIVAL 20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDISUIO_NOTIFICATION_ADAPTER_ARRIVAL | 20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef NDISUIO_NOTIFICATION_ADAPTER_REMOVAL 20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDISUIO_NOTIFICATION_ADAPTER_REMOVAL | 20128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDISUIO_NOTIFICATION_MEDIA_CONNECT | 20148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDISUIO_NOTIFICATION_MEDIA_DISCONNECT | 20158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDISUIO_NOTIFICATION_MEDIA_SPECIFIC_NOTIFICATION; 20168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!DeviceIoControl(drv->ndisuio, IOCTL_NDISUIO_REQUEST_NOTIFICATION, 20188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &req, sizeof(req), NULL, 0, NULL, NULL)) { 20198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "ndisuio_notification_init: " 20208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "IOCTL_NDISUIO_REQUEST_NOTIFICATION failed: %d", 20218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 20228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndisuio_notification_deinit(drv); 20238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 20248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_event(drv->event_queue, sizeof(drv->event_queue), 20278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndisuio_notification_receive, drv, NULL); 20288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 20308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 20328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_get_names(struct wpa_driver_ndis_data *drv) 20358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_USE_NDISUIO 20378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDISUIO_QUERY_BINDING *b; 20388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t blen = sizeof(*b) + 1024; 20398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i, error, found = 0; 20408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD written; 20418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char name[256], desc[256], *dpos; 20428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WCHAR *pos; 20438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t j, len, dlen; 20448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b = os_malloc(blen); 20468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (b == NULL) 20478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 20488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; ; i++) { 20508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(b, 0, blen); 20518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b->BindingIndex = i; 20528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!DeviceIoControl(drv->ndisuio, IOCTL_NDISUIO_QUERY_BINDING, 20538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b, sizeof(NDISUIO_QUERY_BINDING), b, blen, 20548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &written, NULL)) { 20558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt error = (int) GetLastError(); 20568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (error == ERROR_NO_MORE_ITEMS) 20578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "IOCTL_NDISUIO_QUERY_BINDING " 20598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed: %d", error); 20608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (WCHAR *) ((char *) b + b->DeviceNameOffset); 20648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = b->DeviceNameLength; 20658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len >= sizeof(name)) 20668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(name) - 1; 20678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < len; j++) 20688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name[j] = (char) pos[j]; 20698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name[len] = '\0'; 20708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (WCHAR *) ((char *) b + b->DeviceDescrOffset); 20728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = b->DeviceDescrLength; 20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len >= sizeof(desc)) 20748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(desc) - 1; 20758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < len; j++) 20768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc[j] = (char) pos[j]; 20778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc[len] = '\0'; 20788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: %d - %s - %s", i, name, desc); 20808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strstr(name, drv->ifname)) { 20828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Interface name match"); 20838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found = 1; 20848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(desc, drv->ifname, os_strlen(drv->ifname)) == 0) 20888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 20898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Interface description " 20908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "match"); 20918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found = 1; 20928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!found) { 20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Could not find interface '%s'", 20988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->ifname); 20998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(b); 21008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(drv->ifname, 21048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strncmp(name, "\\DEVICE\\", 8) == 0 ? name + 8 : name, 21058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(drv->ifname)); 21068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef _WIN32_WCE 21078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->adapter_name = wpa_strdup_tchar(drv->ifname); 21088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->adapter_name == NULL) { 21098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "NDIS: Failed to allocate memory for " 21108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "adapter name"); 21118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(b); 21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 21158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dpos = os_strstr(desc, " - "); 21178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dpos) 21188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dlen = dpos - desc; 21198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 21208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dlen = os_strlen(desc); 21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->adapter_desc = os_malloc(dlen + 1); 21228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->adapter_desc) { 21238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(drv->adapter_desc, desc, dlen); 21248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->adapter_desc[dlen] = '\0'; 21258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(b); 21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->adapter_desc == NULL) 21308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Adapter description prefix '%s'", 21338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->adapter_desc); 21348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 21368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_USE_NDISUIO */ 21378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PTSTR _names; 21388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *names, *pos, *pos2; 21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG len; 21408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BOOLEAN res; 21418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define MAX_ADAPTERS 32 21428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *name[MAX_ADAPTERS]; 21438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *desc[MAX_ADAPTERS]; 21448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int num_name, num_desc, i, found_name, found_desc; 21458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t dlen; 21468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Packet.dll version: %s", 21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PacketGetVersion()); 21498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = 8192; 21518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _names = os_zalloc(len); 21528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (_names == NULL) 21538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = PacketGetAdapterNames(_names, &len); 21568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!res && len > 8192) { 21578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(_names); 21588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _names = os_zalloc(len); 21598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (_names == NULL) 21608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = PacketGetAdapterNames(_names, &len); 21628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!res) { 21658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "NDIS: Failed to get adapter list " 21668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(PacketGetAdapterNames)"); 21678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(_names); 21688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt names = (char *) _names; 21728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (names[0] && names[1] == '\0' && names[2] && names[3] == '\0') { 21738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Looks like adapter names are in " 21748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "UNICODE"); 21758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Convert to ASCII */ 21768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2 = pos = names; 21778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos2 < names + len) { 21788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos2[0] == '\0' && pos2[1] == '\0' && 21798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2[2] == '\0' && pos2[3] == '\0') { 21808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2 += 4; 21818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 21828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = pos2[0]; 21848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2 += 2; 21858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos + 2, names, pos - names); 21878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 21888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 21898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = names; 21908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_name = 0; 21928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < names + len) { 21938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name[num_name] = pos; 21948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*pos && pos < names + len) 21958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 21968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 1 >= names + len) { 21978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(names); 21988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 22018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_name++; 22028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_name >= MAX_ADAPTERS) { 22038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Too many adapters"); 22048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(names); 22058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == '\0') { 22088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: %d adapter names found", 22098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_name); 22108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 22118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 22128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_desc = 0; 22168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < names + len) { 22178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc[num_desc] = pos; 22188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*pos && pos < names + len) 22198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 22208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 1 >= names + len) { 22218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(names); 22228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 22258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_desc++; 22268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_desc >= MAX_ADAPTERS) { 22278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Too many adapter " 22288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "descriptions"); 22298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(names); 22308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == '\0') { 22338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: %d adapter descriptions " 22348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "found", num_name); 22358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 22368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 22378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 22418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Windows 98 with Packet.dll 3.0 alpha3 does not include adapter 22428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * descriptions. Fill in dummy descriptors to work around this. 22438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 22448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (num_desc < num_name) 22458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc[num_desc++] = "dummy description"; 22468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_name != num_desc) { 22488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: mismatch in adapter name and " 22498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "description counts (%d != %d)", 22508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_name, num_desc); 22518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(names); 22528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found_name = found_desc = -1; 22568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_name; i++) { 22578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: %d - %s - %s", 22588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i, name[i], desc[i]); 22598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (found_name == -1 && os_strstr(name[i], drv->ifname)) 22608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found_name = i; 22618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (found_desc == -1 && 22628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strncmp(desc[i], drv->ifname, os_strlen(drv->ifname)) == 22638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) 22648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found_desc = i; 22658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (found_name < 0 && found_desc >= 0) { 22688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Matched interface '%s' based on " 22698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "description '%s'", 22708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name[found_desc], desc[found_desc]); 22718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found_name = found_desc; 22728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(drv->ifname, 22738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strncmp(name[found_desc], "\\Device\\NPF_", 12) 22748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt == 0 ? name[found_desc] + 12 : name[found_desc], 22758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(drv->ifname)); 22768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (found_name < 0) { 22798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Could not find interface '%s'", 22808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->ifname); 22818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(names); 22828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i = found_name; 22868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strrchr(desc[i], '('); 22878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos) { 22888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dlen = pos - desc[i]; 22898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos--; 22908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos > desc[i] && *pos == ' ') 22918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dlen--; 22928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 22938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dlen = os_strlen(desc[i]); 22948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->adapter_desc = os_malloc(dlen + 1); 22968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->adapter_desc) { 22978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(drv->adapter_desc, desc[i], dlen); 22988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->adapter_desc[dlen] = '\0'; 22998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(names); 23028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->adapter_desc == NULL) 23048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Adapter description prefix '%s'", 23078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->adapter_desc); 23088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 23108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_USE_NDISUIO */ 23118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(CONFIG_NATIVE_WINDOWS) || defined(__CYGWIN__) 23158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef _WIN32_WCE 23168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 23178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * These structures are undocumented for WinXP; only WinCE version is 23188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * documented. These would be included wzcsapi.h if it were available. Some 23198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * changes here have been needed to make the structures match with WinXP SP2. 23208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * It is unclear whether these work with any other version. 23218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 23228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct { 23248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt LPWSTR wszGuid; 23258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} INTF_KEY_ENTRY, *PINTF_KEY_ENTRY; 23268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct { 23288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD dwNumIntfs; 23298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PINTF_KEY_ENTRY pIntfs; 23308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} INTFS_KEY_TABLE, *PINTFS_KEY_TABLE; 23318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct { 23338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD dwDataLen; 23348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt LPBYTE pData; 23358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} RAW_DATA, *PRAW_DATA; 23368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct { 23388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt LPWSTR wszGuid; 23398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt LPWSTR wszDescr; 23408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG ulMediaState; 23418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG ulMediaType; 23428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG ulPhysicalMediaType; 23438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt INT nInfraMode; 23448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt INT nAuthMode; 23458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt INT nWepStatus; 23468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef _WIN32_WCE 23478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 pad[2]; /* why is this needed? */ 23488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 23498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD dwCtlFlags; 23508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD dwCapabilities; /* something added for WinXP SP2(?) */ 23518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RAW_DATA rdSSID; 23528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RAW_DATA rdBSSID; 23538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RAW_DATA rdBSSIDList; 23548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RAW_DATA rdStSSIDList; 23558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RAW_DATA rdCtrlData; 23568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef UNDER_CE 23578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BOOL bInitialized; 23588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 23598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD nWPAMCastCipher; 23608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* add some extra buffer for later additions since this interface is 23618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * far from stable */ 23628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 later_additions[100]; 23638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} INTF_ENTRY, *PINTF_ENTRY; 23648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define INTF_ALL 0xffffffff 23668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define INTF_ALL_FLAGS 0x0000ffff 23678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define INTF_CTLFLAGS 0x00000010 23688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define INTFCTL_ENABLED 0x8000 23698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 23708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef _WIN32_WCE 23738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_rebind_adapter(struct wpa_driver_ndis_data *drv) 23748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HANDLE ndis; 23768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TCHAR multi[100]; 23778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len; 23788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = _tcslen(drv->adapter_name); 23808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > 80) 23818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis = CreateFile(DD_NDIS_DEVICE_NAME, GENERIC_READ | GENERIC_WRITE, 23848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, NULL, OPEN_EXISTING, 0, NULL); 23858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis == INVALID_HANDLE_VALUE) { 23868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Failed to open file to NDIS " 23878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "device: %d", (int) GetLastError()); 23888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len++; 23928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt memcpy(multi, drv->adapter_name, len * sizeof(TCHAR)); 23938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt memcpy(&multi[len], TEXT("NDISUIO\0"), 9 * sizeof(TCHAR)); 23948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += 9; 23958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!DeviceIoControl(ndis, IOCTL_NDIS_REBIND_ADAPTER, 23978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt multi, len * sizeof(TCHAR), NULL, 0, NULL, NULL)) 23988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 23998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: IOCTL_NDIS_REBIND_ADAPTER " 24008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed: 0x%x", (int) GetLastError()); 24018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "NDIS: rebind multi_sz", 24028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) multi, len * sizeof(TCHAR)); 24038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CloseHandle(ndis); 24048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 24058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CloseHandle(ndis); 24088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Requested NDIS rebind of NDISUIO " 24108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "protocol"); 24118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 24138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 24148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 24158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_set_wzc(struct wpa_driver_ndis_data *drv, 24188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int enable) 24198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef _WIN32_WCE 24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HKEY hk, hk2; 24228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt LONG ret; 24238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD i, hnd, len; 24248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TCHAR keyname[256], devname[256]; 24258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define WZC_DRIVER TEXT("Drivers\\BuiltIn\\ZeroConfig") 24278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (enable) { 24298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HANDLE h; 24308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt h = ActivateDeviceEx(WZC_DRIVER, NULL, 0, NULL); 24318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (h == INVALID_HANDLE_VALUE || h == 0) { 24328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Failed to re-enable WZC " 24338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "- ActivateDeviceEx failed: %d", 24348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 24358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 24368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: WZC re-enabled"); 24398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_driver_ndis_rebind_adapter(drv); 24408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 24438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Unfortunately, just disabling the WZC for an interface is not enough 24448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to free NDISUIO for us, so need to disable and unload WZC completely 24458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * for now when using WinCE with NDISUIO. In addition, must request 24468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * NDISUIO protocol to be rebound to the adapter in order to free the 24478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * NDISUIO binding that WZC hold before us. 24488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 24498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Enumerate HKLM\Drivers\Active\* to find a handle to WZC. */ 24518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, DEVLOAD_ACTIVE_KEY, 0, 0, &hk); 24528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret != ERROR_SUCCESS) { 24538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: RegOpenKeyEx(DEVLOAD_ACTIVE_KEY) " 24548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed: %d %d", (int) ret, (int) GetLastError()); 24558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 24568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; ; i++) { 24598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(keyname); 24608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = RegEnumKeyEx(hk, i, keyname, &len, NULL, NULL, NULL, 24618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL); 24628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret != ERROR_SUCCESS) { 24638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Could not find active " 24648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WZC - assuming it is not running."); 24658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RegCloseKey(hk); 24668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 24678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = RegOpenKeyEx(hk, keyname, 0, 0, &hk2); 24708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret != ERROR_SUCCESS) { 24718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: RegOpenKeyEx(active dev) " 24728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed: %d %d", 24738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) ret, (int) GetLastError()); 24748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 24758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(devname); 24788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = RegQueryValueEx(hk2, DEVLOAD_DEVKEY_VALNAME, NULL, NULL, 24798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (LPBYTE) devname, &len); 24808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret != ERROR_SUCCESS) { 24818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: RegQueryValueEx(" 24828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "DEVKEY_VALNAME) failed: %d %d", 24838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) ret, (int) GetLastError()); 24848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RegCloseKey(hk2); 24858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 24868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (_tcscmp(devname, WZC_DRIVER) == 0) 24898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 24908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RegCloseKey(hk2); 24928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RegCloseKey(hk); 24958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Found WZC - get handle to it. */ 24978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(hnd); 24988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = RegQueryValueEx(hk2, DEVLOAD_HANDLE_VALNAME, NULL, NULL, 24998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (PUCHAR) &hnd, &len); 25008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret != ERROR_SUCCESS) { 25018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: RegQueryValueEx(HANDLE_VALNAME) " 25028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed: %d %d", (int) ret, (int) GetLastError()); 25038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RegCloseKey(hk2); 25048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RegCloseKey(hk2); 25088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Deactivate WZC */ 25108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!DeactivateDevice((HANDLE) hnd)) { 25118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: DeactivateDevice failed: %d", 25128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 25138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Disabled WZC temporarily"); 25178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->wzc_disabled = 1; 25188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_driver_ndis_rebind_adapter(drv); 25198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* _WIN32_WCE */ 25218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HMODULE hm; 25238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD (WINAPI *wzc_enum_interf)(LPWSTR pSrvAddr, 25248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PINTFS_KEY_TABLE pIntfs); 25258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD (WINAPI *wzc_query_interf)(LPWSTR pSrvAddr, DWORD dwInFlags, 25268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PINTF_ENTRY pIntf, 25278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt LPDWORD pdwOutFlags); 25288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD (WINAPI *wzc_set_interf)(LPWSTR pSrvAddr, DWORD dwInFlags, 25298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PINTF_ENTRY pIntf, LPDWORD pdwOutFlags); 25308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = -1, j; 25318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD res; 25328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt INTFS_KEY_TABLE guids; 25338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt INTF_ENTRY intf; 25348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char guid[128]; 25358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WCHAR *pos; 25368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD flags, i; 25378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hm = LoadLibrary(TEXT("wzcsapi.dll")); 25398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hm == NULL) { 25408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Failed to load wzcsapi.dll (%u) " 25418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "- WZC probably not running", 25428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned int) GetLastError()); 25438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef _WIN32_WCE 25478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wzc_enum_interf = (void *) GetProcAddressA(hm, "WZCEnumInterfaces"); 25488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wzc_query_interf = (void *) GetProcAddressA(hm, "WZCQueryInterface"); 25498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wzc_set_interf = (void *) GetProcAddressA(hm, "WZCSetInterface"); 25508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* _WIN32_WCE */ 25518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wzc_enum_interf = (void *) GetProcAddress(hm, "WZCEnumInterfaces"); 25528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wzc_query_interf = (void *) GetProcAddress(hm, "WZCQueryInterface"); 25538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wzc_set_interf = (void *) GetProcAddress(hm, "WZCSetInterface"); 25548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 25558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wzc_enum_interf == NULL || wzc_query_interf == NULL || 25578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wzc_set_interf == NULL) { 25588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: WZCEnumInterfaces, " 25598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WZCQueryInterface, or WZCSetInterface not found " 25608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "in wzcsapi.dll"); 25618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 25628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&guids, 0, sizeof(guids)); 25658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wzc_enum_interf(NULL, &guids); 25668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res != 0) { 25678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: WZCEnumInterfaces failed: %d; " 25688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WZC service is apparently not running", 25698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) res); 25708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 25718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: WZCEnumInterfaces: %d interfaces", 25748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) guids.dwNumIntfs); 25758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < guids.dwNumIntfs; i++) { 25778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = guids.pIntfs[i].wszGuid; 25788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < sizeof(guid); j++) { 25798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt guid[j] = (char) *pos; 25808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == 0) 25818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 25828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 25838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt guid[sizeof(guid) - 1] = '\0'; 25858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: intfs %d GUID '%s'", 25868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) i, guid); 25878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strstr(drv->ifname, guid) == NULL) 25888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 25898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Current interface found from " 25918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WZC"); 25928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 25938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i >= guids.dwNumIntfs) { 25968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Current interface not found from " 25978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WZC"); 25988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 25998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&intf, 0, sizeof(intf)); 26028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt intf.wszGuid = guids.pIntfs[i].wszGuid; 26038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Set flags to verify that the structure has not changed. */ 26048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt intf.dwCtlFlags = -1; 26058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt flags = 0; 26068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wzc_query_interf(NULL, INTFCTL_ENABLED, &intf, &flags); 26078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res != 0) { 26088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Could not query flags for the " 26098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WZC interface: %d (0x%x)", 26108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) res, (int) res); 26118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: GetLastError: %u", 26128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned int) GetLastError()); 26138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 26148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: WZC interface flags 0x%x dwCtlFlags 0x%x", 26178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) flags, (int) intf.dwCtlFlags); 26188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (intf.dwCtlFlags == -1) { 26208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Looks like wzcsapi has changed " 26218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "again - could not disable WZC"); 26228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "NDIS: intf", 26238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) &intf, sizeof(intf)); 26248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 26258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (enable) { 26288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(intf.dwCtlFlags & INTFCTL_ENABLED)) { 26298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Enabling WZC for this " 26308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interface"); 26318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt intf.dwCtlFlags |= INTFCTL_ENABLED; 26328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wzc_set_interf(NULL, INTFCTL_ENABLED, &intf, 26338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &flags); 26348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res != 0) { 26358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Failed to enable " 26368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WZC: %d (0x%x)", 26378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) res, (int) res); 26388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: GetLastError: %u", 26398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned int) GetLastError()); 26408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 26418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Re-enabled WZC for this " 26438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interface"); 26448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->wzc_disabled = 0; 26458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 26478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (intf.dwCtlFlags & INTFCTL_ENABLED) { 26488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Disabling WZC for this " 26498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interface"); 26508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt intf.dwCtlFlags &= ~INTFCTL_ENABLED; 26518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wzc_set_interf(NULL, INTFCTL_ENABLED, &intf, 26528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &flags); 26538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res != 0) { 26548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Failed to " 26558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "disable WZC: %d (0x%x)", 26568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) res, (int) res); 26578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: GetLastError: %u", 26588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned int) GetLastError()); 26598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 26608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Disabled WZC temporarily " 26628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for this interface"); 26638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->wzc_disabled = 1; 26648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 26658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: WZC was not enabled for " 26668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "this interface"); 26678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = 0; 26718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 26738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FreeLibrary(hm); 26748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 26768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 26778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_NATIVE_WINDOWS || __CYGWIN__ */ 26808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_set_wzc(struct wpa_driver_ndis_data *drv, 26828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int enable) 26838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS || __CYGWIN__ */ 26888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_USE_NDISUIO 26918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 26928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * l2_packet_ndis.c is sharing the same handle to NDISUIO, so we must be able 26938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to export this handle. This is somewhat ugly, but there is no better 26948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * mechanism available to pass data from driver interface to l2_packet wrapper. 26958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 26968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic HANDLE driver_ndis_ndisuio_handle = INVALID_HANDLE_VALUE; 26978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26988d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtHANDLE driver_ndis_get_ndisuio_handle(void) 26998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return driver_ndis_ndisuio_handle; 27018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_USE_NDISUIO */ 27038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_adapter_init(struct wpa_driver_ndis_data *drv) 27068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_USE_NDISUIO 27088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef _WIN32_WCE 27098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define NDISUIO_DEVICE_NAME TEXT("\\\\.\\\\Ndisuio") 27108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD written; 27118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 27128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->ndisuio = CreateFile(NDISUIO_DEVICE_NAME, 27138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt GENERIC_READ | GENERIC_WRITE, 0, NULL, 27148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt OPEN_EXISTING, 27158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 27168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt INVALID_HANDLE_VALUE); 27178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->ndisuio == INVALID_HANDLE_VALUE) { 27188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "NDIS: Failed to open connection to " 27198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "NDISUIO: %d", (int) GetLastError()); 27208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt driver_ndis_ndisuio_handle = drv->ndisuio; 27238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef _WIN32_WCE 27258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!DeviceIoControl(drv->ndisuio, IOCTL_NDISUIO_BIND_WAIT, NULL, 0, 27268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, 0, &written, NULL)) { 27278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "NDIS: IOCTL_NDISUIO_BIND_WAIT failed: " 27288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%d", (int) GetLastError()); 27298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CloseHandle(drv->ndisuio); 27308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->ndisuio = INVALID_HANDLE_VALUE; 27318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 27348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_USE_NDISUIO */ 27378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_USE_NDISUIO */ 27398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_adapter_open(struct wpa_driver_ndis_data *drv) 27438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_USE_NDISUIO 27458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD written; 27468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define MAX_NDIS_DEVICE_NAME_LEN 256 27478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WCHAR ifname[MAX_NDIS_DEVICE_NAME_LEN]; 27488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, i, pos; 27498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *prefix = "\\DEVICE\\"; 27508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef _WIN32_WCE 27528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = 0; 27538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* _WIN32_WCE */ 27548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = 8; 27558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 27568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = pos + os_strlen(drv->ifname); 27578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len >= MAX_NDIS_DEVICE_NAME_LEN) 27588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < pos; i++) 27608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ifname[i] = (WCHAR) prefix[i]; 27618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = pos; i < len; i++) 27628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ifname[i] = (WCHAR) drv->ifname[i - pos]; 27638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ifname[i] = L'\0'; 27648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!DeviceIoControl(drv->ndisuio, IOCTL_NDISUIO_OPEN_DEVICE, 27668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ifname, len * sizeof(WCHAR), NULL, 0, &written, 27678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL)) { 27688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "NDIS: IOCTL_NDISUIO_OPEN_DEVICE " 27698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed: %d", (int) GetLastError()); 27708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "NDIS: ifname", 27718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (const u8 *) ifname, len * sizeof(WCHAR)); 27728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CloseHandle(drv->ndisuio); 27738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->ndisuio = INVALID_HANDLE_VALUE; 27748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Opened NDISUIO device successfully"); 27788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_USE_NDISUIO */ 27818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char ifname[128]; 27828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(ifname, sizeof(ifname), "\\Device\\NPF_%s", drv->ifname); 27838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->adapter = PacketOpenAdapter(ifname); 27848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->adapter == NULL) { 27858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: PacketOpenAdapter failed for " 27868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s'", ifname); 27878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_USE_NDISUIO */ 27918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_driver_ndis_adapter_close(struct wpa_driver_ndis_data *drv) 27958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_USE_NDISUIO 27978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt driver_ndis_ndisuio_handle = INVALID_HANDLE_VALUE; 27988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->ndisuio != INVALID_HANDLE_VALUE) 27998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CloseHandle(drv->ndisuio); 28008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_USE_NDISUIO */ 28018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->adapter) 28028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PacketCloseAdapter(drv->adapter); 28038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_USE_NDISUIO */ 28048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ndis_add_multicast(struct wpa_driver_ndis_data *drv) 28088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis_set_oid(drv, OID_802_3_MULTICAST_LIST, 28108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (const char *) pae_group_addr, ETH_ALEN) < 0) { 28118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Failed to add PAE group address " 28128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to the multicast list"); 28138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 28148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 28178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 28188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void * wpa_driver_ndis_init(void *ctx, const char *ifname) 28218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv; 28238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 mode; 28248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv = os_zalloc(sizeof(*drv)); 28268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv == NULL) 28278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 28288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->ctx = ctx; 28298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 28308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Compatibility code to strip possible prefix from the GUID. Previous 28318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * versions include \Device\NPF_ prefix for all names, but the internal 28328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * interface name is now only the GUI. Both Packet32 and NDISUIO 28338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * prefixes are supported. 28348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 28358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(ifname, "\\Device\\NPF_", 12) == 0) 28368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ifname += 12; 28378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (os_strncmp(ifname, "\\DEVICE\\", 8) == 0) 28388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ifname += 8; 28398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); 28408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_driver_ndis_adapter_init(drv) < 0) { 28428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(drv); 28438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 28448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_driver_ndis_get_names(drv) < 0) { 28478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_adapter_close(drv); 28488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(drv); 28498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 28508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_set_wzc(drv, 0); 28538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_driver_ndis_adapter_open(drv) < 0) { 28558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_adapter_close(drv); 28568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(drv); 28578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 28588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis_get_oid(drv, OID_802_3_CURRENT_ADDRESS, 28618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (char *) drv->own_addr, ETH_ALEN) < 0) { 28628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Get OID_802_3_CURRENT_ADDRESS " 28638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed"); 28648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_adapter_close(drv); 28658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(drv); 28668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 28678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_get_capability(drv); 28698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Make sure that the driver does not have any obsolete PMKID entries. 28718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 28728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_flush_pmkid(drv); 28738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 28758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Disconnect to make sure that driver re-associates if it was 28768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * connected. 28778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 28788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_disconnect(drv); 28798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(1, 0, wpa_driver_ndis_poll_timeout, drv, NULL); 28818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_NDIS_EVENTS_INTEGRATED 28838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->events = ndis_events_init(&drv->events_pipe, &drv->event_avail, 28848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->ifname, drv->adapter_desc); 28858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->events == NULL) { 28868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_deinit(drv); 28878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 28888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_event(drv->event_avail, sizeof(drv->event_avail), 28908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_event_pipe_cb, drv, NULL); 28918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NDIS_EVENTS_INTEGRATED */ 28928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef _WIN32_WCE 28948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndisuio_notification_init(drv) < 0) { 28958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_deinit(drv); 28968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 28978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 28998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Set mode here in case card was configured for ad-hoc mode 29018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * previously. */ 29028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mode = Ndis802_11Infrastructure; 29038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis_set_oid(drv, OID_802_11_INFRASTRUCTURE_MODE, 29048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (char *) &mode, sizeof(mode)) < 0) { 29058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[8]; 29068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 29078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Failed to set " 29088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "OID_802_11_INFRASTRUCTURE_MODE (%d)", 29098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) mode); 29108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Try to continue anyway */ 29118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = ndis_get_oid(drv, OID_DOT11_CURRENT_OPERATION_MODE, buf, 29138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(buf)); 29148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res > 0) { 29158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "NDIS: The driver seems to use " 29168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Native 802.11 OIDs. These are not yet " 29178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "fully supported."); 29188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->native80211 = 1; 29198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (!drv->has_capability || drv->capa.enc == 0) { 29208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 29218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Note: This will also happen with NDIS 6 drivers with 29228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Vista. 29238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 29248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Driver did not provide " 29258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "any wireless capabilities - assume it is " 29268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "a wired interface"); 29278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->wired = 1; 29288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.flags |= WPA_DRIVER_FLAGS_WIRED; 29298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->has_capability = 1; 29308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_add_multicast(drv); 29318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return drv; 29358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_driver_ndis_deinit(void *priv) 29398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 29418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_NDIS_EVENTS_INTEGRATED 29438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->events) { 29448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_unregister_event(drv->event_avail, 29458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(drv->event_avail)); 29468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_events_deinit(drv->events); 29478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NDIS_EVENTS_INTEGRATED */ 29498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef _WIN32_WCE 29518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndisuio_notification_deinit(drv); 29528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 29538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_driver_ndis_scan_timeout, drv, drv->ctx); 29558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_driver_ndis_poll_timeout, drv, NULL); 29568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_flush_pmkid(drv); 29578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_disconnect(drv); 29588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_driver_ndis_radio_off(drv) < 0) { 29598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: failed to disassociate and turn " 29608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radio off"); 29618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_adapter_close(drv); 29648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->wzc_disabled) 29668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_set_wzc(drv, 1); 29678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef _WIN32_WCE 29698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(drv->adapter_name); 29708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 29718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(drv->adapter_desc); 29728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(drv); 29738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_interface_info * 29778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_driver_ndis_get_interfaces(void *global_priv) 29788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_interface_info *iface = NULL, *niface; 29808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_USE_NDISUIO 29828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDISUIO_QUERY_BINDING *b; 29838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t blen = sizeof(*b) + 1024; 29848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i, error; 29858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD written; 29868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char name[256], desc[256]; 29878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WCHAR *pos; 29888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t j, len; 29898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HANDLE ndisuio; 29908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndisuio = CreateFile(NDISUIO_DEVICE_NAME, 29928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt GENERIC_READ | GENERIC_WRITE, 0, NULL, 29938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt OPEN_EXISTING, 29948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 29958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt INVALID_HANDLE_VALUE); 29968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndisuio == INVALID_HANDLE_VALUE) { 29978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "NDIS: Failed to open connection to " 29988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "NDISUIO: %d", (int) GetLastError()); 29998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 30008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef _WIN32_WCE 30038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!DeviceIoControl(ndisuio, IOCTL_NDISUIO_BIND_WAIT, NULL, 0, 30048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, 0, &written, NULL)) { 30058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "NDIS: IOCTL_NDISUIO_BIND_WAIT failed: " 30068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%d", (int) GetLastError()); 30078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CloseHandle(ndisuio); 30088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 30098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 30118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b = os_malloc(blen); 30138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (b == NULL) { 30148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CloseHandle(ndisuio); 30158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 30168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; ; i++) { 30198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(b, 0, blen); 30208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b->BindingIndex = i; 30218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!DeviceIoControl(ndisuio, IOCTL_NDISUIO_QUERY_BINDING, 30228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b, sizeof(NDISUIO_QUERY_BINDING), b, blen, 30238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &written, NULL)) { 30248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt error = (int) GetLastError(); 30258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (error == ERROR_NO_MORE_ITEMS) 30268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "IOCTL_NDISUIO_QUERY_BINDING " 30288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed: %d", error); 30298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (WCHAR *) ((char *) b + b->DeviceNameOffset); 30338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = b->DeviceNameLength; 30348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len >= sizeof(name)) 30358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(name) - 1; 30368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < len; j++) 30378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name[j] = (char) pos[j]; 30388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name[len] = '\0'; 30398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (WCHAR *) ((char *) b + b->DeviceDescrOffset); 30418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = b->DeviceDescrLength; 30428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len >= sizeof(desc)) 30438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(desc) - 1; 30448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < len; j++) 30458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc[j] = (char) pos[j]; 30468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc[len] = '\0'; 30478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: %d - %s - %s", i, name, desc); 30498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt niface = os_zalloc(sizeof(*niface)); 30518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (niface == NULL) 30528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt niface->drv_name = "ndis"; 30548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(name, "\\DEVICE\\", 8) == 0) 30558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt niface->ifname = os_strdup(name + 8); 30568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 30578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt niface->ifname = os_strdup(name); 30588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (niface->ifname == NULL) { 30598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(niface); 30608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt niface->desc = os_strdup(desc); 30638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt niface->next = iface; 30648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface = niface; 30658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(b); 30688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CloseHandle(ndisuio); 30698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_USE_NDISUIO */ 30708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PTSTR _names; 30718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *names, *pos, *pos2; 30728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG len; 30738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BOOLEAN res; 30748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *name[MAX_ADAPTERS]; 30758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *desc[MAX_ADAPTERS]; 30768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int num_name, num_desc, i; 30778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Packet.dll version: %s", 30798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PacketGetVersion()); 30808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = 8192; 30828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _names = os_zalloc(len); 30838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (_names == NULL) 30848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 30858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = PacketGetAdapterNames(_names, &len); 30878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!res && len > 8192) { 30888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(_names); 30898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _names = os_zalloc(len); 30908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (_names == NULL) 30918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 30928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = PacketGetAdapterNames(_names, &len); 30938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!res) { 30968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "NDIS: Failed to get adapter list " 30978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(PacketGetAdapterNames)"); 30988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(_names); 30998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 31008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt names = (char *) _names; 31038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (names[0] && names[1] == '\0' && names[2] && names[3] == '\0') { 31048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Looks like adapter names are in " 31058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "UNICODE"); 31068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Convert to ASCII */ 31078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2 = pos = names; 31088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos2 < names + len) { 31098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos2[0] == '\0' && pos2[1] == '\0' && 31108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2[2] == '\0' && pos2[3] == '\0') { 31118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2 += 4; 31128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = pos2[0]; 31158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2 += 2; 31168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos + 2, names, pos - names); 31188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 31198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 31208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = names; 31218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_name = 0; 31238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < names + len) { 31248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name[num_name] = pos; 31258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*pos && pos < names + len) 31268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 31278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 1 >= names + len) { 31288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(names); 31298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 31308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 31328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_name++; 31338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_name >= MAX_ADAPTERS) { 31348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Too many adapters"); 31358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(names); 31368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 31378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == '\0') { 31398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: %d adapter names found", 31408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_name); 31418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 31428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_desc = 0; 31478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < names + len) { 31488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc[num_desc] = pos; 31498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*pos && pos < names + len) 31508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 31518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 1 >= names + len) { 31528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(names); 31538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 31548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 31568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_desc++; 31578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_desc >= MAX_ADAPTERS) { 31588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Too many adapter " 31598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "descriptions"); 31608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(names); 31618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 31628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == '\0') { 31648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: %d adapter descriptions " 31658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "found", num_name); 31668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 31678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 31728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Windows 98 with Packet.dll 3.0 alpha3 does not include adapter 31738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * descriptions. Fill in dummy descriptors to work around this. 31748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 31758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (num_desc < num_name) 31768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc[num_desc++] = "dummy description"; 31778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_name != num_desc) { 31798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: mismatch in adapter name and " 31808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "description counts (%d != %d)", 31818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_name, num_desc); 31828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(names); 31838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 31848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_name; i++) { 31878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt niface = os_zalloc(sizeof(*niface)); 31888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (niface == NULL) 31898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt niface->drv_name = "ndis"; 31918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(name[i], "\\Device\\NPF_", 12) == 0) 31928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt niface->ifname = os_strdup(name[i] + 12); 31938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 31948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt niface->ifname = os_strdup(name[i]); 31958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (niface->ifname == NULL) { 31968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(niface); 31978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt niface->desc = os_strdup(desc[i]); 32008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt niface->next = iface; 32018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface = niface; 32028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 32038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_USE_NDISUIO */ 32058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return iface; 32078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 32088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 32101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic const char *ndis_drv_name = "ndis"; 32111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic const char *ndis_drv_desc = "Windows NDIS driver"; 32121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 32131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstruct wpa_driver_ops wpa_driver_ndis_ops; 32141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 32151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid driver_ndis_init_ops(void) 32161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 32171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memset(&wpa_driver_ndis_ops, 0, sizeof(wpa_driver_ndis_ops)); 32181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.name = ndis_drv_name; 32191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.desc = ndis_drv_desc; 32201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.get_bssid = wpa_driver_ndis_get_bssid; 32211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.get_ssid = wpa_driver_ndis_get_ssid; 32221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.set_key = wpa_driver_ndis_set_key; 32231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.init = wpa_driver_ndis_init; 32241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.deinit = wpa_driver_ndis_deinit; 32251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.deauthenticate = wpa_driver_ndis_deauthenticate; 32261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.disassociate = wpa_driver_ndis_disassociate; 32271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.associate = wpa_driver_ndis_associate; 32281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.add_pmkid = wpa_driver_ndis_add_pmkid; 32291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.remove_pmkid = wpa_driver_ndis_remove_pmkid; 32301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.flush_pmkid = wpa_driver_ndis_flush_pmkid; 32311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.get_capa = wpa_driver_ndis_get_capa; 32321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.poll = wpa_driver_ndis_poll; 32331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.get_ifname = wpa_driver_ndis_get_ifname; 32341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.get_mac_addr = wpa_driver_ndis_get_mac_addr; 32351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.get_scan_results2 = 32361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_get_scan_results; 32371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.get_interfaces = wpa_driver_ndis_get_interfaces; 32381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.scan2 = wpa_driver_ndis_scan; 32391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 3240