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.
15 * Please note that ndiswrapper supports WPA configuration via Linux wireless
16 * extensions and if the kernel includes support for this, driver_wext.c should
17 * be used instead of this driver wrapper.
21 #include <sys/ioctl.h>
23 #include "wireless_copy.h"
26 #include "driver_wext.h"
28 struct wpa_driver_ndiswrapper_data
{
29 void *wext
; /* private data for driver_wext */
31 char ifname
[IFNAMSIZ
+ 1];
47 struct wpa_assoc_info
{
54 enum wpa_cipher pairwise_suite
;
55 enum wpa_cipher group_suite
;
56 enum wpa_key_mgmt key_mgmt_suite
;
61 #define PRIV_RESET SIOCIWFIRSTPRIV+0
62 #define WPA_SET_WPA SIOCIWFIRSTPRIV+1
63 #define WPA_SET_KEY SIOCIWFIRSTPRIV+2
64 #define WPA_ASSOCIATE SIOCIWFIRSTPRIV+3
65 #define WPA_DISASSOCIATE SIOCIWFIRSTPRIV+4
66 #define WPA_DROP_UNENCRYPTED SIOCIWFIRSTPRIV+5
67 #define WPA_SET_COUNTERMEASURES SIOCIWFIRSTPRIV+6
68 #define WPA_DEAUTHENTICATE SIOCIWFIRSTPRIV+7
69 #define WPA_SET_AUTH_ALG SIOCIWFIRSTPRIV+8
70 #define WPA_INIT SIOCIWFIRSTPRIV+9
71 #define WPA_DEINIT SIOCIWFIRSTPRIV+10
72 #define WPA_GET_CAPA SIOCIWFIRSTPRIV+11
74 static int wpa_ndiswrapper_set_auth_alg(void *priv
, int auth_alg
);
76 static int get_socket(void)
78 static const int families
[] = {
79 AF_INET
, AF_IPX
, AF_AX25
, AF_APPLETALK
84 for (i
= 0; i
< sizeof(families
) / sizeof(int); ++i
) {
85 sock
= socket(families
[i
], SOCK_DGRAM
, 0);
93 static int iw_set_ext(struct wpa_driver_ndiswrapper_data
*drv
, int request
,
96 os_strlcpy(pwrq
->ifr_name
, drv
->ifname
, IFNAMSIZ
);
97 return ioctl(drv
->sock
, request
, pwrq
);
100 static int wpa_ndiswrapper_set_wpa(void *priv
, int enabled
)
102 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
103 struct iwreq priv_req
;
106 os_memset(&priv_req
, 0, sizeof(priv_req
));
108 priv_req
.u
.data
.flags
= enabled
;
109 if (iw_set_ext(drv
, WPA_SET_WPA
, &priv_req
) < 0)
114 static int wpa_ndiswrapper_set_key(const char *ifname
, void *priv
,
115 enum wpa_alg alg
, const u8
*addr
,
116 int key_idx
, int set_tx
,
117 const u8
*seq
, size_t seq_len
,
118 const u8
*key
, size_t key_len
)
120 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
121 struct wpa_key wpa_key
;
123 struct iwreq priv_req
;
125 os_memset(&priv_req
, 0, sizeof(priv_req
));
129 wpa_key
.key_index
= key_idx
;
130 wpa_key
.set_tx
= set_tx
;
132 wpa_key
.seq_len
= seq_len
;
134 wpa_key
.key_len
= key_len
;
136 priv_req
.u
.data
.pointer
= (void *)&wpa_key
;
137 priv_req
.u
.data
.length
= sizeof(wpa_key
);
139 if (iw_set_ext(drv
, WPA_SET_KEY
, &priv_req
) < 0)
142 if (alg
== WPA_ALG_NONE
) {
144 * ndiswrapper did not seem to be clearing keys properly in
145 * some cases with WPA_SET_KEY. For example, roaming from WPA
146 * enabled AP to plaintext one seemed to fail since the driver
147 * did not associate. Try to make sure the keys are cleared so
148 * that plaintext APs can be used in all cases.
150 wpa_driver_wext_set_key(ifname
, drv
->wext
, alg
, addr
, key_idx
,
151 set_tx
, seq
, seq_len
, key
, key_len
);
157 static int wpa_ndiswrapper_set_countermeasures(void *priv
, int enabled
)
159 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
161 struct iwreq priv_req
;
163 os_memset(&priv_req
, 0, sizeof(priv_req
));
165 priv_req
.u
.param
.value
= enabled
;
166 if (iw_set_ext(drv
, WPA_SET_COUNTERMEASURES
, &priv_req
) < 0)
172 static int wpa_ndiswrapper_set_drop_unencrypted(void *priv
,
175 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
177 struct iwreq priv_req
;
179 os_memset(&priv_req
, 0, sizeof(priv_req
));
181 priv_req
.u
.param
.value
= enabled
;
182 if (iw_set_ext(drv
, WPA_DROP_UNENCRYPTED
, &priv_req
) < 0)
187 static int wpa_ndiswrapper_deauthenticate(void *priv
, const u8
*addr
,
190 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
192 struct iwreq priv_req
;
194 os_memset(&priv_req
, 0, sizeof(priv_req
));
196 priv_req
.u
.param
.value
= reason_code
;
197 os_memcpy(&priv_req
.u
.ap_addr
.sa_data
, addr
, ETH_ALEN
);
198 if (iw_set_ext(drv
, WPA_DEAUTHENTICATE
, &priv_req
) < 0)
203 static int wpa_ndiswrapper_disassociate(void *priv
, const u8
*addr
,
206 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
208 struct iwreq priv_req
;
210 os_memset(&priv_req
, 0, sizeof(priv_req
));
212 os_memcpy(&priv_req
.u
.ap_addr
.sa_data
, addr
, ETH_ALEN
);
213 if (iw_set_ext(drv
, WPA_DISASSOCIATE
, &priv_req
) < 0)
219 wpa_ndiswrapper_associate(void *priv
,
220 struct wpa_driver_associate_params
*params
)
222 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
224 struct wpa_assoc_info wpa_assoc_info
;
225 struct iwreq priv_req
;
227 if (wpa_ndiswrapper_set_drop_unencrypted(drv
,
228 params
->drop_unencrypted
) < 0)
230 if (wpa_ndiswrapper_set_auth_alg(drv
, params
->auth_alg
) < 0)
233 os_memset(&priv_req
, 0, sizeof(priv_req
));
234 os_memset(&wpa_assoc_info
, 0, sizeof(wpa_assoc_info
));
236 wpa_assoc_info
.bssid
= params
->bssid
;
237 wpa_assoc_info
.ssid
= params
->ssid
;
238 wpa_assoc_info
.ssid_len
= params
->ssid_len
;
239 wpa_assoc_info
.freq
= params
->freq
;
240 wpa_assoc_info
.wpa_ie
= params
->wpa_ie
;
241 wpa_assoc_info
.wpa_ie_len
= params
->wpa_ie_len
;
242 wpa_assoc_info
.pairwise_suite
= params
->pairwise_suite
;
243 wpa_assoc_info
.group_suite
= params
->group_suite
;
244 wpa_assoc_info
.key_mgmt_suite
= params
->key_mgmt_suite
;
245 wpa_assoc_info
.auth_alg
= params
->auth_alg
;
246 wpa_assoc_info
.mode
= params
->mode
;
248 priv_req
.u
.data
.pointer
= (void *)&wpa_assoc_info
;
249 priv_req
.u
.data
.length
= sizeof(wpa_assoc_info
);
251 if (iw_set_ext(drv
, WPA_ASSOCIATE
, &priv_req
) < 0)
256 static int wpa_ndiswrapper_set_auth_alg(void *priv
, int auth_alg
)
258 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
260 struct iwreq priv_req
;
262 os_memset(&priv_req
, 0, sizeof(priv_req
));
264 priv_req
.u
.param
.value
= auth_alg
;
265 if (iw_set_ext(drv
, WPA_SET_AUTH_ALG
, &priv_req
) < 0)
270 static int wpa_ndiswrapper_get_bssid(void *priv
, u8
*bssid
)
272 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
273 return wpa_driver_wext_get_bssid(drv
->wext
, bssid
);
277 static int wpa_ndiswrapper_get_ssid(void *priv
, u8
*ssid
)
279 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
280 return wpa_driver_wext_get_ssid(drv
->wext
, ssid
);
284 static int wpa_ndiswrapper_scan(void *priv
,
285 struct wpa_driver_scan_params
*params
)
287 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
288 return wpa_driver_wext_scan(drv
->wext
, params
);
292 static struct wpa_scan_results
* wpa_ndiswrapper_get_scan_results(void *priv
)
294 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
295 return wpa_driver_wext_get_scan_results(drv
->wext
);
299 static int wpa_ndiswrapper_get_capa(void *priv
, struct wpa_driver_capa
*capa
)
301 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
303 struct iwreq priv_req
;
305 os_memset(&priv_req
, 0, sizeof(priv_req
));
307 priv_req
.u
.data
.pointer
= (void *) capa
;
308 priv_req
.u
.data
.length
= sizeof(*capa
);
309 if (iw_set_ext(drv
, WPA_GET_CAPA
, &priv_req
) < 0)
316 static int wpa_ndiswrapper_set_operstate(void *priv
, int state
)
318 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
319 return wpa_driver_wext_set_operstate(drv
->wext
, state
);
323 static void * wpa_ndiswrapper_init(void *ctx
, const char *ifname
)
325 struct wpa_driver_ndiswrapper_data
*drv
;
327 drv
= os_zalloc(sizeof(*drv
));
330 drv
->wext
= wpa_driver_wext_init(ctx
, ifname
);
331 if (drv
->wext
== NULL
) {
337 os_strlcpy(drv
->ifname
, ifname
, sizeof(drv
->ifname
));
338 drv
->sock
= get_socket();
340 wpa_driver_wext_deinit(drv
->wext
);
345 wpa_ndiswrapper_set_wpa(drv
, 1);
351 static void wpa_ndiswrapper_deinit(void *priv
)
353 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
354 wpa_ndiswrapper_set_wpa(drv
, 0);
355 wpa_driver_wext_deinit(drv
->wext
);
361 const struct wpa_driver_ops wpa_driver_ndiswrapper_ops
= {
362 .name
= "ndiswrapper",
363 .desc
= "Linux ndiswrapper (deprecated; use wext)",
364 .set_key
= wpa_ndiswrapper_set_key
,
365 .set_countermeasures
= wpa_ndiswrapper_set_countermeasures
,
366 .deauthenticate
= wpa_ndiswrapper_deauthenticate
,
367 .disassociate
= wpa_ndiswrapper_disassociate
,
368 .associate
= wpa_ndiswrapper_associate
,
370 .get_bssid
= wpa_ndiswrapper_get_bssid
,
371 .get_ssid
= wpa_ndiswrapper_get_ssid
,
372 .scan2
= wpa_ndiswrapper_scan
,
373 .get_scan_results2
= wpa_ndiswrapper_get_scan_results
,
374 .init
= wpa_ndiswrapper_init
,
375 .deinit
= wpa_ndiswrapper_deinit
,
376 .get_capa
= wpa_ndiswrapper_get_capa
,
377 .set_operstate
= wpa_ndiswrapper_set_operstate
,