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