2 * WPA Supplicant - driver interaction with Linux Prism54.org driver
3 * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
4 * Copyright (c) 2004, Luis R. Rodriguez <mcgrof@ruslug.rutgers.edu>
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"
23 #include "driver_hostap.h"
25 struct wpa_driver_prism54_data
{
26 void *wext
; /* private data for driver_wext */
28 char ifname
[IFNAMSIZ
+ 1];
32 #define PRISM54_SET_WPA SIOCIWFIRSTPRIV+12
33 #define PRISM54_HOSTAPD SIOCIWFIRSTPRIV+25
34 #define PRISM54_DROP_UNENCRYPTED SIOCIWFIRSTPRIV+26
36 static void show_set_key_error(struct prism2_hostapd_param
*);
38 static int hostapd_ioctl_prism54(struct wpa_driver_prism54_data
*drv
,
39 struct prism2_hostapd_param
*param
,
40 int len
, int show_err
)
44 os_memset(&iwr
, 0, sizeof(iwr
));
45 os_strlcpy(iwr
.ifr_name
, drv
->ifname
, IFNAMSIZ
);
46 iwr
.u
.data
.pointer
= (caddr_t
) param
;
47 iwr
.u
.data
.length
= len
;
49 if (ioctl(drv
->sock
, PRISM54_HOSTAPD
, &iwr
) < 0) {
52 perror("ioctl[PRISM54_HOSTAPD]");
60 static int wpa_driver_prism54_set_wpa_ie(struct wpa_driver_prism54_data
*drv
,
64 struct prism2_hostapd_param
*param
;
66 size_t blen
= PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN
+ wpa_ie_len
;
67 if (blen
< sizeof(*param
))
68 blen
= sizeof(*param
);
70 param
= os_zalloc(blen
);
74 param
->cmd
= PRISM2_HOSTAPD_SET_GENERIC_ELEMENT
;
75 param
->u
.generic_elem
.len
= wpa_ie_len
;
76 os_memcpy(param
->u
.generic_elem
.data
, wpa_ie
, wpa_ie_len
);
77 res
= hostapd_ioctl_prism54(drv
, param
, blen
, 1);
85 /* This is called at wpa_supplicant daemon init time */
86 static int wpa_driver_prism54_set_wpa(void *priv
, int enabled
)
88 struct wpa_driver_prism54_data
*drv
= priv
;
89 struct prism2_hostapd_param
*param
;
91 size_t blen
= PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN
;
92 if (blen
< sizeof(*param
))
93 blen
= sizeof(*param
);
95 param
= os_zalloc(blen
);
99 param
->cmd
= PRISM54_SET_WPA
;
100 param
->u
.generic_elem
.len
= 0;
101 res
= hostapd_ioctl_prism54(drv
, param
, blen
, 1);
109 static int wpa_driver_prism54_set_key(void *priv
, wpa_alg alg
,
110 const u8
*addr
, int key_idx
, int set_tx
,
111 const u8
*seq
, size_t seq_len
,
112 const u8
*key
, size_t key_len
)
114 struct wpa_driver_prism54_data
*drv
= priv
;
115 struct prism2_hostapd_param
*param
;
141 wpa_printf(MSG_DEBUG
, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%lu "
142 "key_len=%lu", __FUNCTION__
, alg_name
, key_idx
, set_tx
,
143 (unsigned long) seq_len
, (unsigned long) key_len
);
148 blen
= sizeof(*param
) + key_len
;
149 buf
= os_zalloc(blen
);
153 param
= (struct prism2_hostapd_param
*) buf
;
154 param
->cmd
= PRISM2_SET_ENCRYPTION
;
155 /* TODO: In theory, STA in client mode can use five keys; four default
156 * keys for receiving (with keyidx 0..3) and one individual key for
157 * both transmitting and receiving (keyidx 0) _unicast_ packets. Now,
158 * keyidx 0 is reserved for this unicast use and default keys can only
159 * use keyidx 1..3 (i.e., default key with keyidx 0 is not supported).
160 * This should be fine for more or less all cases, but for completeness
161 * sake, the driver could be enhanced to support the missing key. */
164 os_memset(param
->sta_addr
, 0xff, ETH_ALEN
);
166 os_memcpy(param
->sta_addr
, addr
, ETH_ALEN
);
168 os_memset(param
->sta_addr
, 0xff, ETH_ALEN
);
170 os_strlcpy((char *) param
->u
.crypt
.alg
, alg_name
,
171 HOSTAP_CRYPT_ALG_NAME_LEN
);
172 param
->u
.crypt
.flags
= set_tx
? HOSTAP_CRYPT_FLAG_SET_TX_KEY
: 0;
173 param
->u
.crypt
.idx
= key_idx
;
174 os_memcpy(param
->u
.crypt
.seq
, seq
, seq_len
);
175 param
->u
.crypt
.key_len
= key_len
;
176 os_memcpy((u8
*) (param
+ 1), key
, key_len
);
178 if (hostapd_ioctl_prism54(drv
, param
, blen
, 1)) {
179 wpa_printf(MSG_WARNING
, "Failed to set encryption.");
180 show_set_key_error(param
);
189 static int wpa_driver_prism54_set_countermeasures(void *priv
,
193 printf("wpa_driver_prism54_set_countermeasures - not yet "
199 static int wpa_driver_prism54_set_drop_unencrypted(void *priv
,
202 struct wpa_driver_prism54_data
*drv
= priv
;
203 struct prism2_hostapd_param
*param
;
205 size_t blen
= PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN
;
206 if (blen
< sizeof(*param
))
207 blen
= sizeof(*param
);
209 param
= os_zalloc(blen
);
213 param
->cmd
= PRISM54_DROP_UNENCRYPTED
;
214 param
->u
.generic_elem
.len
= 0;
215 res
= hostapd_ioctl_prism54(drv
, param
, blen
, 1);
223 static int wpa_driver_prism54_deauthenticate(void *priv
, const u8
*addr
,
227 printf("wpa_driver_prism54_deauthenticate - not yet implemented\n");
232 static int wpa_driver_prism54_disassociate(void *priv
, const u8
*addr
,
236 printf("wpa_driver_prism54_disassociate - not yet implemented\n");
242 wpa_driver_prism54_associate(void *priv
,
243 struct wpa_driver_associate_params
*params
)
245 struct wpa_driver_prism54_data
*drv
= priv
;
248 if (wpa_driver_prism54_set_wpa_ie(drv
, params
->wpa_ie
,
249 params
->wpa_ie_len
) < 0)
251 if (wpa_driver_wext_set_freq(drv
->wext
, params
->freq
) < 0)
253 if (wpa_driver_wext_set_ssid(drv
->wext
, params
->ssid
,
254 params
->ssid_len
) < 0)
256 if (wpa_driver_wext_set_bssid(drv
->wext
, params
->bssid
) < 0)
262 static void show_set_key_error(struct prism2_hostapd_param
*param
)
264 switch (param
->u
.crypt
.err
) {
265 case HOSTAP_CRYPT_ERR_UNKNOWN_ALG
:
266 wpa_printf(MSG_INFO
, "Unknown algorithm '%s'.",
268 wpa_printf(MSG_INFO
, "You may need to load kernel module to "
269 "register that algorithm.");
270 wpa_printf(MSG_INFO
, "E.g., 'modprobe hostap_crypt_wep' for "
273 case HOSTAP_CRYPT_ERR_UNKNOWN_ADDR
:
274 wpa_printf(MSG_INFO
, "Unknown address " MACSTR
".",
275 MAC2STR(param
->sta_addr
));
277 case HOSTAP_CRYPT_ERR_CRYPT_INIT_FAILED
:
278 wpa_printf(MSG_INFO
, "Crypt algorithm initialization failed.");
280 case HOSTAP_CRYPT_ERR_KEY_SET_FAILED
:
281 wpa_printf(MSG_INFO
, "Key setting failed.");
283 case HOSTAP_CRYPT_ERR_TX_KEY_SET_FAILED
:
284 wpa_printf(MSG_INFO
, "TX key index setting failed.");
286 case HOSTAP_CRYPT_ERR_CARD_CONF_FAILED
:
287 wpa_printf(MSG_INFO
, "Card configuration failed.");
293 static int wpa_driver_prism54_get_bssid(void *priv
, u8
*bssid
)
295 struct wpa_driver_prism54_data
*drv
= priv
;
296 return wpa_driver_wext_get_bssid(drv
->wext
, bssid
);
300 static int wpa_driver_prism54_get_ssid(void *priv
, u8
*ssid
)
302 struct wpa_driver_prism54_data
*drv
= priv
;
303 return wpa_driver_wext_get_ssid(drv
->wext
, ssid
);
307 static int wpa_driver_prism54_scan(void *priv
, const u8
*ssid
, size_t ssid_len
)
309 struct wpa_driver_prism54_data
*drv
= priv
;
310 return wpa_driver_wext_scan(drv
->wext
, ssid
, ssid_len
);
314 static struct wpa_scan_results
*
315 wpa_driver_prism54_get_scan_results(void *priv
)
317 struct wpa_driver_prism54_data
*drv
= priv
;
318 return wpa_driver_wext_get_scan_results(drv
->wext
);
322 static int wpa_driver_prism54_set_operstate(void *priv
, int state
)
324 struct wpa_driver_prism54_data
*drv
= priv
;
325 return wpa_driver_wext_set_operstate(drv
->wext
, state
);
329 static void * wpa_driver_prism54_init(void *ctx
, const char *ifname
)
331 struct wpa_driver_prism54_data
*drv
;
333 drv
= os_zalloc(sizeof(*drv
));
336 drv
->wext
= wpa_driver_wext_init(ctx
, ifname
);
337 if (drv
->wext
== NULL
) {
343 os_strlcpy(drv
->ifname
, ifname
, sizeof(drv
->ifname
));
344 drv
->sock
= socket(PF_INET
, SOCK_DGRAM
, 0);
346 wpa_driver_wext_deinit(drv
->wext
);
355 static void wpa_driver_prism54_deinit(void *priv
)
357 struct wpa_driver_prism54_data
*drv
= priv
;
358 wpa_driver_wext_deinit(drv
->wext
);
364 const struct wpa_driver_ops wpa_driver_prism54_ops
= {
366 .desc
= "Prism54.org driver (Intersil Prism GT/Duette/Indigo)",
367 .get_bssid
= wpa_driver_prism54_get_bssid
,
368 .get_ssid
= wpa_driver_prism54_get_ssid
,
369 .set_wpa
= wpa_driver_prism54_set_wpa
,
370 .set_key
= wpa_driver_prism54_set_key
,
371 .set_countermeasures
= wpa_driver_prism54_set_countermeasures
,
372 .set_drop_unencrypted
= wpa_driver_prism54_set_drop_unencrypted
,
373 .scan
= wpa_driver_prism54_scan
,
374 .get_scan_results2
= wpa_driver_prism54_get_scan_results
,
375 .deauthenticate
= wpa_driver_prism54_deauthenticate
,
376 .disassociate
= wpa_driver_prism54_disassociate
,
377 .associate
= wpa_driver_prism54_associate
,
378 .init
= wpa_driver_prism54_init
,
379 .deinit
= wpa_driver_prism54_deinit
,
380 .set_operstate
= wpa_driver_prism54_set_operstate
,