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 struct wpa_scan_results
* wpa_ndiswrapper_get_scan_results(void *priv
)
282 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
283 return wpa_driver_wext_get_scan_results(drv
->wext
);
287 static int wpa_ndiswrapper_get_capa(void *priv
, struct wpa_driver_capa
*capa
)
289 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
291 struct iwreq priv_req
;
293 os_memset(&priv_req
, 0, sizeof(priv_req
));
295 priv_req
.u
.data
.pointer
= (void *) capa
;
296 priv_req
.u
.data
.length
= sizeof(*capa
);
297 if (iw_set_ext(drv
, WPA_GET_CAPA
, &priv_req
) < 0)
304 static int wpa_ndiswrapper_set_operstate(void *priv
, int state
)
306 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
307 return wpa_driver_wext_set_operstate(drv
->wext
, state
);
311 static void * wpa_ndiswrapper_init(void *ctx
, const char *ifname
)
313 struct wpa_driver_ndiswrapper_data
*drv
;
315 drv
= os_zalloc(sizeof(*drv
));
318 drv
->wext
= wpa_driver_wext_init(ctx
, ifname
);
319 if (drv
->wext
== NULL
) {
325 os_strlcpy(drv
->ifname
, ifname
, sizeof(drv
->ifname
));
326 drv
->sock
= get_socket();
328 wpa_driver_wext_deinit(drv
->wext
);
337 static void wpa_ndiswrapper_deinit(void *priv
)
339 struct wpa_driver_ndiswrapper_data
*drv
= priv
;
340 wpa_driver_wext_deinit(drv
->wext
);
346 const struct wpa_driver_ops wpa_driver_ndiswrapper_ops
= {
347 .name
= "ndiswrapper",
348 .desc
= "Linux ndiswrapper",
349 .set_wpa
= wpa_ndiswrapper_set_wpa
,
350 .set_key
= wpa_ndiswrapper_set_key
,
351 .set_countermeasures
= wpa_ndiswrapper_set_countermeasures
,
352 .set_drop_unencrypted
= wpa_ndiswrapper_set_drop_unencrypted
,
353 .deauthenticate
= wpa_ndiswrapper_deauthenticate
,
354 .disassociate
= wpa_ndiswrapper_disassociate
,
355 .associate
= wpa_ndiswrapper_associate
,
356 .set_auth_alg
= wpa_ndiswrapper_set_auth_alg
,
358 .get_bssid
= wpa_ndiswrapper_get_bssid
,
359 .get_ssid
= wpa_ndiswrapper_get_ssid
,
360 .scan
= wpa_ndiswrapper_scan
,
361 .get_scan_results2
= wpa_ndiswrapper_get_scan_results
,
362 .init
= wpa_ndiswrapper_init
,
363 .deinit
= wpa_ndiswrapper_deinit
,
364 .get_capa
= wpa_ndiswrapper_get_capa
,
365 .set_operstate
= wpa_ndiswrapper_set_operstate
,