Contents of /trunk/wpa_supplicant/wpa-supplicant-0.4.4-zydas-support.patch
Parent Directory | Revision Log
Revision 40 -
(show annotations)
(download)
Mon Oct 10 18:41:40 2005 UTC (18 years, 11 months ago) by niro
File size: 14074 byte(s)
Mon Oct 10 18:41:40 2005 UTC (18 years, 11 months ago) by niro
File size: 14074 byte(s)
renamed to wpa-supplicant
1 | diff -wBNur wpa_supplicant-0.2.4/Makefile lnx_wpa_supplicant_1_2_0_0/Makefile |
2 | --- wpa_supplicant-0.2.4/Makefile 2004-07-18 02:14:25.000000000 +0200 |
3 | +++ lnx_wpa_supplicant_1_2_0_0/Makefile 2005-08-01 11:14:38.000000000 +0200 |
4 | @@ -89,6 +94,12 @@ |
5 | CONFIG_WIRELESS_EXTENSION=y |
6 | endif |
7 | |
8 | +ifdef CONFIG_DRIVER_ZYDAS |
9 | +CFLAGS += -DCONFIG_DRIVER_ZYDAS |
10 | +OBJS += driver_zydas.o |
11 | +CONFIG_WIRELESS_EXTENSION=y |
12 | +endif |
13 | + |
14 | ifdef CONFIG_EAP_TLS |
15 | # EAP-TLS |
16 | CFLAGS += -DEAP_TLS |
17 | diff -wBNur wpa_supplicant-0.2.4/driver_zydas.c lnx_wpa_supplicant_1_2_0_0/driver_zydas.c |
18 | --- wpa_supplicant-0.2.4/driver_zydas.c 1970-01-01 01:00:00.000000000 +0100 |
19 | +++ lnx_wpa_supplicant_1_2_0_0/driver_zydas.c 2005-08-01 11:14:37.000000000 +0200 |
20 | @@ -0,0 +1,444 @@ |
21 | +/* |
22 | + * WPA Supplicant - driver interaction with MADWIFI 802.11 driver |
23 | + * Copyright (c) 2004, Sam Leffler <sam@errno.com> |
24 | + * |
25 | + * This program is free software; you can redistribute it and/or modify |
26 | + * it under the terms of the GNU General Public License version 2 as |
27 | + * published by the Free Software Foundation. |
28 | + * |
29 | + * Alternatively, this software may be distributed under the terms of BSD |
30 | + * license. |
31 | + * |
32 | + * See README and COPYING for more details. |
33 | + */ |
34 | + |
35 | +#include <stdlib.h> |
36 | +#include <stdio.h> |
37 | +#include <unistd.h> |
38 | +#include <string.h> |
39 | +#include <sys/ioctl.h> |
40 | +#include <errno.h> |
41 | + |
42 | +#include "common.h" |
43 | +#include "driver.h" |
44 | +#include "driver_wext.h" |
45 | +#include "eloop.h" |
46 | +#include "wpa_supplicant.h" |
47 | +#include "zydas_common.h" |
48 | + |
49 | +#include <net/if_arp.h> |
50 | +#include <linux/wireless.h> |
51 | + |
52 | +static int zydas_ioctl(const char *ifname, struct zydas_wlan_param *param, |
53 | + int len, int show_err) |
54 | +{ |
55 | + int s; |
56 | + struct iwreq iwr; |
57 | + |
58 | + s = socket(PF_INET, SOCK_DGRAM, 0); |
59 | + if (s < 0) { |
60 | + perror("socket"); |
61 | + return -1; |
62 | + } |
63 | + memset(&iwr, 0, sizeof(iwr)); |
64 | + strncpy(iwr.ifr_name, ifname, IFNAMSIZ); |
65 | + iwr.u.data.pointer = (caddr_t) param; |
66 | + iwr.u.data.length = len; |
67 | + |
68 | + if (ioctl(s, ZD_IOCTL_WPA, &iwr) < 0) { |
69 | + int ret; |
70 | + close(s); |
71 | + ret = errno; |
72 | + if (show_err) |
73 | + perror("ioctl[ZD_IOCTL_WPA]"); |
74 | + return ret; |
75 | + } |
76 | + close(s); |
77 | + |
78 | + return 0; |
79 | +} |
80 | + |
81 | +static int |
82 | +zydas_set_param(const char *ifname, int op, int arg, int show_err) |
83 | +{ |
84 | + struct iwreq iwr; |
85 | + int *i, s, ret = 0; |
86 | + |
87 | + s = socket(PF_INET, SOCK_DGRAM, 0); |
88 | + if (s < 0) { |
89 | + perror("socket[PF_INET,SOCK_DGRAM]"); |
90 | + return -1; |
91 | + } |
92 | + |
93 | + memset(&iwr, 0, sizeof(iwr)); |
94 | + strncpy(iwr.ifr_name, ifname, IFNAMSIZ); |
95 | + i = (int *) iwr.u.name; |
96 | + *i++ = op; |
97 | + *i++ = arg; |
98 | + |
99 | + if (ioctl(s, ZD_IOCTL_PARAM, &iwr) < 0) { |
100 | + perror("ioctl[ZD_IOCTL_PARAM]"); |
101 | + ret = -1; |
102 | + } |
103 | + close(s); |
104 | + |
105 | + return ret; |
106 | +} |
107 | + |
108 | +static int |
109 | +getifflags(const char *ifname, int *flags) |
110 | +{ |
111 | + struct ifreq ifr; |
112 | + int s; |
113 | + |
114 | + s = socket(PF_INET, SOCK_DGRAM, 0); |
115 | + if (s < 0) { |
116 | + perror("socket"); |
117 | + return -1; |
118 | + } |
119 | + |
120 | + memset(&ifr, 0, sizeof(ifr)); |
121 | + strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); |
122 | + if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) { |
123 | + perror("SIOCGIFFLAGS"); |
124 | + return errno; |
125 | + } |
126 | + *flags = ifr.ifr_flags & 0xffff; |
127 | + return 0; |
128 | +} |
129 | + |
130 | +static int |
131 | +setifflags(const char *ifname, int flags) |
132 | +{ |
133 | + struct ifreq ifr; |
134 | + int s; |
135 | + |
136 | + s = socket(PF_INET, SOCK_DGRAM, 0); |
137 | + if (s < 0) { |
138 | + perror("socket"); |
139 | + return -1; |
140 | + } |
141 | + |
142 | + memset(&ifr, 0, sizeof(ifr)); |
143 | + strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); |
144 | + ifr.ifr_flags = flags & 0xffff; |
145 | + if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) { |
146 | + perror("SIOCSIFFLAGS"); |
147 | + return errno; |
148 | + } |
149 | + return 0; |
150 | +} |
151 | + |
152 | +static int |
153 | +wpa_driver_zydas_set_wpa_ie(const char *ifname, |
154 | + const char *wpa_ie, size_t wpa_ie_len) |
155 | +{ |
156 | + struct zydas_wlan_param *param; |
157 | + int res; |
158 | + size_t blen = ZD_GENERIC_ELEMENT_HDR_LEN + wpa_ie_len; |
159 | + if (blen < sizeof(*param)) |
160 | + blen = sizeof(*param); |
161 | + |
162 | + param = (struct zydas_wlan_param *) malloc(blen); |
163 | + if (param == NULL) |
164 | + return -1; |
165 | + |
166 | + memset(param, 0, blen); |
167 | + param->cmd = ZD_CMD_SET_GENERIC_ELEMENT; |
168 | + param->u.generic_elem.len = wpa_ie_len; |
169 | + memcpy(param->u.generic_elem.data, wpa_ie, wpa_ie_len); |
170 | + res = zydas_ioctl(ifname, param, blen, 1); |
171 | + |
172 | + free(param); |
173 | + |
174 | + return res; |
175 | +} |
176 | + |
177 | +static int |
178 | +wpa_driver_zydas_set_wpa(const char *ifname, int enabled) |
179 | +{ |
180 | + int ret = 0; |
181 | + |
182 | + wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); |
183 | + |
184 | + if (!enabled && wpa_driver_zydas_set_wpa_ie(ifname, NULL, 0) < 0) |
185 | + ret = -1; |
186 | + if (zydas_set_param(ifname, ZD_PARAM_ROAMING, enabled, 1) < 0) |
187 | + ret = -1; |
188 | + if (zydas_set_param(ifname, ZD_PARAM_PRIVACY, enabled, 1) < 0) |
189 | + ret = -1; |
190 | + if (zydas_set_param(ifname, ZD_PARAM_WPA, enabled, 1) < 0) |
191 | + ret = -1; |
192 | + |
193 | + return ret; |
194 | +} |
195 | + |
196 | +static int |
197 | +wpa_driver_zydas_set_key(const char *ifname, wpa_alg alg, |
198 | + unsigned char *addr, int key_idx, |
199 | + int set_tx, u8 *seq, size_t seq_len, |
200 | + u8 *key, size_t key_len) |
201 | +{ |
202 | + struct zydas_wlan_param *param; |
203 | + u8 *buf; |
204 | + size_t blen; |
205 | + int ret = 0; |
206 | + char *alg_name; |
207 | + |
208 | + switch (alg) { |
209 | + case WPA_ALG_NONE: |
210 | + alg_name = "NONE"; |
211 | + break; |
212 | + case WPA_ALG_WEP: |
213 | + alg_name = "WEP"; |
214 | + break; |
215 | + case WPA_ALG_TKIP: |
216 | + alg_name = "TKIP"; |
217 | + break; |
218 | + case WPA_ALG_CCMP: |
219 | + alg_name = "CCMP"; |
220 | + break; |
221 | + default: |
222 | + return -1; |
223 | + } |
224 | + |
225 | + wpa_printf(MSG_DEBUG, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%d " |
226 | + "key_len=%d", __FUNCTION__, alg_name, key_idx, set_tx, |
227 | + seq_len, key_len); |
228 | + |
229 | + if (seq_len > 8) |
230 | + return -2; |
231 | + |
232 | + blen = sizeof(*param) + key_len; |
233 | + buf = malloc(blen); |
234 | + if (buf == NULL) |
235 | + return -1; |
236 | + memset(buf, 0, blen); |
237 | + |
238 | + param = (struct zydas_wlan_param *) buf; |
239 | + param->cmd = ZD_CMD_SET_ENCRYPT_KEY; |
240 | + /* TODO: In theory, STA in client mode can use five keys; four default |
241 | + * keys for receiving (with keyidx 0..3) and one individual key for |
242 | + * both transmitting and receiving (keyidx 0) _unicast_ packets. Now, |
243 | + * keyidx 0 is reserved for this unicast use and default keys can only |
244 | + * use keyidx 1..3 (i.e., default key with keyidx 0 is not supported). |
245 | + * This should be fine for more or less all cases, but for completeness |
246 | + * sake, the driver could be enhanced to support the missing key. */ |
247 | +#if 0 |
248 | + if (addr == NULL) |
249 | + memset(param->sta_addr, 0xff, ETH_ALEN); |
250 | + else |
251 | + memcpy(param->sta_addr, addr, ETH_ALEN); |
252 | +#else |
253 | + memset(param->sta_addr, 0xff, ETH_ALEN); |
254 | +#endif |
255 | + strncpy(param->u.crypt.alg, alg_name, ZD_CRYPT_ALG_NAME_LEN); |
256 | + param->u.crypt.flags = set_tx ? ZD_FLAG_SET_TX_KEY : 0; |
257 | + param->u.crypt.idx = key_idx; |
258 | + memcpy(param->u.crypt.seq, seq, seq_len); |
259 | + param->u.crypt.key_len = key_len; |
260 | + memcpy((u8 *) param->u.crypt.key, key, key_len); |
261 | + |
262 | + /* Dump key context */ |
263 | + if(alg == WPA_ALG_TKIP) { |
264 | + int ii; |
265 | + |
266 | + wpa_printf(MSG_DEBUG, "Key Context:"); |
267 | + for(ii = 0; ii < key_len; ) { |
268 | + printf("0x%02x ", key[ii]); |
269 | + |
270 | + if((++ii % 16) == 0) |
271 | + printf("\n"); |
272 | + } |
273 | + |
274 | + printf("\n"); |
275 | + } |
276 | + |
277 | + if (zydas_ioctl(ifname, param, blen, 1)) { |
278 | + wpa_printf(MSG_WARNING, "Failed to set encryption."); |
279 | + //show_set_key_error(param); |
280 | + ret = -1; |
281 | + } |
282 | + free(buf); |
283 | + |
284 | + return ret; |
285 | +} |
286 | + |
287 | +static int |
288 | +wpa_driver_zydas_set_countermeasures(const char *ifname, int enabled) |
289 | +{ |
290 | + /* Enable the countermeasure */ |
291 | + wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); |
292 | + return zydas_set_param(ifname, ZD_PARAM_COUNTERMEASURES, enabled, 1); |
293 | +} |
294 | + |
295 | +static int |
296 | +wpa_driver_zydas_set_drop_unencrypted(const char *ifname, int enabled) |
297 | +{ |
298 | + /* Enable the countermeasure */ |
299 | + wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); |
300 | + return zydas_set_param(ifname, ZD_PARAM_DROPUNENCRYPTED, enabled, 1); |
301 | +} |
302 | + |
303 | +static int |
304 | +wpa_driver_zydas_deauthenticate(const char *ifname, u8 *addr, int reason_code) |
305 | +{ |
306 | + struct zydas_wlan_param *param; |
307 | + int blen; |
308 | + int ret; |
309 | + |
310 | + blen = sizeof(*param); |
311 | + param = (struct zydas_wlan_param *) malloc(blen); |
312 | + if (param == NULL) |
313 | + return -1; |
314 | + |
315 | + memset(param, 0, blen); |
316 | + param->cmd = ZD_CMD_SET_MLME; |
317 | + param->u.mlme.cmd = MLME_STA_DEAUTH; |
318 | + param->u.mlme.reason_code = reason_code; |
319 | + memcpy(param->sta_addr, addr, ETH_ALEN); |
320 | + ret = zydas_ioctl(ifname, param, blen, 1); |
321 | + usleep(100000); |
322 | + free(param); |
323 | + return ret; |
324 | +} |
325 | + |
326 | +static int |
327 | +wpa_driver_zydas_disassociate(const char *ifname, u8 *addr, int reason_code) |
328 | +{ |
329 | + struct zydas_wlan_param *param; |
330 | + int blen; |
331 | + int ret; |
332 | + |
333 | + blen = sizeof(*param); |
334 | + param = (struct zydas_wlan_param *) malloc(blen); |
335 | + if (param == NULL) |
336 | + return -1; |
337 | + |
338 | + memset(param, 0, blen); |
339 | + param->cmd = ZD_CMD_SET_MLME; |
340 | + param->u.mlme.cmd = MLME_STA_DISASSOC; |
341 | + param->u.mlme.reason_code = reason_code; |
342 | + memcpy(param->sta_addr, addr, ETH_ALEN); |
343 | + ret = zydas_ioctl(ifname, param, blen, 1); |
344 | + free(param); |
345 | + return ret; |
346 | +} |
347 | + |
348 | +static int |
349 | +wpa_driver_zydas_associate(const char *ifname, const char *bssid, |
350 | + const char *ssid, size_t ssid_len, |
351 | + int freq, |
352 | + const char *wpa_ie, size_t wpa_ie_len, |
353 | + wpa_cipher pairwise_suite, |
354 | + wpa_cipher group_suite, |
355 | + wpa_key_mgmt key_mgmt_suite) |
356 | +{ |
357 | + int ret = 0; |
358 | + |
359 | + wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); |
360 | + |
361 | + /* Because there might be the case, two or more APs with the same |
362 | + * SSID, in order to identify them, we need to set the BSSID. */ |
363 | + if (wpa_driver_zydas_set_wpa_ie(ifname, wpa_ie, wpa_ie_len) < 0) |
364 | + ret = -1; |
365 | + if (wpa_driver_wext_set_ssid(ifname, ssid, ssid_len) < 0) |
366 | + ret = -1; |
367 | + |
368 | + // Mark for test |
369 | + //if (wpa_driver_wext_set_bssid(ifname, bssid) < 0) |
370 | + // ret = -1; |
371 | + |
372 | +#if 0 |
373 | + /* Allow unencrypted EAPOL messages even if pairwise keys are set when |
374 | + * not using WPA. IEEE 802.1X specifies that these frames are not |
375 | + * encrypted, but WPA encrypts them when pairwise keys are in use. */ |
376 | + if (key_mgmt_suite == KEY_MGMT_802_1X || |
377 | + key_mgmt_suite == KEY_MGMT_PSK) |
378 | + allow_unencrypted_eapol = 0; |
379 | + else |
380 | + allow_unencrypted_eapol = 1; |
381 | + |
382 | + if (prism2param(ifname, PRISM2_PARAM_IEEE_802_1X, |
383 | + allow_unencrypted_eapol) < 0) { |
384 | + wpa_printf(MSG_DEBUG, "hostap: Failed to configure " |
385 | + "ieee_802_1x param"); |
386 | + /* Ignore this error.. driver_hostap.c can also be used with |
387 | + * other drivers that do not support this prism2_param. */ |
388 | + } |
389 | +#endif |
390 | + |
391 | + return ret; |
392 | +} |
393 | + |
394 | +static int |
395 | +wpa_driver_zydas_scan(const char *ifname, |
396 | + void *ctx, u8 *ssid, size_t ssid_len) |
397 | +{ |
398 | + struct zydas_wlan_param param; |
399 | + int ret; |
400 | + |
401 | + if (ssid == NULL) { |
402 | + /* Use standard Linux Wireless Extensions ioctl if possible |
403 | + * because some drivers using hostap code in wpa_supplicant |
404 | + * might not support Host AP specific scan request (with SSID |
405 | + * info). */ |
406 | + return wpa_driver_wext_scan(ifname, ctx, ssid, ssid_len); |
407 | + } |
408 | + |
409 | + if (ssid_len > 32) |
410 | + ssid_len = 32; |
411 | + |
412 | + memset(¶m, 0, sizeof(param)); |
413 | + param.cmd = ZD_CMD_SCAN_REQ; |
414 | + param.u.scan_req.ssid_len = ssid_len; |
415 | + memcpy(param.u.scan_req.ssid, ssid, ssid_len); |
416 | + ret = zydas_ioctl(ifname, ¶m, sizeof(param), 1); |
417 | + |
418 | + /* Not all drivers generate "scan completed" wireless event, so try to |
419 | + * read results after a timeout. */ |
420 | + eloop_register_timeout(3, 0, wpa_driver_wext_scan_timeout, NULL, ctx); |
421 | + |
422 | + return ret; |
423 | +} |
424 | + |
425 | +static int wpa_driver_zydas_set_auth_alg(const char *ifname, int auth_alg) |
426 | +{ |
427 | + int algs = 0; |
428 | + |
429 | + if (auth_alg & AUTH_ALG_OPEN_SYSTEM) |
430 | + algs = 0; |
431 | + if (auth_alg & AUTH_ALG_SHARED_KEY) |
432 | + algs = 1; |
433 | + |
434 | + return zydas_set_param(ifname, ZD_PARAM_AUTH_ALGS, algs, 1); |
435 | +} |
436 | + |
437 | +static void |
438 | +wpa_driver_zydas_cleanup(const char *ifname) |
439 | +{ |
440 | + int flags; |
441 | + |
442 | + /* NB: mark interface down */ |
443 | + if (getifflags(ifname, &flags) == 0) |
444 | + (void) setifflags(ifname, flags &~ IFF_UP); |
445 | +} |
446 | + |
447 | +struct wpa_driver_ops wpa_driver_zydas_ops = { |
448 | + .get_bssid = wpa_driver_wext_get_bssid, |
449 | + .get_ssid = wpa_driver_wext_get_ssid, |
450 | + .set_wpa = wpa_driver_zydas_set_wpa, |
451 | + .set_key = wpa_driver_zydas_set_key, |
452 | + .events_init = wpa_driver_wext_events_init, |
453 | + .events_deinit = wpa_driver_wext_events_deinit, |
454 | + .set_countermeasures = wpa_driver_zydas_set_countermeasures, |
455 | + .set_drop_unencrypted = wpa_driver_zydas_set_drop_unencrypted, |
456 | + .scan = wpa_driver_zydas_scan, |
457 | + .get_scan_results = wpa_driver_wext_get_scan_results, |
458 | + .deauthenticate = wpa_driver_zydas_deauthenticate, |
459 | + .disassociate = wpa_driver_zydas_disassociate, |
460 | + .associate = wpa_driver_zydas_associate, |
461 | + .set_auth_alg = wpa_driver_zydas_set_auth_alg, |
462 | + .cleanup = wpa_driver_zydas_cleanup, |
463 | +}; |
464 | + |
465 | diff -wBNur wpa_supplicant-0.2.4/zydas_common.h lnx_wpa_supplicant_1_2_0_0/zydas_common.h |
466 | --- wpa_supplicant-0.2.4/zydas_common.h 1970-01-01 01:00:00.000000000 +0100 |
467 | +++ lnx_wpa_supplicant_1_2_0_0/zydas_common.h 2005-08-01 11:14:37.000000000 +0200 |
468 | @@ -0,0 +1,65 @@ |
469 | +#ifndef ZYDAS_COMMON_H |
470 | +#define ZYDAS_COMMON_H |
471 | + |
472 | +#define ZD_IOCTL_WPA (SIOCDEVPRIVATE + 1) |
473 | +#define ZD_IOCTL_PARAM (SIOCDEVPRIVATE + 2) |
474 | + |
475 | +#define ZD_PARAM_ROAMING 0x0001 |
476 | +#define ZD_PARAM_PRIVACY 0x0002 |
477 | +#define ZD_PARAM_WPA 0x0003 |
478 | +#define ZD_PARAM_COUNTERMEASURES 0x0004 |
479 | +#define ZD_PARAM_DROPUNENCRYPTED 0x0005 |
480 | +#define ZD_PARAM_AUTH_ALGS 0x0006 |
481 | + |
482 | +#define ZD_CMD_SET_ENCRYPT_KEY 0x0001 |
483 | +#define ZD_CMD_SET_MLME 0x0002 |
484 | +#define ZD_CMD_SCAN_REQ 0x0003 |
485 | +#define ZD_CMD_SET_GENERIC_ELEMENT 0x0004 |
486 | + |
487 | +#define ZD_FLAG_SET_TX_KEY 0x0001 |
488 | + |
489 | +#define ZD_GENERIC_ELEMENT_HDR_LEN \ |
490 | +((int) (&((struct zydas_wlan_param *) 0)->u.generic_elem.data)) |
491 | + |
492 | +#define ZD_CRYPT_ALG_NAME_LEN 16 |
493 | +#define ZD_MAX_KEY_SIZE 32 |
494 | +#define ZD_MAX_GENERIC_SIZE 64 |
495 | + |
496 | +/* structure definition */ |
497 | + |
498 | +struct zydas_wlan_param { |
499 | + u32 cmd; |
500 | + u8 sta_addr[ETH_ALEN]; |
501 | + union { |
502 | + struct { |
503 | + u8 alg[ZD_CRYPT_ALG_NAME_LEN]; |
504 | + u32 flags; |
505 | + u32 err; |
506 | + u8 idx; |
507 | + u8 seq[8]; /* sequence counter (set: RX, get: TX) */ |
508 | + u16 key_len; |
509 | + u8 key[ZD_MAX_KEY_SIZE]; |
510 | + } crypt; |
511 | + struct { |
512 | + u32 flags_and; |
513 | + u32 flags_or; |
514 | + } set_flags_sta; |
515 | + struct { |
516 | + u8 len; |
517 | + u8 data[ZD_MAX_GENERIC_SIZE]; |
518 | + } generic_elem; |
519 | + struct { |
520 | +#define MLME_STA_DEAUTH 0 |
521 | +#define MLME_STA_DISASSOC 1 |
522 | + u16 cmd; |
523 | + u16 reason_code; |
524 | + } mlme; |
525 | + struct { |
526 | + u8 ssid_len; |
527 | + u8 ssid[32]; |
528 | + } scan_req; |
529 | + } u; |
530 | +}; |
531 | + |
532 | +#endif |
533 | + |