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 void wpa_driver_ndis_scan_timeout(void *eloop_ctx, void *timeout_ctx) 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Scan timeout - try to get results"); 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL); 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_scan_native80211( 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv, 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_scan_params *params) 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DOT11_SCAN_REQUEST_V2 req; 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&req, 0, sizeof(req)); 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req.dot11BSSType = dot11_BSS_type_any; 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(req.dot11BSSID, 0xff, ETH_ALEN); 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req.dot11ScanType = dot11_scan_type_auto; 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = ndis_set_oid(drv, OID_DOT11_SCAN_REQUEST, (char *) &req, 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(req)); 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_driver_ndis_scan_timeout, drv, drv->ctx); 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(7, 0, wpa_driver_ndis_scan_timeout, drv, 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->ctx); 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_scan(void *priv, 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_scan_params *params) 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->native80211) 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_driver_ndis_scan_native80211(drv, params); 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!drv->radio_enabled) { 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: turning radio on before the first" 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " scan"); 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_driver_ndis_disconnect(drv) < 0) { 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: failed to enable radio"); 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->radio_enabled = 1; 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = ndis_set_oid(drv, OID_802_11_BSSID_LIST_SCAN, " ", 4); 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_driver_ndis_scan_timeout, drv, drv->ctx); 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(7, 0, wpa_driver_ndis_scan_timeout, drv, 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->ctx); 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie) 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *end, *pos; 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (const u8 *) (res + 1); 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = pos + res->ie_len; 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos + 1 < end) { 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 2 + pos[1] > end) 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[0] == ie) 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos; 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2 + pos[1]; 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_scan_res * wpa_driver_ndis_add_scan_ssid( 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_res *r, NDIS_802_11_SSID *ssid) 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_res *nr; 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos; 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_scan_get_ie(r, WLAN_EID_SSID)) 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return r; /* SSID IE already present */ 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->SsidLength == 0 || ssid->SsidLength > 32) 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return r; /* No valid SSID inside scan data */ 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nr = os_realloc(r, sizeof(*r) + r->ie_len + 2 + ssid->SsidLength); 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (nr == NULL) 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return r; 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = ((u8 *) (nr + 1)) + nr->ie_len; 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = WLAN_EID_SSID; 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = ssid->SsidLength; 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, ssid->Ssid, ssid->SsidLength); 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nr->ie_len += 2 + ssid->SsidLength; 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return nr; 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_scan_results * wpa_driver_ndis_get_scan_results(void *priv) 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_BSSID_LIST_EX *b; 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t blen, count, i; 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len; 8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *pos; 8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_results *results; 8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_scan_res *r; 8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt blen = 65535; 8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b = os_zalloc(blen); 8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (b == NULL) 8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = ndis_get_oid(drv, OID_802_11_BSSID_LIST, (char *) b, blen); 8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 0) { 8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: failed to get scan results"); 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(b); 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count = b->NumberOfItems; 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt results = os_zalloc(sizeof(*results)); 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (results == NULL) { 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(b); 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 85361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt results->res = os_calloc(count, sizeof(struct wpa_scan_res *)); 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (results->res == NULL) { 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(results); 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(b); 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (char *) &b->Bssid[0]; 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < count; i++) { 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_WLAN_BSSID_EX *bss = (NDIS_WLAN_BSSID_EX *) pos; 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_FIXED_IEs *fixed; 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bss->IELength < sizeof(NDIS_802_11_FIXED_IEs)) { 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: too small IELength=%d", 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) bss->IELength); 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (((char *) bss->IEs) + bss->IELength > (char *) b + blen) { 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Some NDIS drivers have been reported to include an 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * entry with an invalid IELength in scan results and 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * this has crashed wpa_supplicant, so validate the 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * returned value before using it. 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: skipped invalid scan " 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "result IE (BSSID=" MACSTR ") IELength=%d", 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(bss->MacAddress), 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) bss->IELength); 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = os_zalloc(sizeof(*r) + bss->IELength - 8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(NDIS_802_11_FIXED_IEs)); 8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (r == NULL) 8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(r->bssid, bss->MacAddress, ETH_ALEN); 8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r->level = (int) bss->Rssi; 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r->freq = bss->Configuration.DSConfig / 1000; 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fixed = (NDIS_802_11_FIXED_IEs *) bss->IEs; 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r->beacon_int = WPA_GET_LE16((u8 *) &fixed->BeaconInterval); 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r->caps = WPA_GET_LE16((u8 *) &fixed->Capabilities); 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r->tsf = WPA_GET_LE64(fixed->Timestamp); 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(r + 1, bss->IEs + sizeof(NDIS_802_11_FIXED_IEs), 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bss->IELength - sizeof(NDIS_802_11_FIXED_IEs)); 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r->ie_len = bss->IELength - sizeof(NDIS_802_11_FIXED_IEs); 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt r = wpa_driver_ndis_add_scan_ssid(r, &bss->Ssid); 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt results->res[results->num++] = r; 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += bss->Length; 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos > (char *) b + blen) 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(b); 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return results; 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_remove_key(struct wpa_driver_ndis_data *drv, 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int key_idx, const u8 *addr, 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *bssid, int pairwise) 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_REMOVE_KEY rkey; 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_KEY_INDEX index; 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res, res2; 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&rkey, 0, sizeof(rkey)); 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rkey.Length = sizeof(rkey); 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rkey.KeyIndex = key_idx; 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pairwise) 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rkey.KeyIndex |= 1 << 30; 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(rkey.BSSID, bssid, ETH_ALEN); 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = ndis_set_oid(drv, OID_802_11_REMOVE_KEY, (char *) &rkey, 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(rkey)); 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!pairwise) { 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt index = key_idx; 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res2 = ndis_set_oid(drv, OID_802_11_REMOVE_WEP, 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (char *) &index, sizeof(index)); 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res2 = 0; 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0 && res2 < 0) 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_add_wep(struct wpa_driver_ndis_data *drv, 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int pairwise, int key_idx, int set_tx, 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *key, size_t key_len) 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_WEP *wep; 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = 12 + key_len; 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wep = os_zalloc(len); 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wep == NULL) 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wep->Length = len; 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wep->KeyIndex = key_idx; 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (set_tx) 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wep->KeyIndex |= 1 << 31; 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if 0 /* Setting bit30 does not seem to work with some NDIS drivers */ 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pairwise) 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wep->KeyIndex |= 1 << 30; 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wep->KeyLength = key_len; 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wep->KeyMaterial, key, key_len); 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_MSGDUMP, "NDIS: OID_802_11_ADD_WEP", 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) wep, len); 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = ndis_set_oid(drv, OID_802_11_ADD_WEP, (char *) wep, len); 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wep); 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_set_key(const char *ifname, void *priv, 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum wpa_alg alg, const u8 *addr, 9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int key_idx, int set_tx, 9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *seq, size_t seq_len, 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *key, size_t key_len) 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, i; 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_KEY *nkey; 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res, pairwise; 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 bssid[ETH_ALEN]; 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (addr == NULL || is_broadcast_ether_addr(addr)) { 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Group Key */ 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pairwise = 0; 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_driver_ndis_get_bssid(drv, bssid) < 0) 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(bssid, 0xff, ETH_ALEN); 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Pairwise Key */ 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pairwise = 1; 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(bssid, addr, ETH_ALEN); 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (alg == WPA_ALG_NONE || key_len == 0) { 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_driver_ndis_remove_key(drv, key_idx, addr, bssid, 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pairwise); 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (alg == WPA_ALG_WEP) { 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_driver_ndis_add_wep(drv, pairwise, key_idx, set_tx, 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key, key_len); 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = 12 + 6 + 6 + 8 + key_len; 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nkey = os_zalloc(len); 10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (nkey == NULL) 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nkey->Length = len; 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nkey->KeyIndex = key_idx; 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (set_tx) 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nkey->KeyIndex |= 1 << 31; 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pairwise) 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nkey->KeyIndex |= 1 << 30; 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (seq && seq_len) 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nkey->KeyIndex |= 1 << 29; 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nkey->KeyLength = key_len; 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(nkey->BSSID, bssid, ETH_ALEN); 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (seq && seq_len) { 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < seq_len; i++) 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt nkey->KeyRSC |= (ULONGLONG) seq[i] << (i * 8); 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (alg == WPA_ALG_TKIP && key_len == 32) { 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(nkey->KeyMaterial, key, 16); 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(nkey->KeyMaterial + 16, key + 24, 8); 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(nkey->KeyMaterial + 24, key + 16, 8); 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(nkey->KeyMaterial, key, key_len); 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_MSGDUMP, "NDIS: OID_802_11_ADD_KEY", 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) nkey, len); 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = ndis_set_oid(drv, OID_802_11_ADD_KEY, (char *) nkey, len); 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(nkey); 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int 10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_driver_ndis_associate(void *priv, 10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_associate_params *params) 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 auth_mode, encr, priv_mode, mode; 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->mode = params->mode; 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Note: Setting OID_802_11_INFRASTRUCTURE_MODE clears current keys, 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * so static WEP keys needs to be set again after this. */ 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->mode == IEEE80211_MODE_IBSS) { 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mode = Ndis802_11IBSS; 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Need to make sure that BSSID polling is enabled for 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * IBSS mode. */ 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_driver_ndis_poll_timeout, drv, NULL); 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(1, 0, wpa_driver_ndis_poll_timeout, 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv, NULL); 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mode = Ndis802_11Infrastructure; 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis_set_oid(drv, OID_802_11_INFRASTRUCTURE_MODE, 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (char *) &mode, sizeof(mode)) < 0) { 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Failed to set " 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "OID_802_11_INFRASTRUCTURE_MODE (%d)", 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) mode); 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Try to continue anyway */ 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1077fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (params->key_mgmt_suite == WPA_KEY_MGMT_NONE || 1078fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt params->key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_NO_WPA) { 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Re-set WEP keys if static WEP configuration is used. */ 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 4; i++) { 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!params->wep_key[i]) 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Re-setting static WEP " 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "key %d", i); 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_set_key(drv->ifname, drv, WPA_ALG_WEP, 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bcast, i, 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i == params->wep_tx_keyidx, 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, 0, params->wep_key[i], 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->wep_key_len[i]); 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->wpa_ie == NULL || params->wpa_ie_len == 0) { 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->auth_alg & WPA_AUTH_ALG_SHARED) { 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->auth_alg & WPA_AUTH_ALG_OPEN) 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_mode = Ndis802_11AuthModeAutoSwitch; 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_mode = Ndis802_11AuthModeShared; 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_mode = Ndis802_11AuthModeOpen; 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv_mode = Ndis802_11PrivFilterAcceptAll; 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (params->wpa_ie[0] == WLAN_EID_RSN) { 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv_mode = Ndis802_11PrivFilter8021xWEP; 1105fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (params->key_mgmt_suite == WPA_KEY_MGMT_PSK) 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_mode = Ndis802_11AuthModeWPA2PSK; 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_mode = Ndis802_11AuthModeWPA2; 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 1110fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt } else if (params->key_mgmt_suite == WPA_KEY_MGMT_WPS) { 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_mode = Ndis802_11AuthModeOpen; 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv_mode = Ndis802_11PrivFilterAcceptAll; 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->wps == WPS_MODE_PRIVACY) { 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 dummy_key[5] = { 0x11, 0x22, 0x33, 0x44, 0x55 }; 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Some NDIS drivers refuse to associate in open mode 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * configuration due to Privacy field mismatch, so use 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * a workaround to make the configuration look like 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * matching one for WPS provisioning. 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Set dummy WEP key as a " 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "workaround to allow driver to associate " 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for WPS"); 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_set_key(drv->ifname, drv, WPA_ALG_WEP, 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bcast, 0, 1, 11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, 0, dummy_key, 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(dummy_key)); 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv_mode = Ndis802_11PrivFilter8021xWEP; 1132fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (params->key_mgmt_suite == WPA_KEY_MGMT_WPA_NONE) 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_mode = Ndis802_11AuthModeWPANone; 1134fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt else if (params->key_mgmt_suite == WPA_KEY_MGMT_PSK) 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_mode = Ndis802_11AuthModeWPAPSK; 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt auth_mode = Ndis802_11AuthModeWPA; 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (params->pairwise_suite) { 1141fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt case WPA_CIPHER_CCMP: 11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr = Ndis802_11Encryption3Enabled; 11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1144fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt case WPA_CIPHER_TKIP: 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr = Ndis802_11Encryption2Enabled; 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1147fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt case WPA_CIPHER_WEP40: 1148fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt case WPA_CIPHER_WEP104: 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr = Ndis802_11Encryption1Enabled; 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1151fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt case WPA_CIPHER_NONE: 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->wps == WPS_MODE_PRIVACY) { 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr = Ndis802_11Encryption1Enabled; 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 1158fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt if (params->group_suite == WPA_CIPHER_CCMP) 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr = Ndis802_11Encryption3Enabled; 1160fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt else if (params->group_suite == WPA_CIPHER_TKIP) 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr = Ndis802_11Encryption2Enabled; 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr = Ndis802_11EncryptionDisabled; 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->wps == WPS_MODE_PRIVACY) { 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr = Ndis802_11Encryption1Enabled; 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt encr = Ndis802_11EncryptionDisabled; 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt }; 11758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis_set_oid(drv, OID_802_11_PRIVACY_FILTER, 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (char *) &priv_mode, sizeof(priv_mode)) < 0) { 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Failed to set " 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "OID_802_11_PRIVACY_FILTER (%d)", 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) priv_mode); 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Try to continue anyway */ 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_set_auth_mode(drv, auth_mode); 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_set_encr_status(drv, encr); 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->bssid) { 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_set_oid(drv, OID_802_11_BSSID, (char *) params->bssid, 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->oid_bssid_set = 1; 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (drv->oid_bssid_set) { 11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_set_oid(drv, OID_802_11_BSSID, "\xff\xff\xff\xff\xff\xff", 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ETH_ALEN); 11948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->oid_bssid_set = 0; 11958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_driver_ndis_set_ssid(drv, params->ssid, params->ssid_len); 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_set_pmkid(struct wpa_driver_ndis_data *drv) 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len, count, i, ret; 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ndis_pmkid_entry *entry; 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_PMKID *p; 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count = 0; 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = drv->pmkid; 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (entry) { 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (count >= drv->no_of_pmkid) 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = entry->next; 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = 8 + count * sizeof(BSSID_INFO); 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p = os_zalloc(len); 12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (p == NULL) 12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p->Length = len; 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p->BSSIDInfoCount = count; 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = drv->pmkid; 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < count; i++) { 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&p->BSSIDInfo[i].BSSID, entry->bssid, ETH_ALEN); 12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(&p->BSSIDInfo[i].PMKID, entry->pmkid, 16); 12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = entry->next; 12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "NDIS: OID_802_11_PMKID", (u8 *) p, len); 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = ndis_set_oid(drv, OID_802_11_PMKID, (char *) p, len); 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(p); 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_add_pmkid(void *priv, const u8 *bssid, 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pmkid) 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ndis_pmkid_entry *entry, *prev; 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->no_of_pmkid == 0) 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = NULL; 12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = drv->pmkid; 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (entry) { 12478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(entry->bssid, bssid, ETH_ALEN) == 0) 12488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = entry; 12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = entry->next; 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry) { 12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Replace existing entry for this BSSID and move it into the 12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * beginning of the list. */ 12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(entry->pmkid, pmkid, 16); 12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev) { 12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev->next = entry->next; 12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->next = drv->pmkid; 12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->pmkid = entry; 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = os_malloc(sizeof(*entry)); 12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (entry) { 12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(entry->bssid, bssid, ETH_ALEN); 12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(entry->pmkid, pmkid, 16); 12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry->next = drv->pmkid; 12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->pmkid = entry; 12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_driver_ndis_set_pmkid(drv); 12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_remove_pmkid(void *priv, const u8 *bssid, 12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pmkid) 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ndis_pmkid_entry *entry, *prev; 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->no_of_pmkid == 0) 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = drv->pmkid; 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = NULL; 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (entry) { 12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(entry->bssid, bssid, ETH_ALEN) == 0 && 12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(entry->pmkid, pmkid, 16) == 0) { 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev) 12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev->next = entry->next; 12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->pmkid = entry->next; 12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(entry); 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = entry; 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt entry = entry->next; 12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_driver_ndis_set_pmkid(drv); 13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_flush_pmkid(void *priv) 13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_PMKID p; 13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ndis_pmkid_entry *pmkid, *prev; 13098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int prev_authmode, ret; 13108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->no_of_pmkid == 0) 13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmkid = drv->pmkid; 13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->pmkid = NULL; 13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pmkid) { 13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev = pmkid; 13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmkid = pmkid->next; 13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(prev); 13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Some drivers may refuse OID_802_11_PMKID if authMode is not set to 13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPA2, so change authMode temporarily, if needed. 13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 13268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prev_authmode = ndis_get_auth_mode(drv); 13278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev_authmode != Ndis802_11AuthModeWPA2) 13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_set_auth_mode(drv, Ndis802_11AuthModeWPA2); 13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&p, 0, sizeof(p)); 13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p.Length = 8; 13328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p.BSSIDInfoCount = 0; 13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "NDIS: OID_802_11_PMKID (flush)", 13348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) &p, 8); 13358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = ndis_set_oid(drv, OID_802_11_PMKID, (char *) &p, 8); 13368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (prev_authmode != Ndis802_11AuthModeWPA2) 13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_set_auth_mode(drv, prev_authmode); 13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_get_associnfo(struct wpa_driver_ndis_data *drv) 13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[512], *pos; 13478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_ASSOCIATION_INFORMATION *ai; 13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len; 13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union wpa_event_data data; 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_BSSID_LIST_EX *b; 13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t blen, i; 13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = ndis_get_oid(drv, OID_802_11_ASSOCIATION_INFORMATION, buf, 13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(buf)); 13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 0) { 13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: failed to get association " 13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "information"); 13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > sizeof(buf)) { 13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Some drivers seem to be producing incorrect length for this 13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * data. Limit the length to the current buffer size to avoid 13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * crashing in hexdump. The data seems to be otherwise valid, 13648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * so better try to use it. */ 13658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: ignored bogus association " 13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "information length %d", len); 13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = ndis_get_oid(drv, OID_802_11_ASSOCIATION_INFORMATION, 13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf, sizeof(buf)); 13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < -1) { 13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: re-reading association " 13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "information failed"); 13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > sizeof(buf)) { 13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: ignored bogus association" 13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " information length %d (re-read)", len); 13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(buf); 13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "NDIS: association information", 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) buf, len); 13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < sizeof(*ai)) { 13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: too short association " 13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "information"); 13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ai = (NDIS_802_11_ASSOCIATION_INFORMATION *) buf; 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: ReqFixed=0x%x RespFixed=0x%x off_req=%d " 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "off_resp=%d len_req=%d len_resp=%d", 13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ai->AvailableRequestFixedIEs, ai->AvailableResponseFixedIEs, 13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) ai->OffsetRequestIEs, (int) ai->OffsetResponseIEs, 13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) ai->RequestIELength, (int) ai->ResponseIELength); 13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ai->OffsetRequestIEs + ai->RequestIELength > (unsigned) len || 13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ai->OffsetResponseIEs + ai->ResponseIELength > (unsigned) len) { 13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: association information - " 13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "IE overflow"); 13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "NDIS: Request IEs", 14028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) buf + ai->OffsetRequestIEs, ai->RequestIELength); 14038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "NDIS: Response IEs", 14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) buf + ai->OffsetResponseIEs, ai->ResponseIELength); 14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&data, 0, sizeof(data)); 14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data.assoc_info.req_ies = (u8 *) buf + ai->OffsetRequestIEs; 14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data.assoc_info.req_ies_len = ai->RequestIELength; 14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data.assoc_info.resp_ies = (u8 *) buf + ai->OffsetResponseIEs; 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data.assoc_info.resp_ies_len = ai->ResponseIELength; 14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt blen = 65535; 14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b = os_zalloc(blen); 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (b == NULL) 14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto skip_scan_results; 14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = ndis_get_oid(drv, OID_802_11_BSSID_LIST, (char *) b, blen); 14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 0) { 14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: failed to get scan results"); 14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(b); 14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b = NULL; 14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto skip_scan_results; 14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: %d BSSID items to process for AssocInfo", 14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned int) b->NumberOfItems); 14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (char *) &b->Bssid[0]; 14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < b->NumberOfItems; i++) { 14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_WLAN_BSSID_EX *bss = (NDIS_WLAN_BSSID_EX *) pos; 14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(drv->bssid, bss->MacAddress, ETH_ALEN) == 0 && 14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bss->IELength > sizeof(NDIS_802_11_FIXED_IEs)) { 14318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data.assoc_info.beacon_ies = 14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ((u8 *) bss->IEs) + 14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(NDIS_802_11_FIXED_IEs); 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data.assoc_info.beacon_ies_len = 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bss->IELength - sizeof(NDIS_802_11_FIXED_IEs); 14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "NDIS: Beacon IEs", 14378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data.assoc_info.beacon_ies, 14388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data.assoc_info.beacon_ies_len); 14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += bss->Length; 14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos > (char *) b + blen) 14438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtskip_scan_results: 14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_event(drv->ctx, EVENT_ASSOCINFO, &data); 14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(b); 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_driver_ndis_poll_timeout(void *eloop_ctx, void *timeout_ctx) 14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = eloop_ctx; 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 bssid[ETH_ALEN]; 14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int poll; 14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->wired) 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_driver_ndis_get_bssid(drv, bssid)) { 14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Disconnected */ 14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!is_zero_ether_addr(drv->bssid)) { 14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(drv->bssid, 0, ETH_ALEN); 14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL); 14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Connected */ 14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(drv->bssid, bssid, ETH_ALEN) != 0) { 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(drv->bssid, bssid, ETH_ALEN); 14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_get_associnfo(drv); 14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL); 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* When using integrated NDIS event receiver, we can skip BSSID 14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * polling when using infrastructure network. However, when using 14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * IBSS mode, many driver do not seem to generate connection event, 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * so we need to enable BSSID polling to figure out when IBSS network 14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * has been formed. 14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt poll = drv->mode == IEEE80211_MODE_IBSS; 14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NDIS_EVENTS_INTEGRATED 14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef _WIN32_WCE 14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt poll = 1; 14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NDIS_EVENTS_INTEGRATED */ 14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (poll) { 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(1, 0, wpa_driver_ndis_poll_timeout, 14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv, NULL); 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_driver_ndis_poll(void *priv) 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_driver_ndis_poll_timeout, drv, NULL); 15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_poll_timeout(drv, NULL); 15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Called when driver generates Media Connect Event by calling 15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * NdisMIndicateStatus() with NDIS_STATUS_MEDIA_CONNECT */ 15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_driver_ndis_event_connect(struct wpa_driver_ndis_data *drv) 15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Media Connect Event"); 15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_driver_ndis_get_bssid(drv, drv->bssid) == 0) { 15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_get_associnfo(drv); 15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL); 15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Called when driver generates Media Disconnect Event by calling 15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * NdisMIndicateStatus() with NDIS_STATUS_MEDIA_DISCONNECT */ 15218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_driver_ndis_event_disconnect(struct wpa_driver_ndis_data *drv) 15228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Media Disconnect Event"); 15248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(drv->bssid, 0, ETH_ALEN); 15258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL); 15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_driver_ndis_event_auth(struct wpa_driver_ndis_data *drv, 15308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t data_len) 15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_AUTHENTICATION_REQUEST *req; 15338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int pairwise = 0, group = 0; 15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union wpa_event_data event; 15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data_len < sizeof(*req)) { 15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Too short Authentication Request " 15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Event (len=%d)", data_len); 15398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req = (NDIS_802_11_AUTHENTICATION_REQUEST *) data; 15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Authentication Request Event: " 15448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Bssid " MACSTR " Flags 0x%x", 15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(req->Bssid), (int) req->Flags); 15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((req->Flags & NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR) == 15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR) 15498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pairwise = 1; 15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if ((req->Flags & NDIS_802_11_AUTH_REQUEST_GROUP_ERROR) == 15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_AUTH_REQUEST_GROUP_ERROR) 15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt group = 1; 15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pairwise || group) { 15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&event, 0, sizeof(event)); 15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt event.michael_mic_failure.unicast = pairwise; 15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_event(drv->ctx, EVENT_MICHAEL_MIC_FAILURE, 15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &event); 15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_driver_ndis_event_pmkid(struct wpa_driver_ndis_data *drv, 15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t data_len) 15658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_PMKID_CANDIDATE_LIST *pmkid; 15678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 15688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union wpa_event_data event; 15698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data_len < 8) { 15718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Too short PMKID Candidate List " 15728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Event (len=%d)", data_len); 15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pmkid = (NDIS_802_11_PMKID_CANDIDATE_LIST *) data; 15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: PMKID Candidate List Event - Version %d " 15778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "NumCandidates %d", 15788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) pmkid->Version, (int) pmkid->NumCandidates); 15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pmkid->Version != 1) { 15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Unsupported PMKID Candidate List " 15828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Version %d", (int) pmkid->Version); 15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data_len < 8 + pmkid->NumCandidates * sizeof(PMKID_CANDIDATE)) { 15878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: PMKID Candidate List underflow"); 15888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 15898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 15908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&event, 0, sizeof(event)); 15928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < pmkid->NumCandidates; i++) { 15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PMKID_CANDIDATE *p = &pmkid->CandidateList[i]; 15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: %d: " MACSTR " Flags 0x%x", 15958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i, MAC2STR(p->BSSID), (int) p->Flags); 15968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(event.pmkid_candidate.bssid, p->BSSID, ETH_ALEN); 15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt event.pmkid_candidate.index = i; 15988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt event.pmkid_candidate.preauth = 15998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt p->Flags & NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED; 16008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_event(drv->ctx, EVENT_PMKID_CANDIDATE, 16018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &event); 16028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Called when driver calls NdisMIndicateStatus() with 16078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * NDIS_STATUS_MEDIA_SPECIFIC_INDICATION */ 16088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_driver_ndis_event_media_specific(struct wpa_driver_ndis_data *drv, 16098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t data_len) 16108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_STATUS_INDICATION *status; 16128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data == NULL || data_len < sizeof(*status)) 16148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 16158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "NDIS: Media Specific Indication", 16178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data, data_len); 16188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = (NDIS_802_11_STATUS_INDICATION *) data; 16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data += sizeof(status); 16218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data_len -= sizeof(status); 16228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (status->StatusType) { 16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Ndis802_11StatusType_Authentication: 16258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_event_auth(drv, data, data_len); 16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Ndis802_11StatusType_PMKID_CandidateList: 16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_event_pmkid(drv, data, data_len); 16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 16318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Unknown StatusType %d", 16328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) status->StatusType); 16338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Called when an adapter is added */ 16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_driver_ndis_event_adapter_arrival(struct wpa_driver_ndis_data *drv) 16408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union wpa_event_data event; 16428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 16438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Notify Adapter Arrival"); 16458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 30; i++) { 16478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Re-open Packet32/NDISUIO connection */ 16488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_adapter_close(drv); 16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_driver_ndis_adapter_init(drv) < 0 || 16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_adapter_open(drv) < 0) { 16518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Driver re-initialization " 16528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(%d) failed", i); 16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_sleep(1, 0); 16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Driver re-initialized"); 16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&event, 0, sizeof(event)); 16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(event.interface_status.ifname, drv->ifname, 16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(event.interface_status.ifname)); 16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt event.interface_status.ievent = EVENT_INTERFACE_ADDED; 16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event); 16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Called when an adapter is removed */ 16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_driver_ndis_event_adapter_removal(struct wpa_driver_ndis_data *drv) 16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union wpa_event_data event; 16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Notify Adapter Removal"); 16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&event, 0, sizeof(event)); 16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(event.interface_status.ifname, drv->ifname, 16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(event.interface_status.ifname)); 16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt event.interface_status.ievent = EVENT_INTERFACE_REMOVED; 16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event); 16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void 16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_driver_ndis_get_wpa_capability(struct wpa_driver_ndis_data *drv) 16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: verifying driver WPA capability"); 16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis_set_auth_mode(drv, Ndis802_11AuthModeWPA) == 0 && 16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_get_auth_mode(drv) == Ndis802_11AuthModeWPA) { 16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: WPA key management supported"); 16908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA; 16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis_set_auth_mode(drv, Ndis802_11AuthModeWPAPSK) == 0 && 16948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_get_auth_mode(drv) == Ndis802_11AuthModeWPAPSK) { 16958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: WPA-PSK key management " 16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "supported"); 16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK; 16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis_set_encr_status(drv, Ndis802_11Encryption3Enabled) == 0 && 17018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_get_encr_status(drv) == Ndis802_11Encryption3KeyAbsent) { 17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: CCMP encryption supported"); 17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP; 17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis_set_encr_status(drv, Ndis802_11Encryption2Enabled) == 0 && 17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_get_encr_status(drv) == Ndis802_11Encryption2KeyAbsent) { 17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: TKIP encryption supported"); 17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.enc |= WPA_DRIVER_CAPA_ENC_TKIP; 17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis_set_encr_status(drv, Ndis802_11Encryption1Enabled) == 0 && 17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_get_encr_status(drv) == Ndis802_11Encryption1KeyAbsent) { 17148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: WEP encryption supported"); 17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP40 | 17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_DRIVER_CAPA_ENC_WEP104; 17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis_set_auth_mode(drv, Ndis802_11AuthModeShared) == 0 && 17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_get_auth_mode(drv) == Ndis802_11AuthModeShared) { 17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.auth |= WPA_DRIVER_AUTH_SHARED; 17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis_set_auth_mode(drv, Ndis802_11AuthModeOpen) == 0 && 17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_get_auth_mode(drv) == Ndis802_11AuthModeOpen) { 17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.auth |= WPA_DRIVER_AUTH_OPEN; 17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_set_encr_status(drv, Ndis802_11EncryptionDisabled); 17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Could also verify OID_802_11_ADD_KEY error reporting and 17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * support for OID_802_11_ASSOCIATION_INFORMATION. */ 17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA && 17358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.enc & (WPA_DRIVER_CAPA_ENC_TKIP | 17368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_DRIVER_CAPA_ENC_CCMP)) { 17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: driver supports WPA"); 17388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->has_capability = 1; 17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 17408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: no WPA support found"); 17418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: driver capabilities: key_mgmt 0x%x " 17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "enc 0x%x auth 0x%x", 17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.key_mgmt, drv->capa.enc, drv->capa.auth); 17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 17478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_driver_ndis_get_capability(struct wpa_driver_ndis_data *drv) 17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[512]; 17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len; 17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_CAPABILITY *c; 17558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.flags = WPA_DRIVER_FLAGS_DRIVER_IE; 17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = ndis_get_oid(drv, OID_802_11_CAPABILITY, buf, sizeof(buf)); 17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 0) { 17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_get_wpa_capability(drv); 17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "OID_802_11_CAPABILITY", (u8 *) buf, len); 17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt c = (NDIS_802_11_CAPABILITY *) buf; 17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < sizeof(*c) || c->Version != 2) { 17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: unsupported " 17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "OID_802_11_CAPABILITY data"); 17698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 17708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Driver supports OID_802_11_CAPABILITY - " 17728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "NoOfPMKIDs %d NoOfAuthEncrPairs %d", 17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) c->NoOfPMKIDs, 17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) c->NoOfAuthEncryptPairsSupported); 17758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->has_capability = 1; 17768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->no_of_pmkid = c->NoOfPMKIDs; 17778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < c->NoOfAuthEncryptPairsSupported; i++) { 17788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDIS_802_11_AUTHENTICATION_ENCRYPTION *ae; 17798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ae = &c->AuthenticationEncryptionSupported[i]; 17808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((char *) (ae + 1) > buf + len) { 17818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: auth/encr pair list " 17828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "overflow"); 17838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_MSGDUMP, "NDIS: %d - auth %d encr %d", 17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i, (int) ae->AuthModeSupported, 17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) ae->EncryptStatusSupported); 17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (ae->AuthModeSupported) { 17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Ndis802_11AuthModeOpen: 17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.auth |= WPA_DRIVER_AUTH_OPEN; 17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Ndis802_11AuthModeShared: 17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.auth |= WPA_DRIVER_AUTH_SHARED; 17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Ndis802_11AuthModeWPA: 17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA; 17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Ndis802_11AuthModeWPAPSK: 17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK; 18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Ndis802_11AuthModeWPA2: 18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA2; 18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Ndis802_11AuthModeWPA2PSK: 18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.key_mgmt |= 18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK; 18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Ndis802_11AuthModeWPANone: 18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.key_mgmt |= 18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE; 18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (ae->EncryptStatusSupported) { 18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Ndis802_11Encryption1Enabled: 18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP40; 18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP104; 18198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Ndis802_11Encryption2Enabled: 18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.enc |= WPA_DRIVER_CAPA_ENC_TKIP; 18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case Ndis802_11Encryption3Enabled: 18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP; 18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: driver capabilities: key_mgmt 0x%x " 18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "enc 0x%x auth 0x%x", 18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.key_mgmt, drv->capa.enc, drv->capa.auth); 18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_get_capa(void *priv, struct wpa_driver_capa *capa) 18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!drv->has_capability) 18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(capa, &drv->capa, sizeof(*capa)); 18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * wpa_driver_ndis_get_ifname(void *priv) 18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return drv->ifname; 18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const u8 * wpa_driver_ndis_get_mac_addr(void *priv) 18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return drv->own_addr; 18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef _WIN32_WCE 18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define NDISUIO_MSG_SIZE (sizeof(NDISUIO_DEVICE_NOTIFICATION) + 512) 18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ndisuio_notification_receive(void *eloop_data, void *user_ctx) 18668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 18678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = eloop_data; 18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDISUIO_DEVICE_NOTIFICATION *hdr; 18698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 buf[NDISUIO_MSG_SIZE]; 18708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD len, flags; 18718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ReadMsgQueue(drv->event_queue, buf, NDISUIO_MSG_SIZE, &len, 0, 18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &flags)) { 18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ndisuio_notification_receive: " 18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ReadMsgQueue failed: %d", (int) GetLastError()); 18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < sizeof(NDISUIO_DEVICE_NOTIFICATION)) { 18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "ndisuio_notification_receive: " 18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Too short message (len=%d)", (int) len); 18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr = (NDISUIO_DEVICE_NOTIFICATION *) buf; 18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Notification received: len=%d type=0x%x", 18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) len, hdr->dwNotificationType); 18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 18898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (hdr->dwNotificationType) { 18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef NDISUIO_NOTIFICATION_ADAPTER_ARRIVAL 18918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case NDISUIO_NOTIFICATION_ADAPTER_ARRIVAL: 18928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: ADAPTER_ARRIVAL"); 18938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_event_adapter_arrival(drv); 18948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 18958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 18968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef NDISUIO_NOTIFICATION_ADAPTER_REMOVAL 18978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case NDISUIO_NOTIFICATION_ADAPTER_REMOVAL: 18988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: ADAPTER_REMOVAL"); 18998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_event_adapter_removal(drv); 19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case NDISUIO_NOTIFICATION_MEDIA_CONNECT: 19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: MEDIA_CONNECT"); 19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SetEvent(drv->connected_event); 19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_event_connect(drv); 19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case NDISUIO_NOTIFICATION_MEDIA_DISCONNECT: 19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ResetEvent(drv->connected_event); 19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: MEDIA_DISCONNECT"); 19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_event_disconnect(drv); 19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case NDISUIO_NOTIFICATION_MEDIA_SPECIFIC_NOTIFICATION: 19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: MEDIA_SPECIFIC_NOTIFICATION"); 19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if _WIN32_WCE == 420 || _WIN32_WCE == 0x420 19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_event_media_specific( 19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv, hdr->pvStatusBuffer, hdr->uiStatusBufferSize); 19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else 19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_event_media_specific( 19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv, ((const u8 *) hdr) + hdr->uiOffsetToStatusBuffer, 19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (size_t) hdr->uiStatusBufferSize); 19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 19248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Unknown notification type 0x%x", 19258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hdr->dwNotificationType); 19268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 19278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ndisuio_notification_deinit(struct wpa_driver_ndis_data *drv) 19328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDISUIO_REQUEST_NOTIFICATION req; 19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt memset(&req, 0, sizeof(req)); 19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req.hMsgQueue = drv->event_queue; 19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req.dwNotificationTypes = 0; 19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!DeviceIoControl(drv->ndisuio, IOCTL_NDISUIO_REQUEST_NOTIFICATION, 19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &req, sizeof(req), NULL, 0, NULL, NULL)) { 19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "ndisuio_notification_deinit: " 19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "IOCTL_NDISUIO_REQUEST_NOTIFICATION failed: %d", 19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 19448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!DeviceIoControl(drv->ndisuio, IOCTL_NDISUIO_CANCEL_NOTIFICATION, 19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, 0, NULL, 0, NULL, NULL)) { 19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "ndisuio_notification_deinit: " 19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "IOCTL_NDISUIO_CANCEL_NOTIFICATION failed: %d", 19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->event_queue) { 19548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_unregister_event(drv->event_queue, 19558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(drv->event_queue)); 19568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CloseHandle(drv->event_queue); 19578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->event_queue = NULL; 19588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->connected_event) { 19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CloseHandle(drv->connected_event); 19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->connected_event = NULL; 19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ndisuio_notification_init(struct wpa_driver_ndis_data *drv) 19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MSGQUEUEOPTIONS opt; 19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDISUIO_REQUEST_NOTIFICATION req; 19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->connected_event = 19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CreateEvent(NULL, TRUE, FALSE, TEXT("WpaSupplicantConnected")); 19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->connected_event == NULL) { 19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "ndisuio_notification_init: " 19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "CreateEvent failed: %d", 19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt memset(&opt, 0, sizeof(opt)); 19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt opt.dwSize = sizeof(opt); 19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt opt.dwMaxMessages = 5; 19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt opt.cbMaxMessage = NDISUIO_MSG_SIZE; 19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt opt.bReadAccess = TRUE; 19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->event_queue = CreateMsgQueue(NULL, &opt); 19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->event_queue == NULL) { 19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "ndisuio_notification_init: " 19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "CreateMsgQueue failed: %d", 19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndisuio_notification_deinit(drv); 19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt memset(&req, 0, sizeof(req)); 19978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req.hMsgQueue = drv->event_queue; 19988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req.dwNotificationTypes = 19998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef NDISUIO_NOTIFICATION_ADAPTER_ARRIVAL 20008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDISUIO_NOTIFICATION_ADAPTER_ARRIVAL | 20018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 20028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef NDISUIO_NOTIFICATION_ADAPTER_REMOVAL 20038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDISUIO_NOTIFICATION_ADAPTER_REMOVAL | 20048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDISUIO_NOTIFICATION_MEDIA_CONNECT | 20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDISUIO_NOTIFICATION_MEDIA_DISCONNECT | 20078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDISUIO_NOTIFICATION_MEDIA_SPECIFIC_NOTIFICATION; 20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!DeviceIoControl(drv->ndisuio, IOCTL_NDISUIO_REQUEST_NOTIFICATION, 20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &req, sizeof(req), NULL, 0, NULL, NULL)) { 20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "ndisuio_notification_init: " 20128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "IOCTL_NDISUIO_REQUEST_NOTIFICATION failed: %d", 20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 20148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndisuio_notification_deinit(drv); 20158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 20168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_event(drv->event_queue, sizeof(drv->event_queue), 20198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndisuio_notification_receive, drv, NULL); 20208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 20228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 20238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 20248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_get_names(struct wpa_driver_ndis_data *drv) 20278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 20288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_USE_NDISUIO 20298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDISUIO_QUERY_BINDING *b; 20308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t blen = sizeof(*b) + 1024; 20318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i, error, found = 0; 20328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD written; 20338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char name[256], desc[256], *dpos; 20348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WCHAR *pos; 20358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t j, len, dlen; 20368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b = os_malloc(blen); 20388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (b == NULL) 20398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 20408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; ; i++) { 20428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(b, 0, blen); 20438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b->BindingIndex = i; 20448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!DeviceIoControl(drv->ndisuio, IOCTL_NDISUIO_QUERY_BINDING, 20458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b, sizeof(NDISUIO_QUERY_BINDING), b, blen, 20468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &written, NULL)) { 20478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt error = (int) GetLastError(); 20488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (error == ERROR_NO_MORE_ITEMS) 20498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "IOCTL_NDISUIO_QUERY_BINDING " 20518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed: %d", error); 20528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (WCHAR *) ((char *) b + b->DeviceNameOffset); 20568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = b->DeviceNameLength; 20578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len >= sizeof(name)) 20588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(name) - 1; 20598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < len; j++) 20608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name[j] = (char) pos[j]; 20618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name[len] = '\0'; 20628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (WCHAR *) ((char *) b + b->DeviceDescrOffset); 20648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = b->DeviceDescrLength; 20658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len >= sizeof(desc)) 20668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(desc) - 1; 20678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < len; j++) 20688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc[j] = (char) pos[j]; 20698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc[len] = '\0'; 20708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: %d - %s - %s", i, name, desc); 20728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strstr(name, drv->ifname)) { 20748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Interface name match"); 20758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found = 1; 20768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(desc, drv->ifname, os_strlen(drv->ifname)) == 0) 20808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 20818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Interface description " 20828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "match"); 20838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found = 1; 20848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 20858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!found) { 20898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Could not find interface '%s'", 20908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->ifname); 20918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(b); 20928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 20938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 20948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(drv->ifname, 20968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strncmp(name, "\\DEVICE\\", 8) == 0 ? name + 8 : name, 20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(drv->ifname)); 20988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef _WIN32_WCE 20998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->adapter_name = wpa_strdup_tchar(drv->ifname); 21008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->adapter_name == NULL) { 21018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "NDIS: Failed to allocate memory for " 21028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "adapter name"); 21038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(b); 21048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 21078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dpos = os_strstr(desc, " - "); 21098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dpos) 21108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dlen = dpos - desc; 21118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dlen = os_strlen(desc); 21134b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt drv->adapter_desc = dup_binstr(desc, dlen); 21148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(b); 21158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->adapter_desc == NULL) 21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Adapter description prefix '%s'", 21198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->adapter_desc); 21208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 21228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_USE_NDISUIO */ 21238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PTSTR _names; 21248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *names, *pos, *pos2; 21258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG len; 21268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BOOLEAN res; 21278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define MAX_ADAPTERS 32 21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *name[MAX_ADAPTERS]; 21298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *desc[MAX_ADAPTERS]; 21308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int num_name, num_desc, i, found_name, found_desc; 21318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t dlen; 21328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Packet.dll version: %s", 21348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PacketGetVersion()); 21358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = 8192; 21378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _names = os_zalloc(len); 21388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (_names == NULL) 21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = PacketGetAdapterNames(_names, &len); 21428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!res && len > 8192) { 21438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(_names); 21448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _names = os_zalloc(len); 21458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (_names == NULL) 21468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = PacketGetAdapterNames(_names, &len); 21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!res) { 21518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "NDIS: Failed to get adapter list " 21528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(PacketGetAdapterNames)"); 21538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(_names); 21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt names = (char *) _names; 21588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (names[0] && names[1] == '\0' && names[2] && names[3] == '\0') { 21598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Looks like adapter names are in " 21608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "UNICODE"); 21618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Convert to ASCII */ 21628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2 = pos = names; 21638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos2 < names + len) { 21648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos2[0] == '\0' && pos2[1] == '\0' && 21658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2[2] == '\0' && pos2[3] == '\0') { 21668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2 += 4; 21678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 21688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = pos2[0]; 21708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2 += 2; 21718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos + 2, names, pos - names); 21738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 21748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 21758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = names; 21768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_name = 0; 21788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < names + len) { 21798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name[num_name] = pos; 21808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*pos && pos < names + len) 21818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 21828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 1 >= names + len) { 21838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(names); 21848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 21878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_name++; 21888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_name >= MAX_ADAPTERS) { 21898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Too many adapters"); 21908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(names); 21918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 21928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == '\0') { 21948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: %d adapter names found", 21958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_name); 21968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 21978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 21988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 21998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_desc = 0; 22028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < names + len) { 22038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc[num_desc] = pos; 22048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*pos && pos < names + len) 22058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 22068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 1 >= names + len) { 22078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(names); 22088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 22118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_desc++; 22128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_desc >= MAX_ADAPTERS) { 22138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Too many adapter " 22148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "descriptions"); 22158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(names); 22168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == '\0') { 22198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: %d adapter descriptions " 22208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "found", num_name); 22218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 22228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 22238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 22278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Windows 98 with Packet.dll 3.0 alpha3 does not include adapter 22288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * descriptions. Fill in dummy descriptors to work around this. 22298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 22308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (num_desc < num_name) 22318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc[num_desc++] = "dummy description"; 22328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_name != num_desc) { 22348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: mismatch in adapter name and " 22358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "description counts (%d != %d)", 22368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_name, num_desc); 22378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(names); 22388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found_name = found_desc = -1; 22428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_name; i++) { 22438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: %d - %s - %s", 22448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i, name[i], desc[i]); 22458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (found_name == -1 && os_strstr(name[i], drv->ifname)) 22468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found_name = i; 22478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (found_desc == -1 && 22488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strncmp(desc[i], drv->ifname, os_strlen(drv->ifname)) == 22498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) 22508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found_desc = i; 22518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (found_name < 0 && found_desc >= 0) { 22548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Matched interface '%s' based on " 22558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "description '%s'", 22568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name[found_desc], desc[found_desc]); 22578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt found_name = found_desc; 22588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(drv->ifname, 22598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strncmp(name[found_desc], "\\Device\\NPF_", 12) 22608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt == 0 ? name[found_desc] + 12 : name[found_desc], 22618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(drv->ifname)); 22628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (found_name < 0) { 22658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Could not find interface '%s'", 22668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->ifname); 22678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(names); 22688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i = found_name; 22728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strrchr(desc[i], '('); 22738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos) { 22748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dlen = pos - desc[i]; 22758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos--; 22768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos > desc[i] && *pos == ' ') 22778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dlen--; 22788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 22798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dlen = os_strlen(desc[i]); 22808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 22814b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt drv->adapter_desc = dup_binstr(desc[i], dlen); 22828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(names); 22838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->adapter_desc == NULL) 22848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 22858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Adapter description prefix '%s'", 22878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->adapter_desc); 22888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 22908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_USE_NDISUIO */ 22918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 22928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 22948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(CONFIG_NATIVE_WINDOWS) || defined(__CYGWIN__) 22958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef _WIN32_WCE 22968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 22978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * These structures are undocumented for WinXP; only WinCE version is 22988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * documented. These would be included wzcsapi.h if it were available. Some 22998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * changes here have been needed to make the structures match with WinXP SP2. 23008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * It is unclear whether these work with any other version. 23018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 23028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct { 23048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt LPWSTR wszGuid; 23058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} INTF_KEY_ENTRY, *PINTF_KEY_ENTRY; 23068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct { 23088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD dwNumIntfs; 23098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PINTF_KEY_ENTRY pIntfs; 23108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} INTFS_KEY_TABLE, *PINTFS_KEY_TABLE; 23118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct { 23138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD dwDataLen; 23148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt LPBYTE pData; 23158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} RAW_DATA, *PRAW_DATA; 23168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct { 23188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt LPWSTR wszGuid; 23198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt LPWSTR wszDescr; 23208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG ulMediaState; 23218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG ulMediaType; 23228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG ulPhysicalMediaType; 23238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt INT nInfraMode; 23248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt INT nAuthMode; 23258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt INT nWepStatus; 23268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef _WIN32_WCE 23278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 pad[2]; /* why is this needed? */ 23288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 23298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD dwCtlFlags; 23308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD dwCapabilities; /* something added for WinXP SP2(?) */ 23318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RAW_DATA rdSSID; 23328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RAW_DATA rdBSSID; 23338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RAW_DATA rdBSSIDList; 23348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RAW_DATA rdStSSIDList; 23358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RAW_DATA rdCtrlData; 23368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef UNDER_CE 23378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BOOL bInitialized; 23388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 23398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD nWPAMCastCipher; 23408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* add some extra buffer for later additions since this interface is 23418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * far from stable */ 23428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 later_additions[100]; 23438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} INTF_ENTRY, *PINTF_ENTRY; 23448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define INTF_ALL 0xffffffff 23468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define INTF_ALL_FLAGS 0x0000ffff 23478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define INTF_CTLFLAGS 0x00000010 23488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define INTFCTL_ENABLED 0x8000 23498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 23508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef _WIN32_WCE 23538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_rebind_adapter(struct wpa_driver_ndis_data *drv) 23548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 23558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HANDLE ndis; 23568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TCHAR multi[100]; 23578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len; 23588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = _tcslen(drv->adapter_name); 23608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > 80) 23618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis = CreateFile(DD_NDIS_DEVICE_NAME, GENERIC_READ | GENERIC_WRITE, 23648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0, NULL, OPEN_EXISTING, 0, NULL); 23658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis == INVALID_HANDLE_VALUE) { 23668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Failed to open file to NDIS " 23678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "device: %d", (int) GetLastError()); 23688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len++; 23728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt memcpy(multi, drv->adapter_name, len * sizeof(TCHAR)); 23738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt memcpy(&multi[len], TEXT("NDISUIO\0"), 9 * sizeof(TCHAR)); 23748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len += 9; 23758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!DeviceIoControl(ndis, IOCTL_NDIS_REBIND_ADAPTER, 23778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt multi, len * sizeof(TCHAR), NULL, 0, NULL, NULL)) 23788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 23798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: IOCTL_NDIS_REBIND_ADAPTER " 23808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed: 0x%x", (int) GetLastError()); 23818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "NDIS: rebind multi_sz", 23828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) multi, len * sizeof(TCHAR)); 23838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CloseHandle(ndis); 23848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 23858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 23868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CloseHandle(ndis); 23888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Requested NDIS rebind of NDISUIO " 23908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "protocol"); 23918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 23938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 23948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 23958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_set_wzc(struct wpa_driver_ndis_data *drv, 23988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int enable) 23998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 24008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef _WIN32_WCE 24018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HKEY hk, hk2; 24028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt LONG ret; 24038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD i, hnd, len; 24048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TCHAR keyname[256], devname[256]; 24058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define WZC_DRIVER TEXT("Drivers\\BuiltIn\\ZeroConfig") 24078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (enable) { 24098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HANDLE h; 24108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt h = ActivateDeviceEx(WZC_DRIVER, NULL, 0, NULL); 24118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (h == INVALID_HANDLE_VALUE || h == 0) { 24128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Failed to re-enable WZC " 24138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "- ActivateDeviceEx failed: %d", 24148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 24158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 24168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: WZC re-enabled"); 24198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_driver_ndis_rebind_adapter(drv); 24208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 24238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Unfortunately, just disabling the WZC for an interface is not enough 24248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to free NDISUIO for us, so need to disable and unload WZC completely 24258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * for now when using WinCE with NDISUIO. In addition, must request 24268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * NDISUIO protocol to be rebound to the adapter in order to free the 24278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * NDISUIO binding that WZC hold before us. 24288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 24298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Enumerate HKLM\Drivers\Active\* to find a handle to WZC. */ 24318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, DEVLOAD_ACTIVE_KEY, 0, 0, &hk); 24328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret != ERROR_SUCCESS) { 24338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: RegOpenKeyEx(DEVLOAD_ACTIVE_KEY) " 24348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed: %d %d", (int) ret, (int) GetLastError()); 24358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 24368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; ; i++) { 24398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(keyname); 24408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = RegEnumKeyEx(hk, i, keyname, &len, NULL, NULL, NULL, 24418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL); 24428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret != ERROR_SUCCESS) { 24438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Could not find active " 24448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WZC - assuming it is not running."); 24458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RegCloseKey(hk); 24468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 24478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = RegOpenKeyEx(hk, keyname, 0, 0, &hk2); 24508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret != ERROR_SUCCESS) { 24518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: RegOpenKeyEx(active dev) " 24528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed: %d %d", 24538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) ret, (int) GetLastError()); 24548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 24558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(devname); 24588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = RegQueryValueEx(hk2, DEVLOAD_DEVKEY_VALNAME, NULL, NULL, 24598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (LPBYTE) devname, &len); 24608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret != ERROR_SUCCESS) { 24618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: RegQueryValueEx(" 24628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "DEVKEY_VALNAME) failed: %d %d", 24638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) ret, (int) GetLastError()); 24648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RegCloseKey(hk2); 24658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 24668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (_tcscmp(devname, WZC_DRIVER) == 0) 24698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 24708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RegCloseKey(hk2); 24728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RegCloseKey(hk); 24758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Found WZC - get handle to it. */ 24778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(hnd); 24788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = RegQueryValueEx(hk2, DEVLOAD_HANDLE_VALNAME, NULL, NULL, 24798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (PUCHAR) &hnd, &len); 24808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret != ERROR_SUCCESS) { 24818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: RegQueryValueEx(HANDLE_VALNAME) " 24828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed: %d %d", (int) ret, (int) GetLastError()); 24838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RegCloseKey(hk2); 24848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 24858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt RegCloseKey(hk2); 24888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Deactivate WZC */ 24908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!DeactivateDevice((HANDLE) hnd)) { 24918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: DeactivateDevice failed: %d", 24928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) GetLastError()); 24938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 24948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 24958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 24968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Disabled WZC temporarily"); 24978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->wzc_disabled = 1; 24988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return wpa_driver_ndis_rebind_adapter(drv); 24998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* _WIN32_WCE */ 25018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HMODULE hm; 25038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD (WINAPI *wzc_enum_interf)(LPWSTR pSrvAddr, 25048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PINTFS_KEY_TABLE pIntfs); 25058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD (WINAPI *wzc_query_interf)(LPWSTR pSrvAddr, DWORD dwInFlags, 25068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PINTF_ENTRY pIntf, 25078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt LPDWORD pdwOutFlags); 25088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD (WINAPI *wzc_set_interf)(LPWSTR pSrvAddr, DWORD dwInFlags, 25098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PINTF_ENTRY pIntf, LPDWORD pdwOutFlags); 25108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = -1, j; 25118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD res; 25128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt INTFS_KEY_TABLE guids; 25138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt INTF_ENTRY intf; 25148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char guid[128]; 25158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WCHAR *pos; 25168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD flags, i; 25178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hm = LoadLibrary(TEXT("wzcsapi.dll")); 25198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hm == NULL) { 25208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Failed to load wzcsapi.dll (%u) " 25218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "- WZC probably not running", 25228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned int) GetLastError()); 25238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 25248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef _WIN32_WCE 25278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wzc_enum_interf = (void *) GetProcAddressA(hm, "WZCEnumInterfaces"); 25288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wzc_query_interf = (void *) GetProcAddressA(hm, "WZCQueryInterface"); 25298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wzc_set_interf = (void *) GetProcAddressA(hm, "WZCSetInterface"); 25308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* _WIN32_WCE */ 25318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wzc_enum_interf = (void *) GetProcAddress(hm, "WZCEnumInterfaces"); 25328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wzc_query_interf = (void *) GetProcAddress(hm, "WZCQueryInterface"); 25338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wzc_set_interf = (void *) GetProcAddress(hm, "WZCSetInterface"); 25348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 25358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wzc_enum_interf == NULL || wzc_query_interf == NULL || 25378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wzc_set_interf == NULL) { 25388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: WZCEnumInterfaces, " 25398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WZCQueryInterface, or WZCSetInterface not found " 25408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "in wzcsapi.dll"); 25418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 25428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&guids, 0, sizeof(guids)); 25458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wzc_enum_interf(NULL, &guids); 25468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res != 0) { 25478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: WZCEnumInterfaces failed: %d; " 25488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WZC service is apparently not running", 25498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) res); 25508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 25518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: WZCEnumInterfaces: %d interfaces", 25548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) guids.dwNumIntfs); 25558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < guids.dwNumIntfs; i++) { 25578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = guids.pIntfs[i].wszGuid; 25588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < sizeof(guid); j++) { 25598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt guid[j] = (char) *pos; 25608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == 0) 25618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 25628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 25638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt guid[sizeof(guid) - 1] = '\0'; 25658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: intfs %d GUID '%s'", 25668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) i, guid); 25678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strstr(drv->ifname, guid) == NULL) 25688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 25698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Current interface found from " 25718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WZC"); 25728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 25738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i >= guids.dwNumIntfs) { 25768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Current interface not found from " 25778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WZC"); 25788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 25798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&intf, 0, sizeof(intf)); 25828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt intf.wszGuid = guids.pIntfs[i].wszGuid; 25838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Set flags to verify that the structure has not changed. */ 25848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt intf.dwCtlFlags = -1; 25858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt flags = 0; 25868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wzc_query_interf(NULL, INTFCTL_ENABLED, &intf, &flags); 25878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res != 0) { 25888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Could not query flags for the " 25898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WZC interface: %d (0x%x)", 25908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) res, (int) res); 25918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: GetLastError: %u", 25928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned int) GetLastError()); 25938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 25948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 25958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: WZC interface flags 0x%x dwCtlFlags 0x%x", 25978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) flags, (int) intf.dwCtlFlags); 25988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 25998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (intf.dwCtlFlags == -1) { 26008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Looks like wzcsapi has changed " 26018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "again - could not disable WZC"); 26028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "NDIS: intf", 26038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) &intf, sizeof(intf)); 26048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 26058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (enable) { 26088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(intf.dwCtlFlags & INTFCTL_ENABLED)) { 26098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Enabling WZC for this " 26108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interface"); 26118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt intf.dwCtlFlags |= INTFCTL_ENABLED; 26128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wzc_set_interf(NULL, INTFCTL_ENABLED, &intf, 26138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &flags); 26148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res != 0) { 26158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Failed to enable " 26168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WZC: %d (0x%x)", 26178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) res, (int) res); 26188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: GetLastError: %u", 26198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned int) GetLastError()); 26208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 26218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Re-enabled WZC for this " 26238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interface"); 26248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->wzc_disabled = 0; 26258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 26278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (intf.dwCtlFlags & INTFCTL_ENABLED) { 26288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Disabling WZC for this " 26298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interface"); 26308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt intf.dwCtlFlags &= ~INTFCTL_ENABLED; 26318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = wzc_set_interf(NULL, INTFCTL_ENABLED, &intf, 26328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &flags); 26338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res != 0) { 26348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Failed to " 26358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "disable WZC: %d (0x%x)", 26368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) res, (int) res); 26378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: GetLastError: %u", 26388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned int) GetLastError()); 26398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 26408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Disabled WZC temporarily " 26428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for this interface"); 26438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->wzc_disabled = 1; 26448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 26458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: WZC was not enabled for " 26468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "this interface"); 26478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 26498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = 0; 26518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 26538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FreeLibrary(hm); 26548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 26568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 26578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_NATIVE_WINDOWS || __CYGWIN__ */ 26608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_set_wzc(struct wpa_driver_ndis_data *drv, 26628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int enable) 26638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 26658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NATIVE_WINDOWS || __CYGWIN__ */ 26688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_USE_NDISUIO 26718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 26728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * l2_packet_ndis.c is sharing the same handle to NDISUIO, so we must be able 26738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to export this handle. This is somewhat ugly, but there is no better 26748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * mechanism available to pass data from driver interface to l2_packet wrapper. 26758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 26768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic HANDLE driver_ndis_ndisuio_handle = INVALID_HANDLE_VALUE; 26778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26788d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtHANDLE driver_ndis_get_ndisuio_handle(void) 26798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return driver_ndis_ndisuio_handle; 26818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 26828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_USE_NDISUIO */ 26838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 26858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_adapter_init(struct wpa_driver_ndis_data *drv) 26868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 26878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_USE_NDISUIO 26888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef _WIN32_WCE 26898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define NDISUIO_DEVICE_NAME TEXT("\\\\.\\\\Ndisuio") 26908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD written; 26918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 26928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->ndisuio = CreateFile(NDISUIO_DEVICE_NAME, 26938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt GENERIC_READ | GENERIC_WRITE, 0, NULL, 26948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt OPEN_EXISTING, 26958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 26968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt INVALID_HANDLE_VALUE); 26978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->ndisuio == INVALID_HANDLE_VALUE) { 26988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "NDIS: Failed to open connection to " 26998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "NDISUIO: %d", (int) GetLastError()); 27008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt driver_ndis_ndisuio_handle = drv->ndisuio; 27038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef _WIN32_WCE 27058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!DeviceIoControl(drv->ndisuio, IOCTL_NDISUIO_BIND_WAIT, NULL, 0, 27068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, 0, &written, NULL)) { 27078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "NDIS: IOCTL_NDISUIO_BIND_WAIT failed: " 27088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%d", (int) GetLastError()); 27098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CloseHandle(drv->ndisuio); 27108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->ndisuio = INVALID_HANDLE_VALUE; 27118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 27148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_USE_NDISUIO */ 27178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_USE_NDISUIO */ 27198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_driver_ndis_adapter_open(struct wpa_driver_ndis_data *drv) 27238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_USE_NDISUIO 27258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD written; 27268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define MAX_NDIS_DEVICE_NAME_LEN 256 27278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WCHAR ifname[MAX_NDIS_DEVICE_NAME_LEN]; 27288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, i, pos; 27298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *prefix = "\\DEVICE\\"; 27308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef _WIN32_WCE 27328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = 0; 27338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* _WIN32_WCE */ 27348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = 8; 27358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 27368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = pos + os_strlen(drv->ifname); 27378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len >= MAX_NDIS_DEVICE_NAME_LEN) 27388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < pos; i++) 27408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ifname[i] = (WCHAR) prefix[i]; 27418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = pos; i < len; i++) 27428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ifname[i] = (WCHAR) drv->ifname[i - pos]; 27438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ifname[i] = L'\0'; 27448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!DeviceIoControl(drv->ndisuio, IOCTL_NDISUIO_OPEN_DEVICE, 27468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ifname, len * sizeof(WCHAR), NULL, 0, &written, 27478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL)) { 27488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "NDIS: IOCTL_NDISUIO_OPEN_DEVICE " 27498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed: %d", (int) GetLastError()); 27508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_ascii(MSG_DEBUG, "NDIS: ifname", 27518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (const u8 *) ifname, len * sizeof(WCHAR)); 27528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CloseHandle(drv->ndisuio); 27538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->ndisuio = INVALID_HANDLE_VALUE; 27548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Opened NDISUIO device successfully"); 27588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_USE_NDISUIO */ 27618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char ifname[128]; 27628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_snprintf(ifname, sizeof(ifname), "\\Device\\NPF_%s", drv->ifname); 27638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->adapter = PacketOpenAdapter(ifname); 27648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->adapter == NULL) { 27658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: PacketOpenAdapter failed for " 27668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "'%s'", ifname); 27678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_USE_NDISUIO */ 27718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_driver_ndis_adapter_close(struct wpa_driver_ndis_data *drv) 27758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_USE_NDISUIO 27778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt driver_ndis_ndisuio_handle = INVALID_HANDLE_VALUE; 27788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->ndisuio != INVALID_HANDLE_VALUE) 27798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CloseHandle(drv->ndisuio); 27808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_USE_NDISUIO */ 27818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->adapter) 27828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PacketCloseAdapter(drv->adapter); 27838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_USE_NDISUIO */ 27848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ndis_add_multicast(struct wpa_driver_ndis_data *drv) 27888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 27898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis_set_oid(drv, OID_802_3_MULTICAST_LIST, 27908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (const char *) pae_group_addr, ETH_ALEN) < 0) { 27918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Failed to add PAE group address " 27928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to the multicast list"); 27938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 27948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 27958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 27978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 27988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 27998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void * wpa_driver_ndis_init(void *ctx, const char *ifname) 28018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 28028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv; 28038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 mode; 28048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv = os_zalloc(sizeof(*drv)); 28068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv == NULL) 28078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 28088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->ctx = ctx; 28098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 28108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Compatibility code to strip possible prefix from the GUID. Previous 28118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * versions include \Device\NPF_ prefix for all names, but the internal 28128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * interface name is now only the GUI. Both Packet32 and NDISUIO 28138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * prefixes are supported. 28148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 28158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(ifname, "\\Device\\NPF_", 12) == 0) 28168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ifname += 12; 28178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (os_strncmp(ifname, "\\DEVICE\\", 8) == 0) 28188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ifname += 8; 28198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); 28208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_driver_ndis_adapter_init(drv) < 0) { 28228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(drv); 28238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 28248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_driver_ndis_get_names(drv) < 0) { 28278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_adapter_close(drv); 28288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(drv); 28298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 28308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_set_wzc(drv, 0); 28338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_driver_ndis_adapter_open(drv) < 0) { 28358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_adapter_close(drv); 28368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(drv); 28378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 28388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis_get_oid(drv, OID_802_3_CURRENT_ADDRESS, 28418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (char *) drv->own_addr, ETH_ALEN) < 0) { 28428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Get OID_802_3_CURRENT_ADDRESS " 28438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed"); 28448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_adapter_close(drv); 28458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(drv); 28468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 28478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_get_capability(drv); 28498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Make sure that the driver does not have any obsolete PMKID entries. 28518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 28528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_flush_pmkid(drv); 28538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 28558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Disconnect to make sure that driver re-associates if it was 28568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * connected. 28578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 28588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_disconnect(drv); 28598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(1, 0, wpa_driver_ndis_poll_timeout, drv, NULL); 28618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_NDIS_EVENTS_INTEGRATED 28638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->events = ndis_events_init(&drv->events_pipe, &drv->event_avail, 28648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->ifname, drv->adapter_desc); 28658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->events == NULL) { 28668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_deinit(drv); 28678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 28688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_event(drv->event_avail, sizeof(drv->event_avail), 28708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_event_pipe_cb, drv, NULL); 28718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NDIS_EVENTS_INTEGRATED */ 28728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef _WIN32_WCE 28748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndisuio_notification_init(drv) < 0) { 28758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_deinit(drv); 28768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 28778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 28788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 28798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Set mode here in case card was configured for ad-hoc mode 28818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * previously. */ 28828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mode = Ndis802_11Infrastructure; 28838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndis_set_oid(drv, OID_802_11_INFRASTRUCTURE_MODE, 28848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (char *) &mode, sizeof(mode)) < 0) { 28858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char buf[8]; 28868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 28878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Failed to set " 28888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "OID_802_11_INFRASTRUCTURE_MODE (%d)", 28898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) mode); 28908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Try to continue anyway */ 28918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 28928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = ndis_get_oid(drv, OID_DOT11_CURRENT_OPERATION_MODE, buf, 28938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(buf)); 28948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res > 0) { 28958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "NDIS: The driver seems to use " 28968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Native 802.11 OIDs. These are not yet " 28978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "fully supported."); 28988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->native80211 = 1; 28998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (!drv->has_capability || drv->capa.enc == 0) { 29008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 29018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Note: This will also happen with NDIS 6 drivers with 29028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Vista. 29038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 29048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Driver did not provide " 29058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "any wireless capabilities - assume it is " 29068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "a wired interface"); 29078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->wired = 1; 29088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->capa.flags |= WPA_DRIVER_FLAGS_WIRED; 29098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt drv->has_capability = 1; 29108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_add_multicast(drv); 29118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return drv; 29158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_driver_ndis_deinit(void *priv) 29198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_ndis_data *drv = priv; 29218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_NDIS_EVENTS_INTEGRATED 29238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->events) { 29248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_unregister_event(drv->event_avail, 29258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(drv->event_avail)); 29268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndis_events_deinit(drv->events); 29278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NDIS_EVENTS_INTEGRATED */ 29298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef _WIN32_WCE 29318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndisuio_notification_deinit(drv); 29328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 29338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_driver_ndis_scan_timeout, drv, drv->ctx); 29358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(wpa_driver_ndis_poll_timeout, drv, NULL); 29368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_flush_pmkid(drv); 29378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_disconnect(drv); 29388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_driver_ndis_radio_off(drv) < 0) { 29398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: failed to disassociate and turn " 29408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "radio off"); 29418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_adapter_close(drv); 29448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (drv->wzc_disabled) 29468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_driver_ndis_set_wzc(drv, 1); 29478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef _WIN32_WCE 29498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(drv->adapter_name); 29508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 29518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(drv->adapter_desc); 29528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(drv); 29538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 29548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_interface_info * 29578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtwpa_driver_ndis_get_interfaces(void *global_priv) 29588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 29598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_interface_info *iface = NULL, *niface; 29608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_USE_NDISUIO 29628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NDISUIO_QUERY_BINDING *b; 29638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t blen = sizeof(*b) + 1024; 29648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i, error; 29658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD written; 29668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char name[256], desc[256]; 29678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WCHAR *pos; 29688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t j, len; 29698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HANDLE ndisuio; 29708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ndisuio = CreateFile(NDISUIO_DEVICE_NAME, 29728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt GENERIC_READ | GENERIC_WRITE, 0, NULL, 29738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt OPEN_EXISTING, 29748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 29758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt INVALID_HANDLE_VALUE); 29768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ndisuio == INVALID_HANDLE_VALUE) { 29778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "NDIS: Failed to open connection to " 29788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "NDISUIO: %d", (int) GetLastError()); 29798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 29808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef _WIN32_WCE 29838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!DeviceIoControl(ndisuio, IOCTL_NDISUIO_BIND_WAIT, NULL, 0, 29848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, 0, &written, NULL)) { 29858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "NDIS: IOCTL_NDISUIO_BIND_WAIT failed: " 29868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%d", (int) GetLastError()); 29878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CloseHandle(ndisuio); 29888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 29898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* _WIN32_WCE */ 29918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b = os_malloc(blen); 29938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (b == NULL) { 29948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CloseHandle(ndisuio); 29958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 29968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 29978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; ; i++) { 29998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(b, 0, blen); 30008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b->BindingIndex = i; 30018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!DeviceIoControl(ndisuio, IOCTL_NDISUIO_QUERY_BINDING, 30028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt b, sizeof(NDISUIO_QUERY_BINDING), b, blen, 30038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &written, NULL)) { 30048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt error = (int) GetLastError(); 30058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (error == ERROR_NO_MORE_ITEMS) 30068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "IOCTL_NDISUIO_QUERY_BINDING " 30088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed: %d", error); 30098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (WCHAR *) ((char *) b + b->DeviceNameOffset); 30138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = b->DeviceNameLength; 30148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len >= sizeof(name)) 30158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(name) - 1; 30168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < len; j++) 30178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name[j] = (char) pos[j]; 30188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name[len] = '\0'; 30198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = (WCHAR *) ((char *) b + b->DeviceDescrOffset); 30218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = b->DeviceDescrLength; 30228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len >= sizeof(desc)) 30238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(desc) - 1; 30248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (j = 0; j < len; j++) 30258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc[j] = (char) pos[j]; 30268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc[len] = '\0'; 30278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: %d - %s - %s", i, name, desc); 30298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt niface = os_zalloc(sizeof(*niface)); 30318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (niface == NULL) 30328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt niface->drv_name = "ndis"; 30348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(name, "\\DEVICE\\", 8) == 0) 30358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt niface->ifname = os_strdup(name + 8); 30368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 30378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt niface->ifname = os_strdup(name); 30388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (niface->ifname == NULL) { 30398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(niface); 30408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt niface->desc = os_strdup(desc); 30438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt niface->next = iface; 30448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface = niface; 30458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(b); 30488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CloseHandle(ndisuio); 30498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_USE_NDISUIO */ 30508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PTSTR _names; 30518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *names, *pos, *pos2; 30528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ULONG len; 30538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BOOLEAN res; 30548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *name[MAX_ADAPTERS]; 30558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *desc[MAX_ADAPTERS]; 30568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int num_name, num_desc, i; 30578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Packet.dll version: %s", 30598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PacketGetVersion()); 30608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = 8192; 30628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _names = os_zalloc(len); 30638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (_names == NULL) 30648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 30658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = PacketGetAdapterNames(_names, &len); 30678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!res && len > 8192) { 30688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(_names); 30698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _names = os_zalloc(len); 30708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (_names == NULL) 30718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 30728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = PacketGetAdapterNames(_names, &len); 30738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!res) { 30768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "NDIS: Failed to get adapter list " 30778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(PacketGetAdapterNames)"); 30788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(_names); 30798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 30808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 30828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt names = (char *) _names; 30838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (names[0] && names[1] == '\0' && names[2] && names[3] == '\0') { 30848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Looks like adapter names are in " 30858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "UNICODE"); 30868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Convert to ASCII */ 30878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2 = pos = names; 30888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos2 < names + len) { 30898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos2[0] == '\0' && pos2[1] == '\0' && 30908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2[2] == '\0' && pos2[3] == '\0') { 30918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2 += 4; 30928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 30938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = pos2[0]; 30958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos2 += 2; 30968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 30978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos + 2, names, pos - names); 30988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 30998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 31008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = names; 31018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_name = 0; 31038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < names + len) { 31048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt name[num_name] = pos; 31058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*pos && pos < names + len) 31068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 31078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 1 >= names + len) { 31088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(names); 31098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 31108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 31128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_name++; 31138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_name >= MAX_ADAPTERS) { 31148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Too many adapters"); 31158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(names); 31168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 31178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == '\0') { 31198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: %d adapter names found", 31208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_name); 31218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 31228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_desc = 0; 31278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < names + len) { 31288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc[num_desc] = pos; 31298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*pos && pos < names + len) 31308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 31318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 1 >= names + len) { 31328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(names); 31338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 31348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 31368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_desc++; 31378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_desc >= MAX_ADAPTERS) { 31388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: Too many adapter " 31398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "descriptions"); 31408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(names); 31418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 31428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == '\0') { 31448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: %d adapter descriptions " 31458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "found", num_name); 31468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 31478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 31528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Windows 98 with Packet.dll 3.0 alpha3 does not include adapter 31538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * descriptions. Fill in dummy descriptors to work around this. 31548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 31558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (num_desc < num_name) 31568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt desc[num_desc++] = "dummy description"; 31578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (num_name != num_desc) { 31598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "NDIS: mismatch in adapter name and " 31608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "description counts (%d != %d)", 31618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_name, num_desc); 31628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(names); 31638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 31648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_name; i++) { 31678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt niface = os_zalloc(sizeof(*niface)); 31688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (niface == NULL) 31698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt niface->drv_name = "ndis"; 31718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strncmp(name[i], "\\Device\\NPF_", 12) == 0) 31728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt niface->ifname = os_strdup(name[i] + 12); 31738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 31748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt niface->ifname = os_strdup(name[i]); 31758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (niface->ifname == NULL) { 31768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(niface); 31778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 31788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt niface->desc = os_strdup(desc[i]); 31808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt niface->next = iface; 31818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt iface = niface; 31828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 31838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_USE_NDISUIO */ 31858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return iface; 31878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 31888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 31901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic const char *ndis_drv_name = "ndis"; 31911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic const char *ndis_drv_desc = "Windows NDIS driver"; 31921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 31931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstruct wpa_driver_ops wpa_driver_ndis_ops; 31941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 31951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid driver_ndis_init_ops(void) 31961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 31971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memset(&wpa_driver_ndis_ops, 0, sizeof(wpa_driver_ndis_ops)); 31981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.name = ndis_drv_name; 31991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.desc = ndis_drv_desc; 32001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.get_bssid = wpa_driver_ndis_get_bssid; 32011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.get_ssid = wpa_driver_ndis_get_ssid; 32021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.set_key = wpa_driver_ndis_set_key; 32031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.init = wpa_driver_ndis_init; 32041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.deinit = wpa_driver_ndis_deinit; 32051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.deauthenticate = wpa_driver_ndis_deauthenticate; 32061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.associate = wpa_driver_ndis_associate; 32071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.add_pmkid = wpa_driver_ndis_add_pmkid; 32081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.remove_pmkid = wpa_driver_ndis_remove_pmkid; 32091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.flush_pmkid = wpa_driver_ndis_flush_pmkid; 32101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.get_capa = wpa_driver_ndis_get_capa; 32111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.poll = wpa_driver_ndis_poll; 32121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.get_ifname = wpa_driver_ndis_get_ifname; 32131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.get_mac_addr = wpa_driver_ndis_get_mac_addr; 32141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.get_scan_results2 = 32151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_get_scan_results; 32161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.get_interfaces = wpa_driver_ndis_get_interfaces; 32171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_driver_ndis_ops.scan2 = wpa_driver_ndis_scan; 32181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 3219