2
* WPA Supplicant - driver interaction with Linux ndiswrapper
3
* Copyright (c) 2004-2006, Giridhar Pemmasani <giri@lmc.cs.sunysb.edu>
4
* Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License version 2 as
8
* published by the Free Software Foundation.
10
* Alternatively, this software may be distributed under the terms of BSD
13
* See README and COPYING for more details.
17
#include <sys/ioctl.h>
19
#include "wireless_copy.h"
22
#include "driver_wext.h"
24
struct wpa_driver_ndiswrapper_data {
25
void *wext; /* private data for driver_wext */
27
char ifname[IFNAMSIZ + 1];
52
wpa_cipher pairwise_suite;
53
wpa_cipher group_suite;
54
wpa_key_mgmt key_mgmt_suite;
59
#define PRIV_RESET SIOCIWFIRSTPRIV+0
60
#define WPA_SET_WPA SIOCIWFIRSTPRIV+1
61
#define WPA_SET_KEY SIOCIWFIRSTPRIV+2
62
#define WPA_ASSOCIATE SIOCIWFIRSTPRIV+3
63
#define WPA_DISASSOCIATE SIOCIWFIRSTPRIV+4
64
#define WPA_DROP_UNENCRYPTED SIOCIWFIRSTPRIV+5
65
#define WPA_SET_COUNTERMEASURES SIOCIWFIRSTPRIV+6
66
#define WPA_DEAUTHENTICATE SIOCIWFIRSTPRIV+7
67
#define WPA_SET_AUTH_ALG SIOCIWFIRSTPRIV+8
68
#define WPA_INIT SIOCIWFIRSTPRIV+9
69
#define WPA_DEINIT SIOCIWFIRSTPRIV+10
70
#define WPA_GET_CAPA SIOCIWFIRSTPRIV+11
72
static int get_socket(void)
74
static const int families[] = {
75
AF_INET, AF_IPX, AF_AX25, AF_APPLETALK
80
for (i = 0; i < sizeof(families) / sizeof(int); ++i) {
81
sock = socket(families[i], SOCK_DGRAM, 0);
89
static int iw_set_ext(struct wpa_driver_ndiswrapper_data *drv, int request,
92
os_strlcpy(pwrq->ifr_name, drv->ifname, IFNAMSIZ);
93
return ioctl(drv->sock, request, pwrq);
96
static int wpa_ndiswrapper_set_wpa(void *priv, int enabled)
98
struct wpa_driver_ndiswrapper_data *drv = priv;
99
struct iwreq priv_req;
102
os_memset(&priv_req, 0, sizeof(priv_req));
104
priv_req.u.data.flags = enabled;
105
if (iw_set_ext(drv, WPA_SET_WPA, &priv_req) < 0)
110
static int wpa_ndiswrapper_set_key(void *priv, wpa_alg alg, const u8 *addr,
111
int key_idx, int set_tx,
112
const u8 *seq, size_t seq_len,
113
const u8 *key, size_t key_len)
115
struct wpa_driver_ndiswrapper_data *drv = priv;
116
struct wpa_key wpa_key;
118
struct iwreq priv_req;
120
os_memset(&priv_req, 0, sizeof(priv_req));
124
wpa_key.key_index = key_idx;
125
wpa_key.set_tx = set_tx;
127
wpa_key.seq_len = seq_len;
129
wpa_key.key_len = key_len;
131
priv_req.u.data.pointer = (void *)&wpa_key;
132
priv_req.u.data.length = sizeof(wpa_key);
134
if (iw_set_ext(drv, WPA_SET_KEY, &priv_req) < 0)
137
if (alg == WPA_ALG_NONE) {
139
* ndiswrapper did not seem to be clearing keys properly in
140
* some cases with WPA_SET_KEY. For example, roaming from WPA
141
* enabled AP to plaintext one seemed to fail since the driver
142
* did not associate. Try to make sure the keys are cleared so
143
* that plaintext APs can be used in all cases.
145
wpa_driver_wext_set_key(drv->wext, alg, addr, key_idx, set_tx,
146
seq, seq_len, key, key_len);
152
static int wpa_ndiswrapper_set_countermeasures(void *priv, int enabled)
154
struct wpa_driver_ndiswrapper_data *drv = priv;
156
struct iwreq priv_req;
158
os_memset(&priv_req, 0, sizeof(priv_req));
160
priv_req.u.param.value = enabled;
161
if (iw_set_ext(drv, WPA_SET_COUNTERMEASURES, &priv_req) < 0)
167
static int wpa_ndiswrapper_set_drop_unencrypted(void *priv,
170
struct wpa_driver_ndiswrapper_data *drv = priv;
172
struct iwreq priv_req;
174
os_memset(&priv_req, 0, sizeof(priv_req));
176
priv_req.u.param.value = enabled;
177
if (iw_set_ext(drv, WPA_DROP_UNENCRYPTED, &priv_req) < 0)
182
static int wpa_ndiswrapper_deauthenticate(void *priv, const u8 *addr,
185
struct wpa_driver_ndiswrapper_data *drv = priv;
187
struct iwreq priv_req;
189
os_memset(&priv_req, 0, sizeof(priv_req));
191
priv_req.u.param.value = reason_code;
192
os_memcpy(&priv_req.u.ap_addr.sa_data, addr, ETH_ALEN);
193
if (iw_set_ext(drv, WPA_DEAUTHENTICATE, &priv_req) < 0)
198
static int wpa_ndiswrapper_disassociate(void *priv, const u8 *addr,
201
struct wpa_driver_ndiswrapper_data *drv = priv;
203
struct iwreq priv_req;
205
os_memset(&priv_req, 0, sizeof(priv_req));
207
os_memcpy(&priv_req.u.ap_addr.sa_data, addr, ETH_ALEN);
208
if (iw_set_ext(drv, WPA_DISASSOCIATE, &priv_req) < 0)
214
wpa_ndiswrapper_associate(void *priv,
215
struct wpa_driver_associate_params *params)
217
struct wpa_driver_ndiswrapper_data *drv = priv;
219
struct wpa_assoc_info wpa_assoc_info;
220
struct iwreq priv_req;
222
os_memset(&priv_req, 0, sizeof(priv_req));
223
os_memset(&wpa_assoc_info, 0, sizeof(wpa_assoc_info));
225
wpa_assoc_info.bssid = params->bssid;
226
wpa_assoc_info.ssid = params->ssid;
227
wpa_assoc_info.ssid_len = params->ssid_len;
228
wpa_assoc_info.freq = params->freq;
229
wpa_assoc_info.wpa_ie = params->wpa_ie;
230
wpa_assoc_info.wpa_ie_len = params->wpa_ie_len;
231
wpa_assoc_info.pairwise_suite = params->pairwise_suite;
232
wpa_assoc_info.group_suite = params->group_suite;
233
wpa_assoc_info.key_mgmt_suite = params->key_mgmt_suite;
234
wpa_assoc_info.auth_alg = params->auth_alg;
235
wpa_assoc_info.mode = params->mode;
237
priv_req.u.data.pointer = (void *)&wpa_assoc_info;
238
priv_req.u.data.length = sizeof(wpa_assoc_info);
240
if (iw_set_ext(drv, WPA_ASSOCIATE, &priv_req) < 0)
245
static int wpa_ndiswrapper_set_auth_alg(void *priv, int auth_alg)
247
struct wpa_driver_ndiswrapper_data *drv = priv;
249
struct iwreq priv_req;
251
os_memset(&priv_req, 0, sizeof(priv_req));
253
priv_req.u.param.value = auth_alg;
254
if (iw_set_ext(drv, WPA_SET_AUTH_ALG, &priv_req) < 0)
259
static int wpa_ndiswrapper_get_bssid(void *priv, u8 *bssid)
261
struct wpa_driver_ndiswrapper_data *drv = priv;
262
return wpa_driver_wext_get_bssid(drv->wext, bssid);
266
static int wpa_ndiswrapper_get_ssid(void *priv, u8 *ssid)
268
struct wpa_driver_ndiswrapper_data *drv = priv;
269
return wpa_driver_wext_get_ssid(drv->wext, ssid);
273
static int wpa_ndiswrapper_scan(void *priv, const u8 *ssid, size_t ssid_len)
275
struct wpa_driver_ndiswrapper_data *drv = priv;
276
return wpa_driver_wext_scan(drv->wext, ssid, ssid_len);
280
static int wpa_ndiswrapper_get_scan_results(void *priv,
281
struct wpa_scan_result *results,
284
struct wpa_driver_ndiswrapper_data *drv = priv;
285
return wpa_driver_wext_get_scan_results(drv->wext, results, max_size);
289
static int wpa_ndiswrapper_get_capa(void *priv, struct wpa_driver_capa *capa)
291
struct wpa_driver_ndiswrapper_data *drv = priv;
293
struct iwreq priv_req;
295
os_memset(&priv_req, 0, sizeof(priv_req));
297
priv_req.u.data.pointer = (void *) capa;
298
priv_req.u.data.length = sizeof(*capa);
299
if (iw_set_ext(drv, WPA_GET_CAPA, &priv_req) < 0)
306
static int wpa_ndiswrapper_set_operstate(void *priv, int state)
308
struct wpa_driver_ndiswrapper_data *drv = priv;
309
return wpa_driver_wext_set_operstate(drv->wext, state);
313
static void * wpa_ndiswrapper_init(void *ctx, const char *ifname)
315
struct wpa_driver_ndiswrapper_data *drv;
317
drv = os_zalloc(sizeof(*drv));
320
drv->wext = wpa_driver_wext_init(ctx, ifname);
321
if (drv->wext == NULL) {
327
os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
328
drv->sock = get_socket();
330
wpa_driver_wext_deinit(drv->wext);
339
static void wpa_ndiswrapper_deinit(void *priv)
341
struct wpa_driver_ndiswrapper_data *drv = priv;
342
wpa_driver_wext_deinit(drv->wext);
348
const struct wpa_driver_ops wpa_driver_ndiswrapper_ops = {
349
.name = "ndiswrapper",
350
.desc = "Linux ndiswrapper",
351
.set_wpa = wpa_ndiswrapper_set_wpa,
352
.set_key = wpa_ndiswrapper_set_key,
353
.set_countermeasures = wpa_ndiswrapper_set_countermeasures,
354
.set_drop_unencrypted = wpa_ndiswrapper_set_drop_unencrypted,
355
.deauthenticate = wpa_ndiswrapper_deauthenticate,
356
.disassociate = wpa_ndiswrapper_disassociate,
357
.associate = wpa_ndiswrapper_associate,
358
.set_auth_alg = wpa_ndiswrapper_set_auth_alg,
360
.get_bssid = wpa_ndiswrapper_get_bssid,
361
.get_ssid = wpa_ndiswrapper_get_ssid,
362
.scan = wpa_ndiswrapper_scan,
363
.get_scan_results = wpa_ndiswrapper_get_scan_results,
364
.init = wpa_ndiswrapper_init,
365
.deinit = wpa_ndiswrapper_deinit,
366
.get_capa = wpa_ndiswrapper_get_capa,
367
.set_operstate = wpa_ndiswrapper_set_operstate,