Magellan Linux

Contents of /trunk/wpa_supplicant/wpa_supplicant-0.4.4-zydas-support.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 39 - (show annotations) (download)
Mon Oct 10 18:18:26 2005 UTC (18 years, 6 months ago) by niro
File size: 14074 byte(s)
files for wpa-support

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(&param, 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, &param, 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 +