00001
00016 #include <stdlib.h>
00017 #include <Packet32.h>
00018 #include <stdio.h>
00019 #include <string.h>
00020 #include <sys/unistd.h>
00021 #include <ntddndis.h>
00022
00023 #include "common.h"
00024 #include "driver.h"
00025 #include "wpa_supplicant.h"
00026 #include "l2_packet.h"
00027 #include "eloop.h"
00028 #include "wpa.h"
00029 #include "driver_ndis.h"
00030
00031 int wpa_driver_register_event_cb(struct wpa_driver_ndis_data *drv);
00032
00033 static void wpa_driver_ndis_poll(void *drv);
00034
00035
00036
00037
00038 #ifndef OID_802_11_BSSID
00039 #define OID_802_11_BSSID 0x0d010101
00040 #define OID_802_11_SSID 0x0d010102
00041 #define OID_802_11_INFRASTRUCTURE_MODE 0x0d010108
00042 #define OID_802_11_ADD_WEP 0x0D010113
00043 #define OID_802_11_REMOVE_WEP 0x0D010114
00044 #define OID_802_11_DISASSOCIATE 0x0D010115
00045 #define OID_802_11_BSSID_LIST 0x0d010217
00046 #define OID_802_11_AUTHENTICATION_MODE 0x0d010118
00047 #define OID_802_11_PRIVACY_FILTER 0x0d010119
00048 #define OID_802_11_BSSID_LIST_SCAN 0x0d01011A
00049 #define OID_802_11_WEP_STATUS 0x0d01011B
00050 #define OID_802_11_ENCRYPTION_STATUS OID_802_11_WEP_STATUS
00051 #define OID_802_11_ADD_KEY 0x0d01011D
00052 #define OID_802_11_REMOVE_KEY 0x0d01011E
00053 #define OID_802_11_ASSOCIATION_INFORMATION 0x0d01011F
00054 #define OID_802_11_TEST 0x0d010120
00055 #define OID_802_11_CAPABILITY 0x0d010122
00056 #define OID_802_11_PMKID 0x0d010123
00057
00058 #define NDIS_802_11_LENGTH_SSID 32
00059 #define NDIS_802_11_LENGTH_RATES 8
00060 #define NDIS_802_11_LENGTH_RATES_EX 16
00061
00062 typedef UCHAR NDIS_802_11_MAC_ADDRESS[6];
00063
00064 typedef struct NDIS_802_11_SSID {
00065 ULONG SsidLength;
00066 UCHAR Ssid[NDIS_802_11_LENGTH_SSID];
00067 } NDIS_802_11_SSID;
00068
00069 typedef LONG NDIS_802_11_RSSI;
00070
00071 typedef enum NDIS_802_11_NETWORK_TYPE {
00072 Ndis802_11FH,
00073 Ndis802_11DS,
00074 Ndis802_11OFDM5,
00075 Ndis802_11OFDM24,
00076 Ndis802_11NetworkTypeMax
00077 } NDIS_802_11_NETWORK_TYPE;
00078
00079 typedef struct NDIS_802_11_CONFIGURATION_FH {
00080 ULONG Length;
00081 ULONG HopPattern;
00082 ULONG HopSet;
00083 ULONG DwellTime;
00084 } NDIS_802_11_CONFIGURATION_FH;
00085
00086 typedef struct NDIS_802_11_CONFIGURATION {
00087 ULONG Length;
00088 ULONG BeaconPeriod;
00089 ULONG ATIMWindow;
00090 ULONG DSConfig;
00091 NDIS_802_11_CONFIGURATION_FH FHConfig;
00092 } NDIS_802_11_CONFIGURATION;
00093
00094 typedef enum NDIS_802_11_NETWORK_INFRASTRUCTURE {
00095 Ndis802_11IBSS,
00096 Ndis802_11Infrastructure,
00097 Ndis802_11AutoUnknown,
00098 Ndis802_11InfrastructureMax
00099 } NDIS_802_11_NETWORK_INFRASTRUCTURE;
00100
00101 typedef enum NDIS_802_11_AUTHENTICATION_MODE {
00102 Ndis802_11AuthModeOpen,
00103 Ndis802_11AuthModeShared,
00104 Ndis802_11AuthModeAutoSwitch,
00105 Ndis802_11AuthModeWPA,
00106 Ndis802_11AuthModeWPAPSK,
00107 Ndis802_11AuthModeWPANone,
00108 Ndis802_11AuthModeWPA2,
00109 Ndis802_11AuthModeWPA2PSK,
00110 Ndis802_11AuthModeMax
00111 } NDIS_802_11_AUTHENTICATION_MODE;
00112
00113 typedef enum NDIS_802_11_WEP_STATUS {
00114 Ndis802_11WEPEnabled,
00115 Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
00116 Ndis802_11WEPDisabled,
00117 Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled,
00118 Ndis802_11WEPKeyAbsent,
00119 Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent,
00120 Ndis802_11WEPNotSupported,
00121 Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported,
00122 Ndis802_11Encryption2Enabled,
00123 Ndis802_11Encryption2KeyAbsent,
00124 Ndis802_11Encryption3Enabled,
00125 Ndis802_11Encryption3KeyAbsent
00126 } NDIS_802_11_WEP_STATUS, NDIS_802_11_ENCRYPTION_STATUS;
00127
00128 typedef enum NDIS_802_11_PRIVACY_FILTER {
00129 Ndis802_11PrivFilterAcceptAll,
00130 Ndis802_11PrivFilter8021xWEP
00131 } NDIS_802_11_PRIVACY_FILTER;
00132
00133 typedef UCHAR NDIS_802_11_RATES[NDIS_802_11_LENGTH_RATES];
00134 typedef UCHAR NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX];
00135
00136 typedef struct NDIS_WLAN_BSSID_EX {
00137 ULONG Length;
00138 NDIS_802_11_MAC_ADDRESS MacAddress;
00139 UCHAR Reserved[2];
00140 NDIS_802_11_SSID Ssid;
00141 ULONG Privacy;
00142 NDIS_802_11_RSSI Rssi;
00143 NDIS_802_11_NETWORK_TYPE NetworkTypeInUse;
00144 NDIS_802_11_CONFIGURATION Configuration;
00145 NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;
00146 NDIS_802_11_RATES_EX SupportedRates;
00147 ULONG IELength;
00148 UCHAR IEs[1];
00149 } NDIS_WLAN_BSSID_EX;
00150
00151 typedef struct NDIS_802_11_BSSID_LIST_EX {
00152 ULONG NumberOfItems;
00153 NDIS_WLAN_BSSID_EX Bssid[1];
00154 } NDIS_802_11_BSSID_LIST_EX;
00155
00156 typedef struct NDIS_802_11_FIXED_IEs {
00157 UCHAR Timestamp[8];
00158 USHORT BeaconInterval;
00159 USHORT Capabilities;
00160 } NDIS_802_11_FIXED_IEs;
00161
00162 typedef struct NDIS_802_11_WEP {
00163 ULONG Length;
00164 ULONG KeyIndex;
00165 ULONG KeyLength;
00166 UCHAR KeyMaterial[1];
00167 } NDIS_802_11_WEP;
00168
00169 typedef ULONG NDIS_802_11_KEY_INDEX;
00170 typedef ULONGLONG NDIS_802_11_KEY_RSC;
00171
00172 typedef struct NDIS_802_11_KEY {
00173 ULONG Length;
00174 ULONG KeyIndex;
00175 ULONG KeyLength;
00176 NDIS_802_11_MAC_ADDRESS BSSID;
00177 NDIS_802_11_KEY_RSC KeyRSC;
00178 UCHAR KeyMaterial[1];
00179 } NDIS_802_11_KEY;
00180
00181 typedef struct NDIS_802_11_REMOVE_KEY {
00182 ULONG Length;
00183 ULONG KeyIndex;
00184 NDIS_802_11_MAC_ADDRESS BSSID;
00185 } NDIS_802_11_REMOVE_KEY;
00186
00187 typedef struct NDIS_802_11_AI_REQFI {
00188 USHORT Capabilities;
00189 USHORT ListenInterval;
00190 NDIS_802_11_MAC_ADDRESS CurrentAPAddress;
00191 } NDIS_802_11_AI_REQFI;
00192
00193 typedef struct NDIS_802_11_AI_RESFI {
00194 USHORT Capabilities;
00195 USHORT StatusCode;
00196 USHORT AssociationId;
00197 } NDIS_802_11_AI_RESFI;
00198
00199 typedef struct NDIS_802_11_ASSOCIATION_INFORMATION {
00200 ULONG Length;
00201 USHORT AvailableRequestFixedIEs;
00202 NDIS_802_11_AI_REQFI RequestFixedIEs;
00203 ULONG RequestIELength;
00204 ULONG OffsetRequestIEs;
00205 USHORT AvailableResponseFixedIEs;
00206 NDIS_802_11_AI_RESFI ResponseFixedIEs;
00207 ULONG ResponseIELength;
00208 ULONG OffsetResponseIEs;
00209 } NDIS_802_11_ASSOCIATION_INFORMATION;
00210
00211 typedef struct NDIS_802_11_AUTHENTICATION_ENCRYPTION {
00212 NDIS_802_11_AUTHENTICATION_MODE AuthModeSupported;
00213 NDIS_802_11_ENCRYPTION_STATUS EncryptStatusSupported;
00214 } NDIS_802_11_AUTHENTICATION_ENCRYPTION;
00215
00216 typedef struct NDIS_802_11_CAPABILITY {
00217 ULONG Length;
00218 ULONG Version;
00219 ULONG NoOfPMKIDs;
00220 ULONG NoOfAuthEncryptPairSupported;
00221 NDIS_802_11_AUTHENTICATION_ENCRYPTION
00222 AuthenticationEncryptionSupported[1];
00223 } NDIS_802_11_CAPABILITY;
00224
00225 typedef UCHAR NDIS_802_11_PMKID_VALUE[16];
00226
00227 typedef struct BSSID_INFO {
00228 NDIS_802_11_MAC_ADDRESS BSSID;
00229 NDIS_802_11_PMKID_VALUE PMKID;
00230 } BSSID_INFO;
00231
00232 typedef struct NDIS_802_11_PMKID {
00233 ULONG Length;
00234 ULONG BSSIDInfoCount;
00235 BSSID_INFO BSSIDInfo[1];
00236 } NDIS_802_11_PMKID;
00237
00238 typedef enum NDIS_802_11_STATUS_TYPE {
00239 Ndis802_11StatusType_Authentication,
00240 Ndis802_11StatusType_PMKID_CandidateList = 2,
00241 Ndis802_11StatusTypeMax
00242 } NDIS_802_11_STATUS_TYPE;
00243
00244 typedef struct NDIS_802_11_STATUS_INDICATION {
00245 NDIS_802_11_STATUS_TYPE StatusType;
00246 } NDIS_802_11_STATUS_INDICATION;
00247
00248 typedef struct PMKID_CANDIDATE {
00249 NDIS_802_11_MAC_ADDRESS BSSID;
00250 ULONG Flags;
00251 } PMKID_CANDIDATE;
00252
00253 #define NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01
00254
00255 typedef struct NDIS_802_11_PMKID_CANDIDATE_LIST {
00256 ULONG Version;
00257 ULONG NumCandidates;
00258 PMKID_CANDIDATE CandidateList[1];
00259 } NDIS_802_11_PMKID_CANDIDATE_LIST;
00260
00261 typedef struct NDIS_802_11_AUTHENTICATION_REQUEST {
00262 ULONG Length;
00263 NDIS_802_11_MAC_ADDRESS Bssid;
00264 ULONG Flags;
00265 } NDIS_802_11_AUTHENTICATION_REQUEST;
00266
00267 #define NDIS_802_11_AUTH_REQUEST_REAUTH 0x01
00268 #define NDIS_802_11_AUTH_REQUEST_KEYUPDATE 0x02
00269 #define NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR 0x06
00270 #define NDIS_802_11_AUTH_REQUEST_GROUP_ERROR 0x0E
00271
00272 #endif
00273
00274
00275 static int ndis_get_oid(struct wpa_driver_ndis_data *drv, unsigned int oid,
00276 char *data, int len)
00277 {
00278 char *buf;
00279 PACKET_OID_DATA *o;
00280 int ret;
00281
00282 buf = malloc(sizeof(*o) + len);
00283 if (buf == NULL)
00284 return -1;
00285 memset(buf, 0, sizeof(*o) + len);
00286 o = (PACKET_OID_DATA *) buf;
00287 o->Oid = oid;
00288 o->Length = len;
00289
00290 if (!PacketRequest(drv->adapter, FALSE, o)) {
00291 wpa_printf(MSG_DEBUG, "%s: oid=0x%x len (%d) failed",
00292 __func__, oid, len);
00293 free(buf);
00294 return -1;
00295 }
00296 if (o->Length > len) {
00297 wpa_printf(MSG_DEBUG, "%s: oid=0x%x Length (%d) > len (%d)",
00298 __func__, oid, (unsigned int) o->Length, len);
00299 free(buf);
00300 return -1;
00301 }
00302 memcpy(data, o->Data, o->Length);
00303 ret = o->Length;
00304 free(buf);
00305 return ret;
00306 }
00307
00308
00309 static int ndis_set_oid(struct wpa_driver_ndis_data *drv, unsigned int oid,
00310 char *data, int len)
00311 {
00312 char *buf;
00313 PACKET_OID_DATA *o;
00314
00315 buf = malloc(sizeof(*o) + len);
00316 if (buf == NULL)
00317 return -1;
00318 memset(buf, 0, sizeof(*o) + len);
00319 o = (PACKET_OID_DATA *) buf;
00320 o->Oid = oid;
00321 o->Length = len;
00322 if (data)
00323 memcpy(o->Data, data, len);
00324
00325 if (!PacketRequest(drv->adapter, TRUE, o)) {
00326 wpa_printf(MSG_DEBUG, "%s: oid=0x%x len (%d) failed",
00327 __func__, oid, len);
00328 free(buf);
00329 return -1;
00330 }
00331 free(buf);
00332 return 0;
00333 }
00334
00335
00336 static int ndis_set_auth_mode(struct wpa_driver_ndis_data *drv, int mode)
00337 {
00338 u32 auth_mode = mode;
00339 if (ndis_set_oid(drv, OID_802_11_AUTHENTICATION_MODE,
00340 (char *) &auth_mode, sizeof(auth_mode)) < 0) {
00341 wpa_printf(MSG_DEBUG, "NDIS: Failed to set "
00342 "OID_802_11_AUTHENTICATION_MODE (%d)",
00343 (int) auth_mode);
00344 return -1;
00345 }
00346 return 0;
00347 }
00348
00349
00350 static int ndis_get_auth_mode(struct wpa_driver_ndis_data *drv)
00351 {
00352 u32 auth_mode;
00353 int res;
00354 res = ndis_get_oid(drv, OID_802_11_AUTHENTICATION_MODE,
00355 (char *) &auth_mode, sizeof(auth_mode));
00356 if (res != sizeof(auth_mode)) {
00357 wpa_printf(MSG_DEBUG, "NDIS: Failed to get "
00358 "OID_802_11_AUTHENTICATION_MODE");
00359 return -1;
00360 }
00361 return auth_mode;
00362 }
00363
00364
00365 static int ndis_set_encr_status(struct wpa_driver_ndis_data *drv, int encr)
00366 {
00367 u32 encr_status = encr;
00368 if (ndis_set_oid(drv, OID_802_11_ENCRYPTION_STATUS,
00369 (char *) &encr_status, sizeof(encr_status)) < 0) {
00370 wpa_printf(MSG_DEBUG, "NDIS: Failed to set "
00371 "OID_802_11_ENCRYPTION_STATUS (%d)", encr);
00372 return -1;
00373 }
00374 return 0;
00375 }
00376
00377
00378 static int ndis_get_encr_status(struct wpa_driver_ndis_data *drv)
00379 {
00380 u32 encr;
00381 int res;
00382 res = ndis_get_oid(drv, OID_802_11_ENCRYPTION_STATUS,
00383 (char *) &encr, sizeof(encr));
00384 if (res != sizeof(encr)) {
00385 wpa_printf(MSG_DEBUG, "NDIS: Failed to get "
00386 "OID_802_11_ENCRYPTION_STATUS");
00387 return -1;
00388 }
00389 return encr;
00390 }
00391
00392
00393 static int wpa_driver_ndis_get_bssid(void *priv, u8 *bssid)
00394 {
00395 struct wpa_driver_ndis_data *drv = priv;
00396
00397 if (drv->wired) {
00398
00399
00400
00401
00402 bssid[0] = 0x01;
00403 bssid[1] = 0x80;
00404 bssid[2] = 0xc2;
00405 bssid[3] = 0x00;
00406 bssid[4] = 0x00;
00407 bssid[5] = 0x03;
00408 return 0;
00409 }
00410
00411 return ndis_get_oid(drv, OID_802_11_BSSID, bssid, ETH_ALEN) < 0 ?
00412 -1 : 0;
00413 }
00414
00415
00416
00417 static int wpa_driver_ndis_get_ssid(void *priv, u8 *ssid)
00418 {
00419 struct wpa_driver_ndis_data *drv = priv;
00420 NDIS_802_11_SSID buf;
00421 int res;
00422
00423 res = ndis_get_oid(drv, OID_802_11_SSID, (char *) &buf, sizeof(buf));
00424 if (res < 4) {
00425 wpa_printf(MSG_DEBUG, "NDIS: Failed to get SSID");
00426 if (drv->wired) {
00427 wpa_printf(MSG_DEBUG, "NDIS: Allow get_ssid failure "
00428 "with a wired interface");
00429 return 0;
00430 }
00431 return -1;
00432 }
00433 memcpy(ssid, buf.Ssid, buf.SsidLength);
00434 return buf.SsidLength;
00435 }
00436
00437
00438 static int wpa_driver_ndis_set_ssid(struct wpa_driver_ndis_data *drv,
00439 const u8 *ssid, size_t ssid_len)
00440 {
00441 NDIS_802_11_SSID buf;
00442
00443 memset(&buf, 0, sizeof(buf));
00444 buf.SsidLength = ssid_len;
00445 memcpy(buf.Ssid, ssid, ssid_len);
00446
00447
00448
00449
00450
00451 drv->radio_enabled = 1;
00452 return ndis_set_oid(drv, OID_802_11_SSID, (char *) &buf, sizeof(buf));
00453 }
00454
00455
00456
00457
00458 static int wpa_driver_ndis_radio_off(struct wpa_driver_ndis_data *drv)
00459 {
00460 drv->radio_enabled = 0;
00461 return ndis_set_oid(drv, OID_802_11_DISASSOCIATE, " ", 4);
00462 }
00463
00464
00465
00466 static int wpa_driver_ndis_disconnect(struct wpa_driver_ndis_data *drv)
00467 {
00468 char ssid[32];
00469 int i;
00470 for (i = 0; i < 32; i++)
00471 ssid[i] = rand() & 0xff;
00472 return wpa_driver_ndis_set_ssid(drv, ssid, 32);
00473 }
00474
00475
00476 static int wpa_driver_ndis_deauthenticate(void *priv, const u8 *addr,
00477 int reason_code)
00478 {
00479 struct wpa_driver_ndis_data *drv = priv;
00480 return wpa_driver_ndis_disconnect(drv);
00481 }
00482
00483
00484 static int wpa_driver_ndis_disassociate(void *priv, const u8 *addr,
00485 int reason_code)
00486 {
00487 struct wpa_driver_ndis_data *drv = priv;
00488 return wpa_driver_ndis_disconnect(drv);
00489 }
00490
00491
00492 static int wpa_driver_ndis_set_wpa(void *priv, int enabled)
00493 {
00494 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
00495 return 0;
00496 }
00497
00498
00499 static void wpa_driver_ndis_scan_timeout(void *eloop_ctx, void *timeout_ctx)
00500 {
00501 wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
00502 wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
00503 }
00504
00505
00506 static int wpa_driver_ndis_scan(void *priv, const u8 *ssid, size_t ssid_len)
00507 {
00508 struct wpa_driver_ndis_data *drv = priv;
00509 int res;
00510
00511 if (!drv->radio_enabled) {
00512 wpa_printf(MSG_DEBUG, "NDIS: turning radio on before the first"
00513 " scan");
00514 if (wpa_driver_ndis_disconnect(drv) < 0) {
00515 wpa_printf(MSG_DEBUG, "NDIS: failed to enable radio");
00516 }
00517 drv->radio_enabled = 1;
00518 }
00519
00520 res = ndis_set_oid(drv, OID_802_11_BSSID_LIST_SCAN, " ", 4);
00521 eloop_register_timeout(3, 0, wpa_driver_ndis_scan_timeout, drv,
00522 drv->ctx);
00523 return res;
00524 }
00525
00526
00527 static void wpa_driver_ndis_get_ies(struct wpa_scan_result *res, u8 *ie,
00528 size_t ie_len)
00529 {
00530 u8 *pos = ie;
00531 u8 *end = ie + ie_len;
00532
00533 if (ie_len < sizeof(NDIS_802_11_FIXED_IEs))
00534 return;
00535
00536 pos += sizeof(NDIS_802_11_FIXED_IEs);
00537
00538 while (pos + 1 < end && pos + 2 + pos[1] <= end) {
00539 u8 ielen = 2 + pos[1];
00540 if (ielen > SSID_MAX_WPA_IE_LEN) {
00541 pos += ielen;
00542 continue;
00543 }
00544 if (pos[0] == GENERIC_INFO_ELEM && pos[1] >= 4 &&
00545 memcmp(pos + 2, "\x00\x50\xf2\x01", 4) == 0) {
00546 memcpy(res->wpa_ie, pos, ielen);
00547 res->wpa_ie_len = ielen;
00548 } else if (pos[0] == RSN_INFO_ELEM) {
00549 memcpy(res->rsn_ie, pos, ielen);
00550 res->rsn_ie_len = ielen;
00551 }
00552 pos += ielen;
00553 }
00554 }
00555
00556
00557 static int wpa_driver_ndis_get_scan_results(void *priv,
00558 struct wpa_scan_result *results,
00559 size_t max_size)
00560 {
00561 struct wpa_driver_ndis_data *drv = priv;
00562 NDIS_802_11_BSSID_LIST_EX *b;
00563 size_t blen;
00564 int len, count, i, j;
00565 char *pos;
00566
00567 blen = 65535;
00568 b = malloc(blen);
00569 if (b == NULL)
00570 return -1;
00571 memset(b, 0, blen);
00572 len = ndis_get_oid(drv, OID_802_11_BSSID_LIST, (char *) b, blen);
00573 if (len < 0) {
00574 wpa_printf(MSG_DEBUG, "NDIS: failed to get scan results");
00575 free(b);
00576 return -1;
00577 }
00578 count = b->NumberOfItems;
00579
00580 if (count > max_size)
00581 count = max_size;
00582
00583 memset(results, 0, max_size * sizeof(struct wpa_scan_result));
00584 pos = (char *) &b->Bssid[0];
00585 for (i = 0; i < count; i++) {
00586 NDIS_WLAN_BSSID_EX *bss = (NDIS_WLAN_BSSID_EX *) pos;
00587 memcpy(results[i].bssid, bss->MacAddress, ETH_ALEN);
00588 memcpy(results[i].ssid, bss->Ssid.Ssid, bss->Ssid.SsidLength);
00589 results[i].ssid_len = bss->Ssid.SsidLength;
00590 if (bss->Privacy)
00591 results[i].caps |= IEEE80211_CAP_PRIVACY;
00592 results[i].level = (int) bss->Rssi;
00593 results[i].freq = bss->Configuration.DSConfig / 1000;
00594 for (j = 0; j < sizeof(bss->SupportedRates); j++) {
00595 if ((bss->SupportedRates[j] & 0x7f) >
00596 results[i].maxrate) {
00597 results[i].maxrate =
00598 bss->SupportedRates[j] & 0x7f;
00599 }
00600 }
00601 wpa_driver_ndis_get_ies(&results[i], bss->IEs, bss->IELength);
00602 pos += bss->Length;
00603 if (pos > (char *) b + blen)
00604 break;
00605 }
00606
00607 free(b);
00608 return count;
00609 }
00610
00611
00612 static int wpa_driver_ndis_remove_key(struct wpa_driver_ndis_data *drv,
00613 int key_idx, const u8 *addr,
00614 const u8 *bssid, int pairwise)
00615 {
00616 NDIS_802_11_REMOVE_KEY rkey;
00617 NDIS_802_11_KEY_INDEX index;
00618 int res, res2;
00619
00620 memset(&rkey, 0, sizeof(rkey));
00621
00622 rkey.Length = sizeof(rkey);
00623 rkey.KeyIndex = key_idx;
00624 if (pairwise)
00625 rkey.KeyIndex |= 1 << 30;
00626 memcpy(rkey.BSSID, bssid, ETH_ALEN);
00627
00628 res = ndis_set_oid(drv, OID_802_11_REMOVE_KEY, (char *) &rkey,
00629 sizeof(rkey));
00630 if (!pairwise) {
00631 res2 = ndis_set_oid(drv, OID_802_11_REMOVE_WEP,
00632 (char *) &index, sizeof(index));
00633 } else
00634 res2 = 0;
00635
00636 if (res < 0 && res2 < 0)
00637 return res;
00638 return 0;
00639 }
00640
00641
00642 static int wpa_driver_ndis_add_wep(struct wpa_driver_ndis_data *drv,
00643 int pairwise, int key_idx, int set_tx,
00644 const u8 *key, size_t key_len)
00645 {
00646 NDIS_802_11_WEP *wep;
00647 size_t len;
00648 int res;
00649
00650 len = 12 + key_len;
00651 wep = malloc(len);
00652 if (wep == NULL)
00653 return -1;
00654 memset(wep, 0, len);
00655 wep->Length = len;
00656 wep->KeyIndex = key_idx;
00657 if (set_tx)
00658 wep->KeyIndex |= 1 << 31;
00659 #if 0
00660 if (pairwise)
00661 wep->KeyIndex |= 1 << 30;
00662 #endif
00663 wep->KeyLength = key_len;
00664 memcpy(wep->KeyMaterial, key, key_len);
00665
00666 wpa_hexdump_key(MSG_MSGDUMP, "NDIS: OIS_802_11_ADD_WEP",
00667 (char *) wep, len);
00668 res = ndis_set_oid(drv, OID_802_11_ADD_WEP, (char *) wep, len);
00669
00670 free(wep);
00671
00672 return res;
00673 }
00674
00675 static int wpa_driver_ndis_set_key(void *priv, wpa_alg alg, const u8 *addr,
00676 int key_idx, int set_tx,
00677 const u8 *seq, size_t seq_len,
00678 const u8 *key, size_t key_len)
00679 {
00680 struct wpa_driver_ndis_data *drv = priv;
00681 size_t len;
00682 NDIS_802_11_KEY *nkey;
00683 int i, res, pairwise;
00684 u8 bssid[ETH_ALEN];
00685
00686 if (addr == NULL || memcmp(addr, "\xff\xff\xff\xff\xff\xff",
00687 ETH_ALEN) == 0) {
00688
00689 pairwise = 0;
00690 wpa_driver_ndis_get_bssid(drv, bssid);
00691 } else {
00692
00693 pairwise = 1;
00694 memcpy(bssid, addr, ETH_ALEN);
00695 }
00696
00697 if (alg == WPA_ALG_NONE || key_len == 0) {
00698 return wpa_driver_ndis_remove_key(drv, key_idx, addr, bssid,
00699 pairwise);
00700 }
00701
00702 if (alg == WPA_ALG_WEP) {
00703 return wpa_driver_ndis_add_wep(drv, pairwise, key_idx, set_tx,
00704 key, key_len);
00705 }
00706
00707 len = 12 + 6 + 6 + 8 + key_len;
00708
00709 nkey = malloc(len);
00710 if (nkey == NULL)
00711 return -1;
00712 memset(nkey, 0, len);
00713
00714 nkey->Length = len;
00715 nkey->KeyIndex = key_idx;
00716 if (set_tx)
00717 nkey->KeyIndex |= 1 << 31;
00718 if (pairwise)
00719 nkey->KeyIndex |= 1 << 30;
00720 if (seq && seq_len)
00721 nkey->KeyIndex |= 1 << 29;
00722 nkey->KeyLength = key_len;
00723 memcpy(nkey->BSSID, bssid, ETH_ALEN);
00724 if (seq && seq_len) {
00725 for (i = 0; i < seq_len; i++)
00726 nkey->KeyRSC |= seq[i] << (i * 8);
00727 }
00728 if (alg == WPA_ALG_TKIP && key_len == 32) {
00729 memcpy(nkey->KeyMaterial, key, 16);
00730 memcpy(nkey->KeyMaterial + 16, key + 24, 8);
00731 memcpy(nkey->KeyMaterial + 24, key + 16, 8);
00732 } else {
00733 memcpy(nkey->KeyMaterial, key, key_len);
00734 }
00735
00736 wpa_hexdump_key(MSG_MSGDUMP, "NDIS: OIS_802_11_ADD_KEY",
00737 (char *) nkey, len);
00738 res = ndis_set_oid(drv, OID_802_11_ADD_KEY, (char *) nkey, len);
00739 free(nkey);
00740
00741 return res;
00742 }
00743
00744
00745 static int
00746 wpa_driver_ndis_associate(void *priv,
00747 struct wpa_driver_associate_params *params)
00748 {
00749 struct wpa_driver_ndis_data *drv = priv;
00750 u32 auth_mode, encr, priv_mode, mode;
00751
00752
00753
00754 if (params->mode == IEEE80211_MODE_IBSS)
00755 mode = Ndis802_11IBSS;
00756 else
00757 mode = Ndis802_11Infrastructure;
00758 if (ndis_set_oid(drv, OID_802_11_INFRASTRUCTURE_MODE,
00759 (char *) &mode, sizeof(mode)) < 0) {
00760 wpa_printf(MSG_DEBUG, "NDIS: Failed to set "
00761 "OID_802_11_INFRASTRUCTURE_MODE (%d)",
00762 (int) mode);
00763
00764 }
00765
00766 if (params->wpa_ie == NULL || params->wpa_ie_len == 0) {
00767 if (params->auth_alg & AUTH_ALG_SHARED_KEY) {
00768 if (params->auth_alg & AUTH_ALG_OPEN_SYSTEM)
00769 auth_mode = Ndis802_11AuthModeAutoSwitch;
00770 else
00771 auth_mode = Ndis802_11AuthModeShared;
00772 } else
00773 auth_mode = Ndis802_11AuthModeOpen;
00774 priv_mode = Ndis802_11PrivFilterAcceptAll;
00775 } else if (params->wpa_ie[0] == RSN_INFO_ELEM) {
00776 priv_mode = Ndis802_11PrivFilter8021xWEP;
00777 if (params->key_mgmt_suite == KEY_MGMT_PSK)
00778 auth_mode = Ndis802_11AuthModeWPA2PSK;
00779 else
00780 auth_mode = Ndis802_11AuthModeWPA2;
00781 } else {
00782 priv_mode = Ndis802_11PrivFilter8021xWEP;
00783 if (params->key_mgmt_suite == KEY_MGMT_WPA_NONE)
00784 auth_mode = Ndis802_11AuthModeWPANone;
00785 else if (params->key_mgmt_suite == KEY_MGMT_PSK)
00786 auth_mode = Ndis802_11AuthModeWPAPSK;
00787 else
00788 auth_mode = Ndis802_11AuthModeWPA;
00789 }
00790
00791 switch (params->pairwise_suite) {
00792 case CIPHER_CCMP:
00793 encr = Ndis802_11Encryption3Enabled;
00794 break;
00795 case CIPHER_TKIP:
00796 encr = Ndis802_11Encryption2Enabled;
00797 break;
00798 case CIPHER_WEP40:
00799 case CIPHER_WEP104:
00800 encr = Ndis802_11Encryption1Enabled;
00801 break;
00802 case CIPHER_NONE:
00803 if (params->group_suite == CIPHER_CCMP)
00804 encr = Ndis802_11Encryption3Enabled;
00805 else if (params->group_suite == CIPHER_TKIP)
00806 encr = Ndis802_11Encryption2Enabled;
00807 else
00808 encr = Ndis802_11EncryptionDisabled;
00809 break;
00810 default:
00811 encr = Ndis802_11EncryptionDisabled;
00812 };
00813
00814 if (ndis_set_oid(drv, OID_802_11_PRIVACY_FILTER,
00815 (char *) &priv_mode, sizeof(priv_mode)) < 0) {
00816 wpa_printf(MSG_DEBUG, "NDIS: Failed to set "
00817 "OID_802_11_PRIVACY_FILTER (%d)",
00818 (int) priv_mode);
00819
00820 }
00821
00822 ndis_set_auth_mode(drv, auth_mode);
00823 ndis_set_encr_status(drv, encr);
00824
00825 return wpa_driver_ndis_set_ssid(drv, params->ssid, params->ssid_len);
00826 }
00827
00828
00829 static int wpa_driver_ndis_set_pmkid(struct wpa_driver_ndis_data *drv)
00830 {
00831 int len, count, i, ret;
00832 struct ndis_pmkid_entry *entry;
00833 NDIS_802_11_PMKID *p;
00834
00835 count = 0;
00836 entry = drv->pmkid;
00837 while (entry) {
00838 count++;
00839 if (count >= drv->no_of_pmkid)
00840 break;
00841 entry = entry->next;
00842 }
00843 len = 8 + count * sizeof(BSSID_INFO);
00844 p = malloc(len);
00845 if (p == NULL)
00846 return -1;
00847 memset(p, 0, len);
00848 p->Length = len;
00849 p->BSSIDInfoCount = count;
00850 entry = drv->pmkid;
00851 for (i = 0; i < count; i++) {
00852 memcpy(&p->BSSIDInfo[i].BSSID, entry->bssid, ETH_ALEN);
00853 memcpy(&p->BSSIDInfo[i].PMKID, entry->pmkid, 16);
00854 entry = entry->next;
00855 }
00856 wpa_hexdump(MSG_MSGDUMP, "NDIS: OID_802_11_PMKID", (char *) p, len);
00857 ret = ndis_set_oid(drv, OID_802_11_PMKID, (char *) p, len);
00858 free(p);
00859 return ret;
00860 }
00861
00862
00863 static int wpa_driver_ndis_add_pmkid(void *priv, const u8 *bssid,
00864 const u8 *pmkid)
00865 {
00866 struct wpa_driver_ndis_data *drv = priv;
00867 struct ndis_pmkid_entry *entry, *prev;
00868
00869 if (drv->no_of_pmkid == 0)
00870 return 0;
00871
00872 prev = NULL;
00873 entry = drv->pmkid;
00874 while (entry) {
00875 if (memcmp(entry->bssid, bssid, ETH_ALEN) == 0)
00876 break;
00877 prev = entry;
00878 entry = entry->next;
00879 }
00880
00881 if (entry) {
00882
00883
00884 memcpy(entry->pmkid, pmkid, 16);
00885 if (prev) {
00886 prev->next = entry->next;
00887 entry->next = drv->pmkid;
00888 drv->pmkid = entry;
00889 }
00890 } else {
00891 entry = malloc(sizeof(*entry));
00892 if (entry) {
00893 memcpy(entry->bssid, bssid, ETH_ALEN);
00894 memcpy(entry->pmkid, pmkid, 16);
00895 entry->next = drv->pmkid;
00896 drv->pmkid = entry;
00897 }
00898 }
00899
00900 return wpa_driver_ndis_set_pmkid(drv);
00901 }
00902
00903
00904 static int wpa_driver_ndis_remove_pmkid(void *priv, const u8 *bssid,
00905 const u8 *pmkid)
00906 {
00907 struct wpa_driver_ndis_data *drv = priv;
00908 struct ndis_pmkid_entry *entry, *prev;
00909
00910 if (drv->no_of_pmkid == 0)
00911 return 0;
00912
00913 entry = drv->pmkid;
00914 prev = NULL;
00915 drv->pmkid = NULL;
00916 while (entry) {
00917 if (memcmp(entry->bssid, bssid, ETH_ALEN) == 0 &&
00918 memcmp(entry->pmkid, pmkid, 16) == 0) {
00919 if (prev)
00920 prev->next = entry->next;
00921 else
00922 drv->pmkid = entry->next;
00923 free(entry);
00924 break;
00925 }
00926 prev = entry;
00927 entry = entry->next;
00928 }
00929 return wpa_driver_ndis_set_pmkid(drv);
00930 }
00931
00932
00933 static int wpa_driver_ndis_flush_pmkid(void *priv)
00934 {
00935 struct wpa_driver_ndis_data *drv = priv;
00936 NDIS_802_11_PMKID p;
00937 struct ndis_pmkid_entry *pmkid, *prev;
00938
00939 if (drv->no_of_pmkid == 0)
00940 return 0;
00941
00942 pmkid = drv->pmkid;
00943 drv->pmkid = NULL;
00944 while (pmkid) {
00945 prev = pmkid;
00946 pmkid = pmkid->next;
00947 free(prev);
00948 }
00949
00950 memset(&p, 0, sizeof(p));
00951 p.Length = 8;
00952 p.BSSIDInfoCount = 0;
00953 wpa_hexdump(MSG_MSGDUMP, "NDIS: OID_802_11_PMKID (flush)",
00954 (char *) &p, 8);
00955 return ndis_set_oid(drv, OID_802_11_PMKID, (char *) &p, 8);
00956 }
00957
00958
00959 static int wpa_driver_ndis_get_associnfo(struct wpa_driver_ndis_data *drv)
00960 {
00961 char buf[512], *pos;
00962 NDIS_802_11_ASSOCIATION_INFORMATION *ai;
00963 int len, i;
00964 union wpa_event_data data;
00965 NDIS_802_11_BSSID_LIST_EX *b;
00966 size_t blen;
00967
00968 len = ndis_get_oid(drv, OID_802_11_ASSOCIATION_INFORMATION, buf,
00969 sizeof(buf));
00970 if (len < 0) {
00971 wpa_printf(MSG_DEBUG, "NDIS: failed to get association "
00972 "information");
00973 return -1;
00974 }
00975 if (len > sizeof(buf)) {
00976
00977
00978
00979
00980 wpa_printf(MSG_DEBUG, "NDIS: ignored bogus association "
00981 "information length %d", len);
00982 len = ndis_get_oid(drv, OID_802_11_ASSOCIATION_INFORMATION,
00983 buf, sizeof(buf));
00984 if (len < -1) {
00985 wpa_printf(MSG_DEBUG, "NDIS: re-reading association "
00986 "information failed");
00987 return -1;
00988 }
00989 if (len > sizeof(buf)) {
00990 wpa_printf(MSG_DEBUG, "NDIS: ignored bogus association"
00991 " information length %d (re-read)", len);
00992 len = sizeof(buf);
00993 }
00994 }
00995 wpa_hexdump(MSG_MSGDUMP, "NDIS: association information", buf, len);
00996 if (len < sizeof(*ai)) {
00997 wpa_printf(MSG_DEBUG, "NDIS: too short association "
00998 "information");
00999 return -1;
01000 }
01001 ai = (NDIS_802_11_ASSOCIATION_INFORMATION *) buf;
01002 wpa_printf(MSG_DEBUG, "NDIS: ReqFixed=0x%x RespFixed=0x%x off_req=%d "
01003 "off_resp=%d len_req=%d len_resp=%d",
01004 ai->AvailableRequestFixedIEs, ai->AvailableResponseFixedIEs,
01005 (int) ai->OffsetRequestIEs, (int) ai->OffsetResponseIEs,
01006 (int) ai->RequestIELength, (int) ai->ResponseIELength);
01007
01008 if (ai->OffsetRequestIEs + ai->RequestIELength > len ||
01009 ai->OffsetResponseIEs + ai->ResponseIELength > len) {
01010 wpa_printf(MSG_DEBUG, "NDIS: association information - "
01011 "IE overflow");
01012 return -1;
01013 }
01014
01015 wpa_hexdump(MSG_MSGDUMP, "NDIS: Request IEs",
01016 buf + ai->OffsetRequestIEs, ai->RequestIELength);
01017 wpa_hexdump(MSG_MSGDUMP, "NDIS: Response IEs",
01018 buf + ai->OffsetResponseIEs, ai->ResponseIELength);
01019
01020 memset(&data, 0, sizeof(data));
01021 data.assoc_info.req_ies = buf + ai->OffsetRequestIEs;
01022 data.assoc_info.req_ies_len = ai->RequestIELength;
01023 data.assoc_info.resp_ies = buf + ai->OffsetResponseIEs;
01024 data.assoc_info.resp_ies_len = ai->ResponseIELength;
01025
01026 blen = 65535;
01027 b = malloc(blen);
01028 if (b == NULL)
01029 goto skip_scan_results;
01030 memset(b, 0, blen);
01031 len = ndis_get_oid(drv, OID_802_11_BSSID_LIST, (char *) b, blen);
01032 if (len < 0) {
01033 wpa_printf(MSG_DEBUG, "NDIS: failed to get scan results");
01034 free(b);
01035 b = NULL;
01036 goto skip_scan_results;
01037 }
01038 wpa_printf(MSG_DEBUG, "NDIS: %d BSSID items to process for AssocInfo",
01039 (unsigned int) b->NumberOfItems);
01040
01041 pos = (char *) &b->Bssid[0];
01042 for (i = 0; i < b->NumberOfItems; i++) {
01043 NDIS_WLAN_BSSID_EX *bss = (NDIS_WLAN_BSSID_EX *) pos;
01044 if (memcmp(drv->bssid, bss->MacAddress, ETH_ALEN) == 0 &&
01045 bss->IELength > sizeof(NDIS_802_11_FIXED_IEs)) {
01046 data.assoc_info.beacon_ies =
01047 ((u8 *) bss->IEs) +
01048 sizeof(NDIS_802_11_FIXED_IEs);
01049 data.assoc_info.beacon_ies_len =
01050 bss->IELength - sizeof(NDIS_802_11_FIXED_IEs);
01051 wpa_hexdump(MSG_MSGDUMP, "NDIS: Beacon IEs",
01052 data.assoc_info.beacon_ies,
01053 data.assoc_info.beacon_ies_len);
01054 break;
01055 }
01056 pos += bss->Length;
01057 if (pos > (char *) b + blen)
01058 break;
01059 }
01060
01061 skip_scan_results:
01062 wpa_supplicant_event(drv->ctx, EVENT_ASSOCINFO, &data);
01063
01064 free(b);
01065
01066 return 0;
01067 }
01068
01069
01070 static void wpa_driver_ndis_poll_timeout(void *eloop_ctx, void *timeout_ctx)
01071 {
01072 struct wpa_driver_ndis_data *drv = eloop_ctx;
01073 u8 bssid[ETH_ALEN];
01074
01075 if (drv->wired)
01076 return;
01077
01078 if (wpa_driver_ndis_get_bssid(drv, bssid)) {
01079
01080 if (memcmp(drv->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN)
01081 != 0) {
01082 memset(drv->bssid, 0, ETH_ALEN);
01083 wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
01084 }
01085 } else {
01086
01087 if (memcmp(drv->bssid, bssid, ETH_ALEN) != 0) {
01088 memcpy(drv->bssid, bssid, ETH_ALEN);
01089 wpa_driver_ndis_get_associnfo(drv);
01090 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
01091 }
01092 }
01093 eloop_register_timeout(1, 0, wpa_driver_ndis_poll_timeout, drv, NULL);
01094 }
01095
01096
01097 static void wpa_driver_ndis_poll(void *priv)
01098 {
01099 struct wpa_driver_ndis_data *drv = priv;
01100 eloop_cancel_timeout(wpa_driver_ndis_poll_timeout, drv, NULL);
01101 wpa_driver_ndis_poll_timeout(drv, NULL);
01102 }
01103
01104
01105
01106
01107 void wpa_driver_ndis_event_connect(struct wpa_driver_ndis_data *drv)
01108 {
01109 wpa_printf(MSG_DEBUG, "NDIS: Media Connect Event");
01110 if (wpa_driver_ndis_get_bssid(drv, drv->bssid) == 0) {
01111 wpa_driver_ndis_get_associnfo(drv);
01112 wpa_supplicant_event(drv->ctx, EVENT_ASSOC, NULL);
01113 }
01114 }
01115
01116
01117
01118
01119 void wpa_driver_ndis_event_disconnect(struct wpa_driver_ndis_data *drv)
01120 {
01121 wpa_printf(MSG_DEBUG, "NDIS: Media Disconnect Event");
01122 memset(drv->bssid, 0, ETH_ALEN);
01123 wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
01124 }
01125
01126
01127 static void wpa_driver_ndis_event_auth(struct wpa_driver_ndis_data *drv,
01128 const u8 *data, size_t data_len)
01129 {
01130 NDIS_802_11_AUTHENTICATION_REQUEST *req;
01131 int pairwise = 0, group = 0;
01132 union wpa_event_data event;
01133
01134 if (data_len < sizeof(*req)) {
01135 wpa_printf(MSG_DEBUG, "NDIS: Too short Authentication Request "
01136 "Event (len=%d)", data_len);
01137 return;
01138 }
01139 req = (NDIS_802_11_AUTHENTICATION_REQUEST *) data;
01140
01141 wpa_printf(MSG_DEBUG, "NDIS: Authentication Request Event: "
01142 "Bssid " MACSTR " Flags 0x%x",
01143 MAC2STR(req->Bssid), (int) req->Flags);
01144
01145 if ((req->Flags & NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR) ==
01146 NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR)
01147 pairwise = 1;
01148 else if ((req->Flags & NDIS_802_11_AUTH_REQUEST_GROUP_ERROR) ==
01149 NDIS_802_11_AUTH_REQUEST_GROUP_ERROR)
01150 group = 1;
01151
01152 if (pairwise || group) {
01153 memset(&event, 0, sizeof(event));
01154 event.michael_mic_failure.unicast = pairwise;
01155 wpa_supplicant_event(drv->ctx, EVENT_MICHAEL_MIC_FAILURE,
01156 &event);
01157 }
01158 }
01159
01160
01161 static void wpa_driver_ndis_event_pmkid(struct wpa_driver_ndis_data *drv,
01162 const u8 *data, size_t data_len)
01163 {
01164 NDIS_802_11_PMKID_CANDIDATE_LIST *pmkid;
01165 int i;
01166 union wpa_event_data event;
01167
01168 if (data_len < 8) {
01169 wpa_printf(MSG_DEBUG, "NDIS: Too short PMKID Candidate List "
01170 "Event (len=%d)", data_len);
01171 return;
01172 }
01173 pmkid = (NDIS_802_11_PMKID_CANDIDATE_LIST *) data;
01174 wpa_printf(MSG_DEBUG, "NDIS: PMKID Candidate List Event - Version %d "
01175 "NumCandidates %d",
01176 (int) pmkid->Version, (int) pmkid->NumCandidates);
01177
01178 if (pmkid->Version != 1) {
01179 wpa_printf(MSG_DEBUG, "NDIS: Unsupported PMKID Candidate List "
01180 "Version %d", (int) pmkid->Version);
01181 return;
01182 }
01183
01184 if (data_len < 8 + pmkid->NumCandidates * sizeof(PMKID_CANDIDATE)) {
01185 wpa_printf(MSG_DEBUG, "NDIS: PMKID Candidate List underflow");
01186 return;
01187 }
01188
01189 memset(&event, 0, sizeof(event));
01190 for (i = 0; i < pmkid->NumCandidates; i++) {
01191 PMKID_CANDIDATE *p = &pmkid->CandidateList[i];
01192 wpa_printf(MSG_DEBUG, "NDIS: %d: " MACSTR " Flags 0x%x",
01193 i, MAC2STR(p->BSSID), (int) p->Flags);
01194 memcpy(event.pmkid_candidate.bssid, p->BSSID, ETH_ALEN);
01195 event.pmkid_candidate.index = i;
01196 event.pmkid_candidate.preauth =
01197 p->Flags & NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
01198 wpa_supplicant_event(drv->ctx, EVENT_PMKID_CANDIDATE,
01199 &event);
01200 }
01201 }
01202
01203
01204
01205
01206 void wpa_driver_ndis_event_media_specific(struct wpa_driver_ndis_data *drv,
01207 const u8 *data, size_t data_len)
01208 {
01209 NDIS_802_11_STATUS_INDICATION *status;
01210
01211 if (data == NULL || data_len < sizeof(*status))
01212 return;
01213
01214 wpa_hexdump(MSG_DEBUG, "NDIS: Media Specific Indication",
01215 data, data_len);
01216
01217 status = (NDIS_802_11_STATUS_INDICATION *) data;
01218 data += sizeof(status);
01219 data_len -= sizeof(status);
01220
01221 switch (status->StatusType) {
01222 case Ndis802_11StatusType_Authentication:
01223 wpa_driver_ndis_event_auth(drv, data, data_len);
01224 break;
01225 case Ndis802_11StatusType_PMKID_CandidateList:
01226 wpa_driver_ndis_event_pmkid(drv, data, data_len);
01227 break;
01228 default:
01229 wpa_printf(MSG_DEBUG, "NDIS: Unknown StatusType %d",
01230 (int) status->StatusType);
01231 break;
01232 }
01233 }
01234
01235
01236 static void
01237 wpa_driver_ndis_get_wpa_capability(struct wpa_driver_ndis_data *drv)
01238 {
01239 wpa_printf(MSG_DEBUG, "NDIS: verifying driver WPA capability");
01240
01241 if (ndis_set_auth_mode(drv, Ndis802_11AuthModeWPA) == 0 &&
01242 ndis_get_auth_mode(drv) == Ndis802_11AuthModeWPA) {
01243 wpa_printf(MSG_DEBUG, "NDIS: WPA key management supported");
01244 drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA;
01245 }
01246
01247 if (ndis_set_auth_mode(drv, Ndis802_11AuthModeWPAPSK) == 0 &&
01248 ndis_get_auth_mode(drv) == Ndis802_11AuthModeWPAPSK) {
01249 wpa_printf(MSG_DEBUG, "NDIS: WPA-PSK key management "
01250 "supported");
01251 drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK;
01252 }
01253
01254 if (ndis_set_encr_status(drv, Ndis802_11Encryption3Enabled) == 0 &&
01255 ndis_get_encr_status(drv) == Ndis802_11Encryption3KeyAbsent) {
01256 wpa_printf(MSG_DEBUG, "NDIS: CCMP encryption supported");
01257 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP;
01258 }
01259
01260 if (ndis_set_encr_status(drv, Ndis802_11Encryption2Enabled) == 0 &&
01261 ndis_get_encr_status(drv) == Ndis802_11Encryption2KeyAbsent) {
01262 wpa_printf(MSG_DEBUG, "NDIS: TKIP encryption supported");
01263 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_TKIP;
01264 }
01265
01266 if (ndis_set_encr_status(drv, Ndis802_11Encryption1Enabled) == 0 &&
01267 ndis_get_encr_status(drv) == Ndis802_11Encryption1KeyAbsent) {
01268 wpa_printf(MSG_DEBUG, "NDIS: WEP encryption supported");
01269 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP40 |
01270 WPA_DRIVER_CAPA_ENC_WEP104;
01271 }
01272
01273 if (ndis_set_auth_mode(drv, Ndis802_11AuthModeShared) == 0 &&
01274 ndis_get_auth_mode(drv) == Ndis802_11AuthModeShared) {
01275 drv->capa.auth |= WPA_DRIVER_AUTH_SHARED;
01276 }
01277
01278 if (ndis_set_auth_mode(drv, Ndis802_11AuthModeOpen) == 0 &&
01279 ndis_get_auth_mode(drv) == Ndis802_11AuthModeOpen) {
01280 drv->capa.auth |= WPA_DRIVER_AUTH_OPEN;
01281 }
01282
01283 ndis_set_encr_status(drv, Ndis802_11EncryptionDisabled);
01284
01285
01286
01287
01288 if (drv->capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA &&
01289 drv->capa.enc & (WPA_DRIVER_CAPA_ENC_TKIP |
01290 WPA_DRIVER_CAPA_ENC_CCMP)) {
01291 wpa_printf(MSG_DEBUG, "NDIS: driver supports WPA");
01292 drv->has_capability = 1;
01293 } else {
01294 wpa_printf(MSG_DEBUG, "NDIS: no WPA support found");
01295 }
01296
01297 wpa_printf(MSG_DEBUG, "NDIS: driver capabilities: key_mgmt 0x%x "
01298 "enc 0x%x auth 0x%x",
01299 drv->capa.key_mgmt, drv->capa.enc, drv->capa.auth);
01300 }
01301
01302
01303 static void wpa_driver_ndis_get_capability(struct wpa_driver_ndis_data *drv)
01304 {
01305 char buf[512];
01306 int len, i;
01307 NDIS_802_11_CAPABILITY *c;
01308
01309 drv->capa.flags = WPA_DRIVER_FLAGS_DRIVER_IE |
01310 WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC;
01311
01312 len = ndis_get_oid(drv, OID_802_11_CAPABILITY, buf, sizeof(buf));
01313 if (len < 0) {
01314 wpa_driver_ndis_get_wpa_capability(drv);
01315 return;
01316 }
01317
01318 wpa_hexdump(MSG_MSGDUMP, "OID_802_11_CAPABILITY", buf, len);
01319 c = (NDIS_802_11_CAPABILITY *) buf;
01320 if (len < sizeof(*c) || c->Version != 2) {
01321 wpa_printf(MSG_DEBUG, "NDIS: unsupported "
01322 "OID_802_11_CAPABILITY data");
01323 return;
01324 }
01325 wpa_printf(MSG_DEBUG, "NDIS: Driver supports OID_802_11_CAPABILITY - "
01326 "NoOfPMKIDs %d NoOfAuthEncrPairs %d",
01327 (int) c->NoOfPMKIDs, (int) c->NoOfAuthEncryptPairSupported);
01328 drv->has_capability = 1;
01329 drv->no_of_pmkid = c->NoOfPMKIDs;
01330 for (i = 0; i < c->NoOfAuthEncryptPairSupported; i++) {
01331 NDIS_802_11_AUTHENTICATION_ENCRYPTION *ae;
01332 ae = &c->AuthenticationEncryptionSupported[i];
01333 if ((char *) (ae + 1) > buf + len) {
01334 wpa_printf(MSG_DEBUG, "NDIS: auth/encr pair list "
01335 "overflow");
01336 break;
01337 }
01338 wpa_printf(MSG_MSGDUMP, "NDIS: %d - auth %d encr %d",
01339 i, (int) ae->AuthModeSupported,
01340 (int) ae->EncryptStatusSupported);
01341 switch (ae->AuthModeSupported) {
01342 case Ndis802_11AuthModeOpen:
01343 drv->capa.auth |= WPA_DRIVER_AUTH_OPEN;
01344 break;
01345 case Ndis802_11AuthModeShared:
01346 drv->capa.auth |= WPA_DRIVER_AUTH_SHARED;
01347 break;
01348 case Ndis802_11AuthModeWPA:
01349 drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA;
01350 break;
01351 case Ndis802_11AuthModeWPAPSK:
01352 drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK;
01353 break;
01354 case Ndis802_11AuthModeWPA2:
01355 drv->capa.key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA2;
01356 break;
01357 case Ndis802_11AuthModeWPA2PSK:
01358 drv->capa.key_mgmt |=
01359 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK;
01360 break;
01361 case Ndis802_11AuthModeWPANone:
01362 drv->capa.key_mgmt |=
01363 WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE;
01364 break;
01365 default:
01366 break;
01367 }
01368 switch (ae->EncryptStatusSupported) {
01369 case Ndis802_11Encryption1Enabled:
01370 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP40;
01371 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP104;
01372 break;
01373 case Ndis802_11Encryption2Enabled:
01374 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_TKIP;
01375 break;
01376 case Ndis802_11Encryption3Enabled:
01377 drv->capa.enc |= WPA_DRIVER_CAPA_ENC_CCMP;
01378 break;
01379 default:
01380 break;
01381 }
01382 }
01383
01384 wpa_printf(MSG_DEBUG, "NDIS: driver capabilities: key_mgmt 0x%x "
01385 "enc 0x%x auth 0x%x",
01386 drv->capa.key_mgmt, drv->capa.enc, drv->capa.auth);
01387 }
01388
01389
01390 static int wpa_driver_ndis_get_capa(void *priv, struct wpa_driver_capa *capa)
01391 {
01392 struct wpa_driver_ndis_data *drv = priv;
01393 if (!drv->has_capability)
01394 return -1;
01395 memcpy(capa, &drv->capa, sizeof(*capa));
01396 return 0;
01397 }
01398
01399
01400 static const char * wpa_driver_ndis_get_ifname(void *priv)
01401 {
01402 struct wpa_driver_ndis_data *drv = priv;
01403 return drv->ifname;
01404 }
01405
01406
01407 static const u8 * wpa_driver_ndis_get_mac_addr(void *priv)
01408 {
01409 struct wpa_driver_ndis_data *drv = priv;
01410 return drv->own_addr;
01411 }
01412
01413
01414 static int wpa_driver_ndis_get_names(struct wpa_driver_ndis_data *drv)
01415 {
01416 PTSTR names, pos, pos2;
01417 ULONG len;
01418 BOOLEAN res;
01419 const int MAX_ADAPTERS = 32;
01420 char *name[MAX_ADAPTERS];
01421 char *desc[MAX_ADAPTERS];
01422 int num_name, num_desc, i, found_name, found_desc;
01423 size_t dlen;
01424
01425 wpa_printf(MSG_DEBUG, "NDIS: Packet.dll version: %s",
01426 PacketGetVersion());
01427
01428 len = 8192;
01429 names = malloc(len);
01430 if (names == NULL)
01431 return -1;
01432 memset(names, 0, len);
01433
01434 res = PacketGetAdapterNames(names, &len);
01435 if (!res && len > 8192) {
01436 free(names);
01437 names = malloc(len);
01438 if (names == NULL)
01439 return -1;
01440 memset(names, 0, len);
01441 res = PacketGetAdapterNames(names, &len);
01442 }
01443
01444 if (!res) {
01445 wpa_printf(MSG_ERROR, "NDIS: Failed to get adapter list "
01446 "(PacketGetAdapterNames)");
01447 free(names);
01448 return -1;
01449 }
01450
01451
01452
01453 if (names[0] && names[1] == '\0' && names[2] && names[3] == '\0') {
01454 wpa_printf(MSG_DEBUG, "NDIS: Looks like adapter names are in "
01455 "UNICODE");
01456
01457 pos2 = pos = names;
01458 while (pos2 < names + len) {
01459 if (pos2[0] == '\0' && pos2[1] == '\0' &&
01460 pos2[2] == '\0' && pos2[3] == '\0') {
01461 pos2 += 4;
01462 break;
01463 }
01464 *pos++ = pos2[0];
01465 pos2 += 2;
01466 }
01467 memcpy(pos + 2, names, pos - names);
01468 pos += 2;
01469 } else
01470 pos = names;
01471
01472 num_name = 0;
01473 while (pos < names + len) {
01474 name[num_name] = pos;
01475 while (*pos && pos < names + len)
01476 pos++;
01477 if (pos + 1 >= names + len) {
01478 free(names);
01479 return -1;
01480 }
01481 pos++;
01482 num_name++;
01483 if (num_name >= MAX_ADAPTERS) {
01484 wpa_printf(MSG_DEBUG, "NDIS: Too many adapters");
01485 free(names);
01486 return -1;
01487 }
01488 if (*pos == '\0') {
01489 wpa_printf(MSG_DEBUG, "NDIS: %d adapter names found",
01490 num_name);
01491 pos++;
01492 break;
01493 }
01494 }
01495
01496 num_desc = 0;
01497 while (pos < names + len) {
01498 desc[num_desc] = pos;
01499 while (*pos && pos < names + len)
01500 pos++;
01501 if (pos + 1 >= names + len) {
01502 free(names);
01503 return -1;
01504 }
01505 pos++;
01506 num_desc++;
01507 if (num_desc >= MAX_ADAPTERS) {
01508 wpa_printf(MSG_DEBUG, "NDIS: Too many adapter "
01509 "descriptions");
01510 free(names);
01511 return -1;
01512 }
01513 if (*pos == '\0') {
01514 wpa_printf(MSG_DEBUG, "NDIS: %d adapter descriptions "
01515 "found", num_name);
01516 pos++;
01517 break;
01518 }
01519 }
01520
01521
01522
01523
01524
01525 while (num_desc < num_name)
01526 desc[num_desc++] = "dummy description";
01527
01528 if (num_name != num_desc) {
01529 wpa_printf(MSG_DEBUG, "NDIS: mismatch in adapter name and "
01530 "description counts (%d != %d)",
01531 num_name, num_desc);
01532 free(names);
01533 return -1;
01534 }
01535
01536 found_name = found_desc = -1;
01537 for (i = 0; i < num_name; i++) {
01538 wpa_printf(MSG_DEBUG, "NDIS: %d - %s - %s",
01539 i, name[i], desc[i]);
01540 if (found_name == -1 && strcmp(name[i], drv->ifname) == 0) {
01541 found_name = i;
01542 }
01543 if (found_desc == -1 &&
01544 strncmp(desc[i], drv->ifname, strlen(drv->ifname)) == 0) {
01545 found_desc = i;
01546 }
01547 }
01548
01549 if (found_name < 0 && found_desc >= 0) {
01550 wpa_printf(MSG_DEBUG, "NDIS: Matched interface '%s' based on "
01551 "description '%s'",
01552 name[found_desc], desc[found_desc]);
01553 found_name = found_desc;
01554 strncpy(drv->ifname, name[found_desc], sizeof(drv->ifname));
01555 }
01556
01557 if (found_name < 0) {
01558 wpa_printf(MSG_DEBUG, "NDIS: Could not find interface '%s'",
01559 drv->ifname);
01560 free(names);
01561 return -1;
01562 }
01563
01564 i = found_name;
01565 pos = strchr(desc[i], '(');
01566 if (pos) {
01567 dlen = pos - desc[i];
01568 pos--;
01569 if (pos > desc[i] && *pos == ' ')
01570 dlen--;
01571 } else {
01572 dlen = strlen(desc[i]);
01573 }
01574 drv->adapter_desc = malloc(dlen + 1);
01575 if (drv->adapter_desc) {
01576 memcpy(drv->adapter_desc, desc[i], dlen);
01577 drv->adapter_desc[dlen] = '\0';
01578 }
01579
01580 free(names);
01581
01582 if (drv->adapter_desc == NULL)
01583 return -1;
01584
01585 wpa_printf(MSG_DEBUG, "NDIS: Adapter description prefix '%s'",
01586 drv->adapter_desc);
01587
01588 return 0;
01589 }
01590
01591
01592 static void * wpa_driver_ndis_init(void *ctx, const char *ifname)
01593 {
01594 struct wpa_driver_ndis_data *drv;
01595 u32 mode;
01596
01597 drv = malloc(sizeof(*drv));
01598 if (drv == NULL)
01599 return NULL;
01600 memset(drv, 0, sizeof(*drv));
01601 drv->ctx = ctx;
01602 strncpy(drv->ifname, ifname, sizeof(drv->ifname));
01603 drv->event_sock = -1;
01604
01605 if (wpa_driver_ndis_get_names(drv) < 0) {
01606 free(drv);
01607 return NULL;
01608 }
01609
01610 drv->adapter = PacketOpenAdapter(drv->ifname);
01611 if (drv->adapter == NULL) {
01612 wpa_printf(MSG_DEBUG, "NDIS: PacketOpenAdapter failed for "
01613 "'%s'", drv->ifname);
01614 free(drv);
01615 return NULL;
01616 }
01617
01618 if (ndis_get_oid(drv, OID_802_3_CURRENT_ADDRESS,
01619 drv->own_addr, ETH_ALEN) < 0) {
01620 wpa_printf(MSG_DEBUG, "NDIS: Get OID_802_3_CURRENT_ADDRESS "
01621 "failed");
01622 PacketCloseAdapter(drv->adapter);
01623 free(drv);
01624 return NULL;
01625 }
01626 wpa_driver_ndis_get_capability(drv);
01627
01628
01629
01630 wpa_driver_ndis_flush_pmkid(drv);
01631
01632 eloop_register_timeout(1, 0, wpa_driver_ndis_poll_timeout, drv, NULL);
01633
01634 wpa_driver_register_event_cb(drv);
01635
01636
01637
01638 mode = Ndis802_11Infrastructure;
01639 if (ndis_set_oid(drv, OID_802_11_INFRASTRUCTURE_MODE,
01640 (char *) &mode, sizeof(mode)) < 0) {
01641 wpa_printf(MSG_DEBUG, "NDIS: Failed to set "
01642 "OID_802_11_INFRASTRUCTURE_MODE (%d)",
01643 (int) mode);
01644
01645
01646 if (!drv->has_capability && drv->capa.enc == 0) {
01647 wpa_printf(MSG_DEBUG, "NDIS: Driver did not provide "
01648 "any wireless capabilities - assume it is "
01649 "a wired interface");
01650 drv->wired = 1;
01651 }
01652 }
01653
01654 return drv;
01655 }
01656
01657
01658 static void wpa_driver_ndis_deinit(void *priv)
01659 {
01660 struct wpa_driver_ndis_data *drv = priv;
01661 eloop_cancel_timeout(wpa_driver_ndis_poll_timeout, drv, NULL);
01662 wpa_driver_ndis_flush_pmkid(drv);
01663 wpa_driver_ndis_disconnect(drv);
01664 if (wpa_driver_ndis_radio_off(drv) < 0) {
01665 wpa_printf(MSG_DEBUG, "NDIS: failed to disassociate and turn "
01666 "radio off");
01667 }
01668 if (drv->event_sock >= 0) {
01669 eloop_unregister_read_sock(drv->event_sock);
01670 close(drv->event_sock);
01671 }
01672 if (drv->adapter)
01673 PacketCloseAdapter(drv->adapter);
01674
01675 free(drv->adapter_desc);
01676 free(drv);
01677 }
01678
01679
01680 const struct wpa_driver_ops wpa_driver_ndis_ops = {
01681 .name = "ndis",
01682 .desc = "Windows NDIS driver",
01683 .init = wpa_driver_ndis_init,
01684 .deinit = wpa_driver_ndis_deinit,
01685 .set_wpa = wpa_driver_ndis_set_wpa,
01686 .scan = wpa_driver_ndis_scan,
01687 .get_scan_results = wpa_driver_ndis_get_scan_results,
01688 .get_bssid = wpa_driver_ndis_get_bssid,
01689 .get_ssid = wpa_driver_ndis_get_ssid,
01690 .set_key = wpa_driver_ndis_set_key,
01691 .associate = wpa_driver_ndis_associate,
01692 .deauthenticate = wpa_driver_ndis_deauthenticate,
01693 .disassociate = wpa_driver_ndis_disassociate,
01694 .poll = wpa_driver_ndis_poll,
01695 .add_pmkid = wpa_driver_ndis_add_pmkid,
01696 .remove_pmkid = wpa_driver_ndis_remove_pmkid,
01697 .flush_pmkid = wpa_driver_ndis_flush_pmkid,
01698 .get_capa = wpa_driver_ndis_get_capa,
01699 .get_ifname = wpa_driver_ndis_get_ifname,
01700 .get_mac_addr = wpa_driver_ndis_get_mac_addr,
01701 };
01702