add place-holder directory for the a3000 wd533c93 scsi controller implementation.
[AROS.git] / workbench / network / WirelessManager / src / drivers / driver_ndiswrapper.c
blobcd2f61e468a043ad212da0cd80d7fb87544aca82
1 /*
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
11 * license.
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.
20 #include "includes.h"
21 #include <sys/ioctl.h>
23 #include "wireless_copy.h"
24 #include "common.h"
25 #include "driver.h"
26 #include "driver_wext.h"
28 struct wpa_driver_ndiswrapper_data {
29 void *wext; /* private data for driver_wext */
30 void *ctx;
31 char ifname[IFNAMSIZ + 1];
32 int sock;
36 struct wpa_key {
37 enum wpa_alg alg;
38 const u8 *addr;
39 int key_index;
40 int set_tx;
41 const u8 *seq;
42 size_t seq_len;
43 const u8 *key;
44 size_t key_len;
47 struct wpa_assoc_info {
48 const u8 *bssid;
49 const u8 *ssid;
50 size_t ssid_len;
51 int freq;
52 const u8 *wpa_ie;
53 size_t wpa_ie_len;
54 enum wpa_cipher pairwise_suite;
55 enum wpa_cipher group_suite;
56 enum wpa_key_mgmt key_mgmt_suite;
57 int auth_alg;
58 int mode;
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
81 unsigned int i;
82 int sock;
84 for (i = 0; i < sizeof(families) / sizeof(int); ++i) {
85 sock = socket(families[i], SOCK_DGRAM, 0);
86 if (sock >= 0)
87 return sock;
90 return -1;
93 static int iw_set_ext(struct wpa_driver_ndiswrapper_data *drv, int request,
94 struct iwreq *pwrq)
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;
104 int ret = 0;
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)
110 ret = -1;
111 return ret;
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;
122 int ret = 0;
123 struct iwreq priv_req;
125 os_memset(&priv_req, 0, sizeof(priv_req));
127 wpa_key.alg = alg;
128 wpa_key.addr = addr;
129 wpa_key.key_index = key_idx;
130 wpa_key.set_tx = set_tx;
131 wpa_key.seq = seq;
132 wpa_key.seq_len = seq_len;
133 wpa_key.key = key;
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)
140 ret = -1;
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);
154 return ret;
157 static int wpa_ndiswrapper_set_countermeasures(void *priv, int enabled)
159 struct wpa_driver_ndiswrapper_data *drv = priv;
160 int ret = 0;
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)
167 ret = -1;
169 return ret;
172 static int wpa_ndiswrapper_set_drop_unencrypted(void *priv,
173 int enabled)
175 struct wpa_driver_ndiswrapper_data *drv = priv;
176 int ret = 0;
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)
183 ret = -1;
184 return ret;
187 static int wpa_ndiswrapper_deauthenticate(void *priv, const u8 *addr,
188 int reason_code)
190 struct wpa_driver_ndiswrapper_data *drv = priv;
191 int ret = 0;
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)
199 ret = -1;
200 return ret;
203 static int wpa_ndiswrapper_disassociate(void *priv, const u8 *addr,
204 int reason_code)
206 struct wpa_driver_ndiswrapper_data *drv = priv;
207 int ret = 0;
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)
214 ret = -1;
215 return ret;
218 static int
219 wpa_ndiswrapper_associate(void *priv,
220 struct wpa_driver_associate_params *params)
222 struct wpa_driver_ndiswrapper_data *drv = priv;
223 int ret = 0;
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)
229 ret = -1;
230 if (wpa_ndiswrapper_set_auth_alg(drv, params->auth_alg) < 0)
231 ret = -1;
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)
252 ret = -1;
253 return ret;
256 static int wpa_ndiswrapper_set_auth_alg(void *priv, int auth_alg)
258 struct wpa_driver_ndiswrapper_data *drv = priv;
259 int ret = 0;
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)
266 ret = -1;
267 return ret;
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;
302 int ret = 0;
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)
310 ret = -1;
311 return ret;
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));
328 if (drv == NULL)
329 return NULL;
330 drv->wext = wpa_driver_wext_init(ctx, ifname);
331 if (drv->wext == NULL) {
332 os_free(drv);
333 return NULL;
336 drv->ctx = ctx;
337 os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
338 drv->sock = get_socket();
339 if (drv->sock < 0) {
340 wpa_driver_wext_deinit(drv->wext);
341 os_free(drv);
342 return NULL;
345 wpa_ndiswrapper_set_wpa(drv, 1);
347 return drv;
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);
356 close(drv->sock);
357 os_free(drv);
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,