summaryrefslogtreecommitdiffstats
path: root/meta/packages/wpa-supplicant/wpa-supplicant-0.4.7/driver-hermes.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/packages/wpa-supplicant/wpa-supplicant-0.4.7/driver-hermes.patch')
-rw-r--r--meta/packages/wpa-supplicant/wpa-supplicant-0.4.7/driver-hermes.patch884
1 files changed, 884 insertions, 0 deletions
diff --git a/meta/packages/wpa-supplicant/wpa-supplicant-0.4.7/driver-hermes.patch b/meta/packages/wpa-supplicant/wpa-supplicant-0.4.7/driver-hermes.patch
new file mode 100644
index 0000000000..4044835e1c
--- /dev/null
+++ b/meta/packages/wpa-supplicant/wpa-supplicant-0.4.7/driver-hermes.patch
@@ -0,0 +1,884 @@
1--- /dev/null
2+++ wpa_supplicant-0.4.7/driver_hermes.c
3@@ -0,0 +1,705 @@
4+/*
5+ * WPA Supplicant - testing driver interface
6+ * Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.fi>
7+ *
8+ * This program is free software; you can redistribute it and/or modify
9+ * it under the terms of the GNU General Public License version 2 as
10+ * published by the Free Software Foundation.
11+ *
12+ * Alternatively, this software may be distributed under the terms of BSD
13+ * license.
14+ *
15+ * See README and COPYING for more details.
16+ */
17+
18+#include <stdlib.h>
19+#include <stdio.h>
20+#include <unistd.h>
21+#include <string.h>
22+#include <sys/ioctl.h>
23+#include <errno.h>
24+#include <net/if_arp.h>
25+
26+#include "wireless_copy.h"
27+#include "common.h"
28+#include "driver.h"
29+
30+#include "eloop.h"
31+#include "wpa_supplicant.h"
32+#include "priv_netlink.h"
33+
34+#include "hostap_common.h"
35+#include "driver_wext.h"
36+#include "driver_hermes.h"
37+
38+
39+
40+/* Enumeration for supported Hermes Types */
41+enum
42+{
43+ WL_HERMES_UNKNOWN = 0,
44+ WL_HERMES_1 = 1,
45+ WL_HERMES_2 = 2,
46+ WL_HERMES_25 = 3
47+};
48+
49+
50+
51+
52+struct wpa_driver_hermes_data {
53+ void *wext; /* private data for driver_wext */
54+ void *ctx;
55+ char ifname[IFNAMSIZ + 1];
56+ int sock;
57+ int type;
58+};
59+
60+
61+
62+/****************************************************************************/
63+/* */
64+/* Routines for basic device access to Agere Hermes-I/Hermes-II via the UIL */
65+/* */
66+/****************************************************************************/
67+
68+IFBP _connect(void *priv)
69+{
70+ struct wpa_driver_hermes_data *drv = priv;
71+ int result = 0;
72+ IFBP ifbp = NULL;
73+ struct uilreq urq;
74+
75+ //wpa_printf(MSG_DEBUG, "%s: %s %d", __FUNCTION__, drv->ifname, drv->sock);
76+
77+ memset(&urq, 0, sizeof(urq));
78+
79+ strcpy(urq.ifr_name, drv->ifname);
80+ urq.command = UIL_FUN_CONNECT;
81+
82+ result = ioctl(drv->sock, WVLAN2_IOCTL_UIL, &urq);
83+ if (result == 0 && urq.result == UIL_SUCCESS) {
84+ ifbp = urq.hcfCtx;
85+ } else {
86+ wpa_printf(MSG_DEBUG, "%s: could not set IFBP, result %d", __FUNCTION__, result);
87+ }
88+
89+ return ifbp;
90+}
91+
92+
93+void _disconnect(void *priv, IFBP ifbp)
94+{
95+ struct wpa_driver_hermes_data *drv = priv;
96+ int result = 0;
97+ struct uilreq urq;
98+
99+ //wpa_printf(MSG_DEBUG, "%s: %s", __FUNCTION__, drv->ifname);
100+
101+ if (ifbp != NULL) {
102+ memset(&urq, 0, sizeof(struct uilreq));
103+
104+ strcpy(urq.ifr_name, drv->ifname);
105+ urq.command = UIL_FUN_DISCONNECT;
106+ urq.hcfCtx = ifbp;
107+
108+ result = ioctl(drv->sock, WVLAN2_IOCTL_UIL, &urq);
109+
110+ if (result != 0 || urq.result != UIL_SUCCESS) {
111+ wpa_printf( MSG_WARNING, "wl_disconnect(): ioctl() failed, errno: %d", errno );
112+ wpa_printf( MSG_WARNING, "wl_disconnect(): urq.result: %d", urq.result );
113+ }
114+ } else {
115+ wpa_printf(MSG_WARNING, "wl_disconnect(): called with NULL ifbp");
116+ }
117+
118+ return;
119+}
120+
121+int _get_info(void *priv, ltv_t *ltv)
122+{
123+ struct wpa_driver_hermes_data *drv = priv;
124+ int result = 0;
125+ IFBP ifbp = NULL;
126+ struct uilreq urq;
127+
128+ //wpa_printf(MSG_DEBUG, "%s: %s", __FUNCTION__, drv->ifname);
129+
130+ /* First, connect to the device */
131+ ifbp = _connect(priv);
132+ if (ifbp != NULL && ltv != NULL) {
133+ memset(&urq, 0, sizeof(struct uilreq));
134+
135+ strcpy(urq.ifr_name, drv->ifname);
136+ urq.hcfCtx = ifbp;
137+ urq.command = UIL_FUN_GET_INFO;
138+ urq.len = sizeof(ltv_t);
139+ urq.data = ltv;
140+
141+ result = ioctl(drv->sock, WVLAN2_IOCTL_UIL, &urq);
142+
143+ if (result != 0 || urq.result != UIL_SUCCESS) {
144+ wpa_printf(MSG_WARNING, "wl_disconnect(): ioctl() failed, errno: %d", errno);
145+ wpa_printf(MSG_WARNING, "wl_disconnect(): urq.result: %d", urq.result);
146+ }
147+ _disconnect(priv, ifbp);
148+ } else {
149+ wpa_printf( MSG_WARNING, "Could not connect to the device, or LTV NULL");
150+ result = -1;
151+ }
152+
153+ return result;
154+}
155+
156+int _put_info(void *priv, ltv_t *ltv)
157+{
158+ struct wpa_driver_hermes_data *drv = priv;
159+ int result = 0;
160+ IFBP ifbp = NULL;
161+ struct uilreq urq;
162+
163+ //wpa_printf(MSG_DEBUG, "%s: %s", __FUNCTION__, drv->ifname);
164+
165+ /* First, connect to the device */
166+ ifbp = _connect(priv);
167+ if (ifbp != NULL && ltv != NULL) {
168+ memset(&urq, 0, sizeof(struct uilreq));
169+
170+ strcpy(urq.ifr_name, drv->ifname);
171+ urq.hcfCtx = ifbp;
172+ urq.command = UIL_FUN_PUT_INFO;
173+ urq.len = sizeof( ltv_t );
174+ urq.data = ltv;
175+
176+ result = ioctl(drv->sock, WVLAN2_IOCTL_UIL, &urq);
177+
178+ if (result != 0 || urq.result != UIL_SUCCESS) {
179+ wpa_printf(MSG_WARNING, "_put_info(): ioctl() failed, errno: %d", errno);
180+ wpa_printf(MSG_WARNING, "_put_info(): urq.result: %d", urq.result);
181+ }
182+
183+ _disconnect(priv, ifbp);
184+ } else {
185+ wpa_printf(MSG_WARNING, "%s: could not connect to the device, or LTV NULL", __FUNCTION__ );
186+ result = -1;
187+ }
188+
189+ return result;
190+}
191+
192+
193+static void _detect_hermes_type(void *priv)
194+{
195+ struct wpa_driver_hermes_data *drv = priv;
196+ CFG_FW_IDENTITY_STRCT *fw_id;
197+ ltv_t ltv;
198+ int result;
199+
200+ //wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
201+
202+ drv->type = WL_HERMES_UNKNOWN;
203+
204+ if (drv->sock >= 0) {
205+ fw_id = (CFG_FW_IDENTITY_STRCT *)&ltv;
206+ fw_id->len = ( sizeof(CFG_FW_IDENTITY_STRCT) / sizeof( hcf_16 )) - 1;
207+ fw_id->typ = CFG_FW_IDENTITY;
208+
209+ result = _get_info(priv, (ltv_t *)fw_id);
210+ if (result == HCF_SUCCESS) {
211+ //wpa_printf(MSG_DEBUG, "PRI CompID : %d", fw_id->comp_id);
212+ //wpa_printf(MSG_DEBUG, "PRI Variant : %d", fw_id->variant);
213+ //wpa_printf(MSG_DEBUG, "PRI Version : %d.%02d", fw_id->version_major, fw_id->version_minor);
214+
215+ switch(fw_id->comp_id) {
216+ case COMP_ID_FW_STA:
217+ switch (fw_id->variant) {
218+ case 1:
219+ case 2:
220+ wpa_printf(MSG_DEBUG, "found Hermes 1 STA");
221+ drv->type = WL_HERMES_1;
222+ break;
223+
224+ case 3:
225+ wpa_printf(MSG_DEBUG, "found Hermes 2 STA");
226+ drv->type = WL_HERMES_2;
227+ break;
228+ case 4:
229+ wpa_printf(MSG_DEBUG, "found Hermes 2.5 STA");
230+ drv->type = WL_HERMES_25;
231+ break;
232+ }
233+ break;
234+
235+ case COMP_ID_FW_AP:
236+ switch (fw_id->variant) {
237+ case 1:
238+ wpa_printf(MSG_DEBUG, "found Hermes 1 AP");
239+ drv->type = WL_HERMES_1;
240+ break;
241+
242+ case 2:
243+ wpa_printf(MSG_DEBUG, "found Hermes 2 AP" );
244+ drv->type = WL_HERMES_2;
245+ break;
246+ }
247+ break;
248+
249+ default:
250+ wpa_printf(MSG_WARNING, "could not detect Hermes type!");
251+ break;
252+ }
253+ }
254+ }
255+}
256+
257+
258+
259+/****************************************************************************/
260+
261+
262+static int wpa_driver_hermes_set_wpa_ie(void *priv, const char *wpa_ie,
263+ size_t wpa_ie_len)
264+{
265+ struct wpa_driver_hermes_data *drv = priv;
266+ ltv_t ltv;
267+
268+ wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
269+
270+ ltv.len = 2;
271+ ltv.typ = CFG_SET_WPA_AUTH_KEY_MGMT_SUITE;
272+
273+ switch(drv->type) {
274+ case WL_HERMES_1:
275+ ltv.u.u16[0] = 2;
276+ break;
277+
278+ case WL_HERMES_2:
279+ case WL_HERMES_25:
280+ ltv.u.u16[0] = 4;
281+ break;
282+
283+ default:
284+ ltv.u.u16[0] = 0;
285+ break;
286+ }
287+
288+ return _put_info(priv, &ltv);
289+}
290+
291+
292+static int wpa_driver_hermes_set_wpa(void *priv, int enabled)
293+{
294+ ltv_t ltv;
295+
296+ wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
297+
298+ ltv.len = 2;
299+ ltv.typ = CFG_CNF_ENCRYPTION;
300+ ltv.u.u16[0] = enabled ? 2 : 0; /* Setting CFG_CNF_ENCRYPTION to 2 sets WPA: TKIP or better */
301+
302+ return _put_info(priv, &ltv);
303+}
304+
305+
306+static int wpa_driver_hermes_set_key(void *priv, wpa_alg alg,
307+ const u8 *addr, int key_idx,
308+ int set_tx, const u8 *seq, size_t seq_len,
309+ const u8 *key, size_t key_len)
310+{
311+ struct wpa_driver_hermes_data *drv = priv;
312+ int ret = 0;
313+ char *alg_name;
314+ ltv_t ltv;
315+ int count = 0;
316+ int buf_idx = 0;
317+ hcf_8 tsc[] = { 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00 };
318+ hcf_8 rsc[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
319+
320+
321+ switch (alg) {
322+ case WPA_ALG_NONE:
323+ alg_name = "none";
324+ break;
325+ case WPA_ALG_WEP:
326+ alg_name = "WEP";
327+ break;
328+ case WPA_ALG_TKIP:
329+ alg_name = "TKIP";
330+ break;
331+ case WPA_ALG_CCMP:
332+ alg_name = "CCMP";
333+ break;
334+ default:
335+ return -1;
336+ }
337+
338+ wpa_printf(MSG_DEBUG, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%d "
339+ "key_len=%d", __FUNCTION__, alg_name, key_idx, set_tx,
340+ seq_len, key_len);
341+
342+ if (seq_len > IW_ENCODE_SEQ_MAX_SIZE) {
343+ wpa_printf(MSG_DEBUG, "%s: Invalid seq_len %lu", __FUNCTION__, (unsigned long) seq_len);
344+ return -2;
345+ }
346+
347+ /* Check the key index here; if 0, load as Pairwise Key, otherwise, load as
348+ a group key. Note that for the Hermes, the RIDs for group/pairwise keys
349+ are different from each other and different than the default WEP keys as
350+ well. */
351+ switch (alg) {
352+ case WPA_ALG_TKIP:
353+ /* Make sure that there is no data queued up in the firmware before
354+ setting the TKIP keys. If this check is not performed, some data
355+ may be sent out with incorrect MIC and cause synchronizarion
356+ errors with the AP */
357+ /* Check every 1ms for 100ms */
358+ for (count = 0; count < 100; count++) {
359+ usleep(1000);
360+
361+ ltv.len = 2;
362+ ltv.typ = 0xFD91; // This RID not defined in HCF yet!!!
363+ ltv.u.u16[0] = 0;
364+
365+ _get_info( priv, &ltv);
366+
367+ if (ltv.u.u16[0] == 0)
368+ break;
369+ }
370+
371+ if (count == 100)
372+ wpa_printf(MSG_DEBUG, "%s: Timed out waiting for TxQ!", __FUNCTION__);
373+
374+
375+ switch (key_idx) {
376+ case 0:
377+ /* Only load key as pairwise key for Hermes-II and II.5. For Hermes-I,
378+ fall through to the next case and load the pairwise key as
379+ a Group Key at index 0. */
380+ if (drv->type == WL_HERMES_2 || drv->type == WL_HERMES_25) {
381+ ltv.len = 28;
382+ ltv.typ = CFG_ADD_TKIP_MAPPED_KEY;
383+
384+ /* Load the BSSID */
385+ memcpy(&ltv.u.u8[buf_idx], addr, ETH_ALEN);
386+ buf_idx += ETH_ALEN;
387+
388+ /* Load the TKIP key */
389+ memcpy(&ltv.u.u8[buf_idx], &key[0], 16);
390+ buf_idx += 16;
391+
392+ /* Load the TSC */
393+ memcpy(&ltv.u.u8[buf_idx], tsc, 8);
394+ buf_idx += 8;
395+
396+ /* Load the RSC */
397+ /* Copy the RSC from the supplicant to a local buffer, because
398+ the RSC doesn't always contain the padding needed */
399+ memcpy(rsc, seq, seq_len);
400+ memcpy(&ltv.u.u8[buf_idx], rsc, 8);
401+ buf_idx += 8;
402+
403+ /* Load the TxMIC key */
404+ memcpy(&ltv.u.u8[buf_idx], &key[16], 8);
405+ buf_idx += 8;
406+
407+ /* Load the RxMIC key */
408+ memcpy(&ltv.u.u8[buf_idx], &key[24], 8);
409+
410+ /* Send the request to the Hermes */
411+ _put_info(priv, &ltv);
412+ break;
413+ }
414+
415+ case 1:
416+ case 2:
417+ case 3:
418+ ltv.len = 26;
419+ ltv.typ = CFG_ADD_TKIP_DEFAULT_KEY;
420+
421+ /* Load the key Index */
422+ ltv.u.u16[buf_idx] = key_idx;
423+
424+ /* If this is a Tx Key, set bit 8000 */
425+ if (set_tx)
426+ ltv.u.u16[buf_idx] |= 0x8000;
427+
428+ buf_idx += 2;
429+
430+ /* Load the RSC */
431+ /* Copy the RSC from the supplicant to a local buffer, because
432+ the RSC doesn't always contain the padding needed */
433+ memcpy(rsc, seq, seq_len);
434+ memcpy(&ltv.u.u8[buf_idx], rsc, 8);
435+ buf_idx += 8;
436+
437+ /* Load the TKIP, TxMIC, and RxMIC keys in one shot, because in
438+ CFG_ADD_TKIP_DEFAULT_KEY they are back-to-back */
439+ memcpy(&ltv.u.u8[buf_idx], key, key_len);
440+ buf_idx += key_len;
441+
442+ /* Load the TSC */
443+ memcpy(&ltv.u.u8[buf_idx], tsc, 8);
444+
445+ /* Send the request to the Hermes */
446+ _put_info(priv, &ltv);
447+ break;
448+
449+ default:
450+ break;
451+ }
452+
453+ break;
454+
455+ case WPA_ALG_WEP:
456+ case WPA_ALG_CCMP:
457+ break;
458+
459+ case WPA_ALG_NONE:
460+ switch (key_idx) {
461+ case 0:
462+ if (drv->type == WL_HERMES_2 || drv->type == WL_HERMES_25) {
463+ /* Only clear a pairwise key for Hermes-II. For Hermes-I,
464+ fall through to the next case and clear the key as a
465+ Group Key at index 0. */
466+ if (addr) {
467+ ltv.len = 7;
468+ ltv.typ = CFG_REMOVE_TKIP_MAPPED_KEY;
469+
470+ memcpy(&ltv.u.u8[0], addr, ETH_ALEN);
471+
472+ _put_info(priv, &ltv);
473+ }
474+ break;
475+ }
476+
477+ case 1:
478+ case 2:
479+ case 3:
480+ /* Clear the Group TKIP keys by index */
481+ ltv.len = 2;
482+ ltv.typ = CFG_REMOVE_TKIP_DEFAULT_KEY;
483+
484+ ltv.u.u16[0] = key_idx;
485+
486+ _put_info(priv, &ltv);
487+ break;
488+
489+ default:
490+ break;
491+ }
492+ break;
493+
494+ default:
495+ break;
496+ }
497+
498+ return ret;
499+}
500+
501+
502+static int wpa_driver_hermes_set_countermeasures(void *priv, int enabled)
503+{
504+ ltv_t ltv;
505+
506+ /* The supplicant handles all the timers related to MIC failure and
507+ countermeasures. When countermeasures are enabled, shut down the card;
508+ when disable, re-enable the card. Make sure that the EAPOL message
509+ is getting out before card disable */
510+
511+ wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
512+
513+ ltv.len = 2;
514+ ltv.typ = CFG_DRIVER_ENABLE;
515+ ltv.u.u16[0] = enabled ? 0 : 1;
516+
517+ return _put_info(priv, &ltv);
518+}
519+
520+
521+static int wpa_driver_hermes_set_drop_unencrypted(void *priv, int enabled)
522+{
523+ ltv_t ltv;
524+
525+ wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
526+
527+ ltv.len = 2;
528+ ltv.typ = CFG_CNF_EXCL_UNENCRYPTED;
529+ ltv.u.u16[0] = enabled;
530+
531+ return _put_info(priv, &ltv);
532+}
533+
534+
535+static int wpa_driver_hermes_deauthenticate(void *priv, const u8 *addr,
536+ int reason_code)
537+{
538+ wpa_printf(MSG_DEBUG, "%s: *DUMMY* %d", __FUNCTION__, reason_code);
539+
540+ return 0;
541+}
542+
543+
544+static int wpa_driver_hermes_disassociate(void *priv, const u8 *addr, int reason_code)
545+{
546+ ltv_t ltv;
547+
548+ wpa_printf(MSG_DEBUG, "%s: reason=%d", __FUNCTION__, reason_code);
549+
550+ ltv.len = 2;
551+ ltv.typ = 0xFCC8; // This RID not defined in HCF yet!!!
552+ memcpy( &ltv.u.u8[0], addr, ETH_ALEN );
553+ ltv.u.u16[ETH_ALEN / 2] = reason_code;
554+
555+ return _put_info( priv, &ltv);
556+}
557+
558+
559+static int wpa_driver_hermes_associate(
560+ void *priv, struct wpa_driver_associate_params *params)
561+{
562+ struct wpa_driver_hermes_data *drv = priv;
563+
564+#if 0
565+ wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
566+#else
567+ wpa_printf(MSG_DEBUG, "%s: priv=%p freq=%d pairwise_suite=%d "
568+ "group_suite=%d key_mgmt_suite=%d auth_alg=%d mode=%d",
569+ __func__, priv, params->freq, params->pairwise_suite,
570+ params->group_suite, params->key_mgmt_suite,
571+ params->auth_alg, params->mode);
572+ if (params->bssid) {
573+ wpa_printf(MSG_DEBUG, " bssid=" MACSTR,
574+ MAC2STR(params->bssid));
575+ }
576+ if (params->ssid) {
577+ wpa_hexdump_ascii(MSG_DEBUG, " ssid",
578+ params->ssid, params->ssid_len);
579+ }
580+ if (params->wpa_ie) {
581+ wpa_hexdump(MSG_DEBUG, " wpa_ie",
582+ params->wpa_ie, params->wpa_ie_len);
583+ }
584+#endif
585+
586+ if (wpa_driver_hermes_set_wpa_ie(priv, params->wpa_ie, params->wpa_ie_len) < 0)
587+ return -1;
588+ if (wpa_driver_wext_set_freq(drv->wext, params->freq) < 0)
589+ return -1;
590+ if (wpa_driver_wext_set_ssid(drv->wext, params->ssid, params->ssid_len) < 0)
591+ return -1;
592+#ifdef UNSUPPORTED_IN_HERMES_DRIVER
593+ if (wpa_driver_wext_hermes_bssid(drv->wext, params->bssid) < 0)
594+ return -1;
595+#endif
596+
597+ return 0;
598+}
599+
600+
601+static int wpa_driver_hermes_get_bssid(void *priv, u8 *bssid)
602+{
603+ struct wpa_driver_hermes_data *drv = priv;
604+ return wpa_driver_wext_get_bssid(drv->wext, bssid);
605+}
606+
607+
608+static int wpa_driver_hermes_get_ssid(void *priv, u8 *ssid)
609+{
610+ struct wpa_driver_hermes_data *drv = priv;
611+ return wpa_driver_wext_get_ssid(drv->wext, ssid);
612+}
613+
614+
615+static int wpa_driver_hermes_scan(void *priv, const u8 *ssid, size_t ssid_len)
616+{
617+ struct wpa_driver_hermes_data *drv = priv;
618+ return wpa_driver_wext_scan(drv->wext, ssid, ssid_len);
619+}
620+
621+
622+static int wpa_driver_hermes_get_scan_results(void *priv,
623+ struct wpa_scan_result *results,
624+ size_t max_size)
625+{
626+ struct wpa_driver_hermes_data *drv = priv;
627+ return wpa_driver_wext_get_scan_results(drv->wext, results, max_size);
628+}
629+
630+
631+static void * wpa_driver_hermes_init(void *ctx, const char *ifname)
632+{
633+ struct wpa_driver_hermes_data *drv;
634+
635+ wpa_printf(MSG_DEBUG, "%s: %s", __FUNCTION__, ifname);
636+
637+ drv = malloc(sizeof(*drv));
638+ if (drv == NULL)
639+ return NULL;
640+ memset(drv, 0, sizeof(*drv));
641+
642+ /* Initialize wireless context */
643+ drv->wext = wpa_driver_wext_init(ctx, ifname);
644+ if (drv->wext == NULL) {
645+ perror("no wext context");
646+ goto no_wext;
647+ }
648+
649+ drv->ctx = ctx;
650+ strncpy(drv->ifname, ifname, sizeof(drv->ifname));
651+
652+ drv->sock = socket(PF_INET, SOCK_DGRAM, 0);
653+ if (drv->sock < 0) {
654+ perror("socket(PF_INET,SOCK_DGRAM)");
655+ goto no_sock;
656+ }
657+
658+ _detect_hermes_type(drv);
659+
660+ return drv;
661+
662+no_sock:
663+ wpa_driver_wext_deinit(drv->wext);
664+no_wext:
665+ free(drv);
666+ return NULL;
667+}
668+
669+
670+static void wpa_driver_hermes_deinit(void *priv)
671+{
672+ struct wpa_driver_hermes_data *drv = priv;
673+ wpa_driver_wext_deinit(drv->wext);
674+ close(drv->sock);
675+ free(drv);
676+}
677+
678+
679+
680+
681+struct wpa_driver_ops wpa_driver_hermes_ops = {
682+ .name = "hermes",
683+ .desc = "wpa_supplicant hermes driver",
684+
685+ .init = wpa_driver_hermes_init,
686+ .deinit = wpa_driver_hermes_deinit,
687+
688+ // from old driver_hermes.c:
689+ .get_bssid = wpa_driver_hermes_get_bssid,
690+ .get_ssid = wpa_driver_hermes_get_ssid,
691+ .set_wpa = wpa_driver_hermes_set_wpa,
692+ .set_key = wpa_driver_hermes_set_key,
693+ //.events_init = wpa_driver_wext_events_init,
694+ //.events_deinit = wpa_driver_wext_events_deinit,
695+ .set_countermeasures = wpa_driver_hermes_set_countermeasures,
696+ .set_drop_unencrypted = wpa_driver_hermes_set_drop_unencrypted,
697+ .scan = wpa_driver_hermes_scan,
698+ .get_scan_results = wpa_driver_hermes_get_scan_results,
699+ .deauthenticate = wpa_driver_hermes_deauthenticate,
700+ .disassociate = wpa_driver_hermes_disassociate,
701+ .associate = wpa_driver_hermes_associate,
702+
703+
704+#if 0
705+ /* Not possible with current Hermes driver:
706+ .set_auth_alg = wpa_driver_hermes_set_auth_alg, */
707+#endif
708+};
709--- /dev/null
710+++ wpa_supplicant-0.4.7/driver_hermes.h
711@@ -0,0 +1,173 @@
712+#ifndef HERMES_DRIVER_H
713+#define HERMES_DRIVER_H
714+
715+typedef unsigned char hcf_8;
716+typedef unsigned short hcf_16;
717+typedef unsigned long hcf_32;
718+typedef hcf_16 hcf_io;
719+typedef hcf_8 *wci_bufp;
720+
721+typedef struct {
722+ hcf_16 len;
723+ hcf_16 typ;
724+ unsigned short * bufp;
725+} RID_LOG_STRCT;
726+typedef RID_LOG_STRCT *RID_LOGP;
727+
728+typedef struct {
729+ hcf_16 len;
730+ hcf_16 typ;
731+ hcf_16 comp_id;
732+ hcf_16 variant;
733+ hcf_16 version_major;
734+ hcf_16 version_minor;
735+} CFG_FW_IDENTITY_STRCT;
736+
737+typedef struct {
738+ hcf_32 TxUnicastFrames;
739+ hcf_32 TxMulticastFrames;
740+ hcf_32 TxFragments;
741+ hcf_32 TxUnicastOctets;
742+ hcf_32 TxMulticastOctets;
743+ hcf_32 TxDeferredTransmissions;
744+ hcf_32 TxSingleRetryFrames;
745+ hcf_32 TxMultipleRetryFrames;
746+ hcf_32 TxRetryLimitExceeded;
747+ hcf_32 TxDiscards;
748+ hcf_32 RxUnicastFrames;
749+ hcf_32 RxMulticastFrames;
750+ hcf_32 RxFragments;
751+ hcf_32 RxUnicastOctets;
752+ hcf_32 RxMulticastOctets;
753+ hcf_32 RxFCSErrors;
754+ hcf_32 RxDiscardsNoBuffer;
755+ hcf_32 TxDiscardsWrongSA;
756+ hcf_32 RxWEPUndecryptable;
757+ hcf_32 RxMsgInMsgFragments;
758+ hcf_32 RxMsgInBadMsgFragments;
759+ hcf_32 RxDiscardsWEPICVError;
760+ hcf_32 RxDiscardsWEPExcluded;
761+} CFG_HERMES_TALLIES_STRCT;
762+
763+typedef struct {
764+ hcf_32 not_used_NoBufInq;
765+ hcf_32 NoBufInfo;
766+ hcf_32 NoBufMB;
767+ hcf_32 MiscErr;
768+ hcf_32 EngCnt;
769+} CFG_HCF_TALLIES_STRCT;
770+
771+typedef struct {
772+ hcf_io IFB_IOBase;
773+ hcf_16 IFB_IORange;
774+
775+ hcf_32 IFB_TickIni;
776+
777+ hcf_16 IFB_Version;
778+ hcf_16 IFB_CardStat;
779+ hcf_16 IFB_TraceLvl;
780+ hcf_16 *IFB_MBp;
781+ hcf_16 IFB_MBSize;
782+ hcf_16 IFB_MBWp;
783+ hcf_16 IFB_MBRp;
784+ hcf_16 IFB_MBInfoLen;
785+
786+ hcf_16 IFB_DLMode;
787+ hcf_16 IFB_Magic;
788+ hcf_16 IFB_Cmd;
789+ hcf_16 IFB_RxFID;
790+ RID_LOGP IFB_RIDLogp;
791+ hcf_16 IFB_Monitor;
792+ hcf_16 IFB_TxFid;
793+ hcf_16 IFB_RxLen;
794+ hcf_16 IFB_DefunctStat;
795+
796+ hcf_16 IFB_ErrCmd;
797+ hcf_16 IFB_ErrQualifier;
798+ hcf_16 IFB_lal;
799+ wci_bufp IFB_lap;
800+ hcf_16 IFB_LinkStat;
801+
802+ void (*IFB_MICRxRtn)( hcf_32*, hcf_32 );
803+ void (*IFB_MICTxRtn)( hcf_32*, hcf_32 );
804+ hcf_16 IFB_rx_tlen;
805+ hcf_16 IFB_tx_tlen;
806+ hcf_8 IFB_rx_32[4];
807+ hcf_8 IFB_tx_32[4];
808+ hcf_16 IFB_RscInd;
809+ hcf_16 IFB_MB_FID;
810+ hcf_16 IFB_DLTarget[2];
811+
812+ hcf_16 IFB_DLPage;
813+ hcf_16 IFB_DLOffset;
814+ hcf_16 IFB_DLLen;
815+
816+ hcf_16 volatile IFB_IntOffCnt;
817+ hcf_16 IFB_IntEnMask;
818+
819+ CFG_FW_IDENTITY_STRCT IFB_FWIdentity;
820+ hcf_16 IFB_Tally;
821+ hcf_16 IFB_TallyTyp;
822+
823+ CFG_HERMES_TALLIES_STRCT IFB_NIC_Tallies;
824+ CFG_HCF_TALLIES_STRCT IFB_HCF_Tallies;
825+
826+ void *IFB_MSFSup;
827+} IFB_STRCT;
828+
829+typedef IFB_STRCT* IFBP;
830+
831+struct uilreq
832+{
833+ union
834+ {
835+ char ifrn_name[16];
836+ } ifr_ifrn;
837+
838+ IFBP hcfCtx;
839+ __u8 command;
840+ __u8 result;
841+ __u16 len;
842+ void *data;
843+};
844+
845+typedef struct
846+{
847+ hcf_16 len;
848+ hcf_16 typ;
849+ union
850+ {
851+ hcf_8 u8[(512 - (sizeof(hcf_16) * 2)) / sizeof(hcf_8)];
852+ hcf_16 u16[(512 - (sizeof(hcf_16) * 2)) / sizeof(hcf_16)];
853+ hcf_32 u32[(512 - (sizeof(hcf_16) * 2)) / sizeof(hcf_32)];
854+ } u;
855+} ltv_t;
856+
857+
858+#define UIL_FUN_CONNECT 0x00
859+#define UIL_FUN_DISCONNECT 0x01
860+#define UIL_FUN_GET_INFO 0x04
861+#define UIL_FUN_PUT_INFO 0x05
862+
863+#define GENERIC_INFO_ELEM 0xdd
864+#define RSN_INFO_ELEM 0x30
865+
866+#define CFG_DRIVER_ENABLE 0x0902
867+#define CFG_CNF_ENCRYPTION 0xFC20
868+#define CFG_ADD_TKIP_DEFAULT_KEY 0xFCB4
869+#define CFG_SET_WPA_AUTH_KEY_MGMT_SUITE 0xFCB5
870+#define CFG_REMOVE_TKIP_DEFAULT_KEY 0xFCB6
871+#define CFG_ADD_TKIP_MAPPED_KEY 0xFCB7
872+#define CFG_REMOVE_TKIP_MAPPED_KEY 0xFCB8
873+#define CFG_FW_IDENTITY 0xFD20
874+#define CFG_CNF_EXCL_UNENCRYPTED 0xFC22
875+
876+#define HCF_SUCCESS 0x00
877+#define UIL_SUCCESS 0x00
878+
879+#define COMP_ID_FW_STA 31
880+#define COMP_ID_FW_AP 32
881+
882+#define WVLAN2_IOCTL_UIL SIOCDEVPRIVATE
883+
884+#endif