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];
56 wpa_cipher pairwise_suite
;
57 wpa_cipher group_suite
;
58 wpa_key_mgmt key_mgmt_suite
;
63 #define PRIV_RESET SIOCIWFIRSTPRIV+0
64 #define WPA_SET_WPA SIOCIWFIRSTPRIV+1
65 #define WPA_SET_KEY SIOCIWFIRSTPRIV+2
66 #define WPA_ASSOCIATE SIOCIWFIRSTPRIV+3
67 #define WPA_DISASSOCIATE SIOCIWFIRSTPRIV+4
68 #define WPA_DROP_UNENCRYPTED SIOCIWFIRSTPRIV+5
69 #define WPA_SET_COUNTERMEASURES SIOCIWFIRSTPRIV+6
70 #define WPA_DEAUTHENTICATE SIOCIWFIRSTPRIV+7
71 #define WPA_SET_AUTH_ALG SIOCIWFIRSTPRIV+8
72 #define WPA_INIT SIOCIWFIRSTPRIV+9
73 #define WPA_DEINIT SIOCIWFIRSTPRIV+10
74 #define WPA_GET_CAPA SIOCIWFIRSTPRIV+11
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(void *priv
, wpa_alg alg
, const u8
*addr
,
115 int key_idx
, int set_tx
,
116 const u8
*seq
, size_t seq_len
,
117 const u8
*key
, size_t key_len
)
119 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
120 struct wpa_key wpa_key
;
122 struct iwreq priv_req
;
124 os_memset(&priv_req
, 0, sizeof(priv_req
));
128 wpa_key
.key_index
= key_idx
;
129 wpa_key
.set_tx
= set_tx
;
131 wpa_key
.seq_len
= seq_len
;
133 wpa_key
.key_len
= key_len
;
135 priv_req
.u
.data
.pointer
= (void *)&wpa_key
;
136 priv_req
.u
.data
.length
= sizeof(wpa_key
);
138 if (iw_set_ext(drv
, WPA_SET_KEY
, &priv_req
) < 0)
141 if (alg
== WPA_ALG_NONE
) {
143 * ndiswrapper did not seem to be clearing keys properly in
144 * some cases with WPA_SET_KEY. For example, roaming from WPA
145 * enabled AP to plaintext one seemed to fail since the driver
146 * did not associate. Try to make sure the keys are cleared so
147 * that plaintext APs can be used in all cases.
149 wpa_driver_wext_set_key(drv
->wext
, alg
, addr
, key_idx
, set_tx
,
150 seq
, seq_len
, key
, key_len
);
156 static int wpa_ndiswrapper_set_countermeasures(void *priv
, int enabled
)
158 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
160 struct iwreq priv_req
;
162 os_memset(&priv_req
, 0, sizeof(priv_req
));
164 priv_req
.u
.param
.value
= enabled
;
165 if (iw_set_ext(drv
, WPA_SET_COUNTERMEASURES
, &priv_req
) < 0)
171 static int wpa_ndiswrapper_set_drop_unencrypted(void *priv
,
174 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
176 struct iwreq priv_req
;
178 os_memset(&priv_req
, 0, sizeof(priv_req
));
180 priv_req
.u
.param
.value
= enabled
;
181 if (iw_set_ext(drv
, WPA_DROP_UNENCRYPTED
, &priv_req
) < 0)
186 static int wpa_ndiswrapper_deauthenticate(void *priv
, const u8
*addr
,
189 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
191 struct iwreq priv_req
;
193 os_memset(&priv_req
, 0, sizeof(priv_req
));
195 priv_req
.u
.param
.value
= reason_code
;
196 os_memcpy(&priv_req
.u
.ap_addr
.sa_data
, addr
, ETH_ALEN
);
197 if (iw_set_ext(drv
, WPA_DEAUTHENTICATE
, &priv_req
) < 0)
202 static int wpa_ndiswrapper_disassociate(void *priv
, const u8
*addr
,
205 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
207 struct iwreq priv_req
;
209 os_memset(&priv_req
, 0, sizeof(priv_req
));
211 os_memcpy(&priv_req
.u
.ap_addr
.sa_data
, addr
, ETH_ALEN
);
212 if (iw_set_ext(drv
, WPA_DISASSOCIATE
, &priv_req
) < 0)
218 wpa_ndiswrapper_associate(void *priv
,
219 struct wpa_driver_associate_params
*params
)
221 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
223 struct wpa_assoc_info wpa_assoc_info
;
224 struct iwreq priv_req
;
226 os_memset(&priv_req
, 0, sizeof(priv_req
));
227 os_memset(&wpa_assoc_info
, 0, sizeof(wpa_assoc_info
));
229 wpa_assoc_info
.bssid
= params
->bssid
;
230 wpa_assoc_info
.ssid
= params
->ssid
;
231 wpa_assoc_info
.ssid_len
= params
->ssid_len
;
232 wpa_assoc_info
.freq
= params
->freq
;
233 wpa_assoc_info
.wpa_ie
= params
->wpa_ie
;
234 wpa_assoc_info
.wpa_ie_len
= params
->wpa_ie_len
;
235 wpa_assoc_info
.pairwise_suite
= params
->pairwise_suite
;
236 wpa_assoc_info
.group_suite
= params
->group_suite
;
237 wpa_assoc_info
.key_mgmt_suite
= params
->key_mgmt_suite
;
238 wpa_assoc_info
.auth_alg
= params
->auth_alg
;
239 wpa_assoc_info
.mode
= params
->mode
;
241 priv_req
.u
.data
.pointer
= (void *)&wpa_assoc_info
;
242 priv_req
.u
.data
.length
= sizeof(wpa_assoc_info
);
244 if (iw_set_ext(drv
, WPA_ASSOCIATE
, &priv_req
) < 0)
249 static int wpa_ndiswrapper_set_auth_alg(void *priv
, int auth_alg
)
251 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
253 struct iwreq priv_req
;
255 os_memset(&priv_req
, 0, sizeof(priv_req
));
257 priv_req
.u
.param
.value
= auth_alg
;
258 if (iw_set_ext(drv
, WPA_SET_AUTH_ALG
, &priv_req
) < 0)
263 static int wpa_ndiswrapper_get_bssid(void *priv
, u8
*bssid
)
265 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
266 return wpa_driver_wext_get_bssid(drv
->wext
, bssid
);
270 static int wpa_ndiswrapper_get_ssid(void *priv
, u8
*ssid
)
272 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
273 return wpa_driver_wext_get_ssid(drv
->wext
, ssid
);
277 static int wpa_ndiswrapper_scan(void *priv
, const u8
*ssid
, size_t ssid_len
)
279 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
280 return wpa_driver_wext_scan(drv
->wext
, ssid
, ssid_len
);
284 static struct wpa_scan_results
* wpa_ndiswrapper_get_scan_results(void *priv
)
286 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
287 return wpa_driver_wext_get_scan_results(drv
->wext
);
291 static int wpa_ndiswrapper_get_capa(void *priv
, struct wpa_driver_capa
*capa
)
293 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
295 struct iwreq priv_req
;
297 os_memset(&priv_req
, 0, sizeof(priv_req
));
299 priv_req
.u
.data
.pointer
= (void *) capa
;
300 priv_req
.u
.data
.length
= sizeof(*capa
);
301 if (iw_set_ext(drv
, WPA_GET_CAPA
, &priv_req
) < 0)
308 static int wpa_ndiswrapper_set_operstate(void *priv
, int state
)
310 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
311 return wpa_driver_wext_set_operstate(drv
->wext
, state
);
315 static void * wpa_ndiswrapper_init(void *ctx
, const char *ifname
)
317 struct wpa_driver_ndiswrapper_data
*drv
;
319 drv
= os_zalloc(sizeof(*drv
));
322 drv
->wext
= wpa_driver_wext_init(ctx
, ifname
);
323 if (drv
->wext
== NULL
) {
329 os_strlcpy(drv
->ifname
, ifname
, sizeof(drv
->ifname
));
330 drv
->sock
= get_socket();
332 wpa_driver_wext_deinit(drv
->wext
);
341 static void wpa_ndiswrapper_deinit(void *priv
)
343 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
344 wpa_driver_wext_deinit(drv
->wext
);
350 const struct wpa_driver_ops wpa_driver_ndiswrapper_ops
= {
351 .name
= "ndiswrapper",
352 .desc
= "Linux ndiswrapper (deprecated; use wext)",
353 .set_wpa
= wpa_ndiswrapper_set_wpa
,
354 .set_key
= wpa_ndiswrapper_set_key
,
355 .set_countermeasures
= wpa_ndiswrapper_set_countermeasures
,
356 .set_drop_unencrypted
= wpa_ndiswrapper_set_drop_unencrypted
,
357 .deauthenticate
= wpa_ndiswrapper_deauthenticate
,
358 .disassociate
= wpa_ndiswrapper_disassociate
,
359 .associate
= wpa_ndiswrapper_associate
,
360 .set_auth_alg
= wpa_ndiswrapper_set_auth_alg
,
362 .get_bssid
= wpa_ndiswrapper_get_bssid
,
363 .get_ssid
= wpa_ndiswrapper_get_ssid
,
364 .scan
= wpa_ndiswrapper_scan
,
365 .get_scan_results2
= wpa_ndiswrapper_get_scan_results
,
366 .init
= wpa_ndiswrapper_init
,
367 .deinit
= wpa_ndiswrapper_deinit
,
368 .get_capa
= wpa_ndiswrapper_get_capa
,
369 .set_operstate
= wpa_ndiswrapper_set_operstate
,