remove @EAP_LDFLAGS@, no longer exists
[mech_eap.orig] / libeap / src / drivers / driver_ralink.c
1 /*
2  * WPA Supplicant - driver interaction with Ralink Wireless Client
3  * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi>
4  * Copyright (c) 2007, Snowpin Lee <snowpin_lee@ralinktech.com.tw>
5  *
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.
9  *
10  * Alternatively, this software may be distributed under the terms of BSD
11  * license.
12  *
13  * See README and COPYING for more details.
14  *
15  */
16
17 #include "includes.h"
18 #include <sys/ioctl.h>
19
20 #include "wireless_copy.h"
21 #include "common.h"
22 #include "driver.h"
23 #include "l2_packet/l2_packet.h"
24 #include "eloop.h"
25 #include "common/ieee802_11_defs.h"
26 #include "priv_netlink.h"
27 #include "netlink.h"
28 #include "linux_ioctl.h"
29 #include "driver_ralink.h"
30
31 static void wpa_driver_ralink_scan_timeout(void *eloop_ctx, void *timeout_ctx);
32
33 #define MAX_SSID_LEN 32
34
35 struct wpa_driver_ralink_data {
36         void *ctx;
37         int ioctl_sock;
38         struct netlink_data *netlink;
39         char ifname[IFNAMSIZ + 1];
40         u8 *assoc_req_ies;
41         size_t assoc_req_ies_len;
42         u8 *assoc_resp_ies;
43         size_t assoc_resp_ies_len;
44         int no_of_pmkid;
45         struct ndis_pmkid_entry *pmkid;
46         int we_version_compiled;
47         int ap_scan;
48         int scanning_done;
49         u8 g_driver_down;
50         BOOLEAN bAddWepKey;
51 };
52
53 static int ralink_set_oid(struct wpa_driver_ralink_data *drv,
54                           unsigned short oid, char *data, int len)
55 {
56         char *buf;
57         struct iwreq iwr;
58
59         buf = os_zalloc(len);
60         if (buf == NULL)
61                 return -1;
62         os_memset(&iwr, 0, sizeof(iwr));
63         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
64         iwr.u.data.flags = oid;
65         iwr.u.data.flags |= OID_GET_SET_TOGGLE;
66
67         if (data)
68                 os_memcpy(buf, data, len);
69
70         iwr.u.data.pointer = (caddr_t) buf;
71         iwr.u.data.length = len;
72
73         if (ioctl(drv->ioctl_sock, RT_PRIV_IOCTL, &iwr) < 0) {
74                 wpa_printf(MSG_DEBUG, "%s: oid=0x%x len (%d) failed",
75                            __func__, oid, len);
76                 os_free(buf);
77                 return -1;
78         }
79         os_free(buf);
80         return 0;
81 }
82
83 static int
84 ralink_get_new_driver_flag(struct wpa_driver_ralink_data *drv)
85 {
86         struct iwreq iwr;
87         UCHAR enabled = 0;
88
89         os_memset(&iwr, 0, sizeof(iwr));
90         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
91         iwr.u.data.pointer = (UCHAR*) &enabled;
92         iwr.u.data.flags = RT_OID_NEW_DRIVER;
93
94         if (ioctl(drv->ioctl_sock, RT_PRIV_IOCTL, &iwr) < 0) {
95                 wpa_printf(MSG_DEBUG, "%s: failed", __func__);
96                 return 0;
97         }
98
99         return (enabled == 1) ? 1 : 0;
100 }
101
102 static int wpa_driver_ralink_get_bssid(void *priv, u8 *bssid)
103 {
104         struct wpa_driver_ralink_data *drv = priv;
105         struct iwreq iwr;
106         int ret = 0;
107
108         if (drv->g_driver_down == 1)
109                 return -1;
110
111         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
112
113         os_memset(&iwr, 0, sizeof(iwr));
114         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
115
116         if (ioctl(drv->ioctl_sock, SIOCGIWAP, &iwr) < 0) {
117                 perror("ioctl[SIOCGIWAP]");
118                 ret = -1;
119         }
120         os_memcpy(bssid, iwr.u.ap_addr.sa_data, ETH_ALEN);
121
122         return ret;
123 }
124
125 static int wpa_driver_ralink_get_ssid(void *priv, u8 *ssid)
126 {
127         struct wpa_driver_ralink_data *drv = priv;
128 #if 0
129         struct wpa_supplicant *wpa_s = drv->ctx;
130         struct wpa_ssid *entry;
131 #endif
132         int ssid_len;
133         u8 bssid[ETH_ALEN];
134         u8 ssid_str[MAX_SSID_LEN];
135         struct iwreq iwr;
136 #if 0
137         int result = 0;
138 #endif
139         int ret = 0;
140 #if 0
141         BOOLEAN ieee8021x_mode = FALSE;
142         BOOLEAN ieee8021x_required_key = FALSE;
143 #endif
144
145         if (drv->g_driver_down == 1)
146                 return -1;
147
148         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
149
150         os_memset(&iwr, 0, sizeof(iwr));
151         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
152         iwr.u.essid.pointer = (caddr_t) ssid;
153         iwr.u.essid.length = 32;
154
155         if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) {
156                 perror("ioctl[SIOCGIWESSID]");
157                 ret = -1;
158         } else
159                 ret = iwr.u.essid.length;
160
161         if (ret <= 0)
162                 return ret;
163
164         ssid_len = ret;
165         os_memset(ssid_str, 0, MAX_SSID_LEN);
166         os_memcpy(ssid_str, ssid, ssid_len);
167
168         if (drv->ap_scan == 0) {
169                 /* Read BSSID form driver */
170                 if (wpa_driver_ralink_get_bssid(priv, bssid) < 0) {
171                         wpa_printf(MSG_WARNING, "Could not read BSSID from "
172                                    "driver.");
173                         return ret;
174                 }
175
176 #if 0
177                 entry = wpa_s->conf->ssid;
178                 while (entry) {
179                         if (!entry->disabled && ssid_len == entry->ssid_len &&
180                             os_memcmp(ssid_str, entry->ssid, ssid_len) == 0 &&
181                             (!entry->bssid_set ||
182                              os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)) {
183                                 /* match the config of driver */
184                                 result = 1;
185                                 break;
186                         }
187                         entry = entry->next;
188                 }
189
190                 if (result) {
191                         wpa_printf(MSG_DEBUG, "Ready to set 802.1x mode and "
192                                    "ieee_required_keys parameters to driver");
193
194                         /* set 802.1x mode and ieee_required_keys parameter */
195                         if (entry->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
196                                 if ((entry->eapol_flags & (EAPOL_FLAG_REQUIRE_KEY_UNICAST | EAPOL_FLAG_REQUIRE_KEY_BROADCAST)))
197                                                 ieee8021x_required_key = TRUE;
198                                 ieee8021x_mode = TRUE;
199                         }
200
201                         if (ralink_set_oid(drv, OID_802_11_SET_IEEE8021X, (char *) &ieee8021x_mode, sizeof(BOOLEAN)) < 0)
202                         {
203                                 wpa_printf(MSG_DEBUG, "RALINK: Failed to set OID_802_11_SET_IEEE8021X(%d)", (int) ieee8021x_mode);
204                         }
205                         else
206                         {
207                                 wpa_printf(MSG_DEBUG, "ieee8021x_mode is %s", ieee8021x_mode ? "TRUE" : "FALSE");
208                         }
209
210                         if (ralink_set_oid(drv, OID_802_11_SET_IEEE8021X_REQUIRE_KEY, (char *) &ieee8021x_required_key, sizeof(BOOLEAN)) < 0)
211                         {
212                                 wpa_printf(MSG_DEBUG, "ERROR: Failed to set OID_802_11_SET_IEEE8021X_REQUIRE_KEY(%d)", (int) ieee8021x_required_key);
213                         }
214                         else
215                         {
216                                 wpa_printf(MSG_DEBUG, "ieee8021x_required_key is %s and eapol_flag(%d)", ieee8021x_required_key ? "TRUE" : "FALSE",
217                                                                                                                                                                                                 entry->eapol_flags);
218                         }
219                 }
220 #endif
221         }
222
223         return ret;
224 }
225
226 static int wpa_driver_ralink_set_ssid(struct wpa_driver_ralink_data *drv,
227                                       const u8 *ssid, size_t ssid_len)
228 {
229         NDIS_802_11_SSID *buf;
230         int ret = 0;
231         struct iwreq iwr;
232
233         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
234
235         buf = os_zalloc(sizeof(NDIS_802_11_SSID));
236         if (buf == NULL)
237                 return -1;
238         os_memset(buf, 0, sizeof(buf));
239         buf->SsidLength = ssid_len;
240         os_memcpy(buf->Ssid, ssid, ssid_len);
241         os_memset(&iwr, 0, sizeof(iwr));
242         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
243
244         iwr.u.data.flags = OID_802_11_SSID;
245         iwr.u.data.flags |= OID_GET_SET_TOGGLE;
246         iwr.u.data.pointer = (caddr_t) buf;
247         iwr.u.data.length = sizeof(NDIS_802_11_SSID);
248
249         if (ioctl(drv->ioctl_sock, RT_PRIV_IOCTL, &iwr) < 0) {
250                 perror("ioctl[RT_PRIV_IOCTL] -- OID_802_11_SSID");
251                 ret = -1;
252         }
253         os_free(buf);
254         return ret;
255 }
256
257 static void wpa_driver_ralink_event_pmkid(struct wpa_driver_ralink_data *drv,
258                                           const u8 *data, size_t data_len)
259 {
260         NDIS_802_11_PMKID_CANDIDATE_LIST *pmkid;
261         size_t i;
262         union wpa_event_data event;
263
264         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
265
266         if (data_len < 8) {
267                 wpa_printf(MSG_DEBUG, "RALINK: Too short PMKID Candidate List "
268                            "Event (len=%lu)", (unsigned long) data_len);
269                 return;
270         }
271         pmkid = (NDIS_802_11_PMKID_CANDIDATE_LIST *) data;
272         wpa_printf(MSG_DEBUG, "RALINK: PMKID Candidate List Event - Version %d"
273                    " NumCandidates %d",
274                    (int) pmkid->Version, (int) pmkid->NumCandidates);
275
276         if (pmkid->Version != 1) {
277                 wpa_printf(MSG_DEBUG, "RALINK: Unsupported PMKID Candidate "
278                            "List Version %d", (int) pmkid->Version);
279                 return;
280         }
281
282         if (data_len < 8 + pmkid->NumCandidates * sizeof(PMKID_CANDIDATE)) {
283                 wpa_printf(MSG_DEBUG, "RALINK: PMKID Candidate List "
284                            "underflow");
285
286                 return;
287         }
288
289
290
291         os_memset(&event, 0, sizeof(event));
292         for (i = 0; i < pmkid->NumCandidates; i++) {
293                 PMKID_CANDIDATE *p = &pmkid->CandidateList[i];
294                 wpa_printf(MSG_DEBUG, "RALINK: %lu: " MACSTR " Flags 0x%x",
295                            (unsigned long) i, MAC2STR(p->BSSID),
296                            (int) p->Flags);
297                 os_memcpy(event.pmkid_candidate.bssid, p->BSSID, ETH_ALEN);
298                 event.pmkid_candidate.index = i;
299                 event.pmkid_candidate.preauth =
300                         p->Flags & NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED;
301                 wpa_supplicant_event(drv->ctx, EVENT_PMKID_CANDIDATE,
302                                      &event);
303         }
304 }
305
306 static int wpa_driver_ralink_set_pmkid(struct wpa_driver_ralink_data *drv)
307 {
308         int len, count, i, ret;
309         struct ndis_pmkid_entry *entry;
310         NDIS_802_11_PMKID *p;
311
312         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
313
314         count = 0;
315         entry = drv->pmkid;
316         while (entry) {
317                 count++;
318                 if (count >= drv->no_of_pmkid)
319                         break;
320                 entry = entry->next;
321         }
322         len = 8 + count * sizeof(BSSID_INFO);
323         p = os_zalloc(len);
324         if (p == NULL)
325                 return -1;
326         p->Length = len;
327         p->BSSIDInfoCount = count;
328         entry = drv->pmkid;
329         for (i = 0; i < count; i++) {
330                 os_memcpy(&p->BSSIDInfo[i].BSSID, entry->bssid, ETH_ALEN);
331                 os_memcpy(&p->BSSIDInfo[i].PMKID, entry->pmkid, 16);
332                 entry = entry->next;
333         }
334         wpa_hexdump(MSG_MSGDUMP, "NDIS: OID_802_11_PMKID",
335                     (const u8 *) p, len);
336         ret = ralink_set_oid(drv, OID_802_11_PMKID, (char *) p, len);
337         os_free(p);
338         return ret;
339 }
340
341 static int wpa_driver_ralink_add_pmkid(void *priv, const u8 *bssid,
342                                        const u8 *pmkid)
343 {
344         struct wpa_driver_ralink_data *drv = priv;
345         struct ndis_pmkid_entry *entry, *prev;
346
347         if (drv->g_driver_down == 1)
348                 return -1;
349
350         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
351
352         if (drv->no_of_pmkid == 0)
353                 return 0;
354
355         prev = NULL;
356         entry = drv->pmkid;
357         while (entry) {
358                 if (os_memcmp(entry->bssid, bssid, ETH_ALEN) == 0)
359                         break;
360                 prev = entry;
361                 entry = entry->next;
362         }
363
364         if (entry) {
365                 /* Replace existing entry for this BSSID and move it into the
366                  * beginning of the list. */
367                 os_memcpy(entry->pmkid, pmkid, 16);
368                 if (prev) {
369                         prev->next = entry->next;
370                         entry->next = drv->pmkid;
371                         drv->pmkid = entry;
372                 }
373         } else {
374                 entry = os_malloc(sizeof(*entry));
375                 if (entry) {
376                         os_memcpy(entry->bssid, bssid, ETH_ALEN);
377                         os_memcpy(entry->pmkid, pmkid, 16);
378                         entry->next = drv->pmkid;
379                         drv->pmkid = entry;
380                 }
381         }
382
383         return wpa_driver_ralink_set_pmkid(drv);
384 }
385
386
387 static int wpa_driver_ralink_remove_pmkid(void *priv, const u8 *bssid,
388                                           const u8 *pmkid)
389 {
390         struct wpa_driver_ralink_data *drv = priv;
391         struct ndis_pmkid_entry *entry, *prev;
392
393         if (drv->g_driver_down == 1)
394                 return -1;
395
396         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
397
398         if (drv->no_of_pmkid == 0)
399                 return 0;
400
401         entry = drv->pmkid;
402         prev = NULL;
403         drv->pmkid = NULL;
404         while (entry) {
405                 if (os_memcmp(entry->bssid, bssid, ETH_ALEN) == 0 &&
406                     os_memcmp(entry->pmkid, pmkid, 16) == 0) {
407                         if (prev)
408                                 prev->next = entry->next;
409                         else
410                                 drv->pmkid = entry->next;
411                         os_free(entry);
412                         break;
413                 }
414                 prev = entry;
415                 entry = entry->next;
416         }
417         return wpa_driver_ralink_set_pmkid(drv);
418 }
419
420
421 static int wpa_driver_ralink_flush_pmkid(void *priv)
422 {
423         struct wpa_driver_ralink_data *drv = priv;
424         NDIS_802_11_PMKID p;
425         struct ndis_pmkid_entry *pmkid, *prev;
426
427         if (drv->g_driver_down == 1)
428                 return -1;
429
430         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
431
432         if (drv->no_of_pmkid == 0)
433                 return 0;
434
435         pmkid = drv->pmkid;
436         drv->pmkid = NULL;
437         while (pmkid) {
438                 prev = pmkid;
439                 pmkid = pmkid->next;
440                 os_free(prev);
441         }
442
443         os_memset(&p, 0, sizeof(p));
444         p.Length = 8;
445         p.BSSIDInfoCount = 0;
446         wpa_hexdump(MSG_MSGDUMP, "NDIS: OID_802_11_PMKID (flush)",
447                     (const u8 *) &p, 8);
448         return ralink_set_oid(drv, OID_802_11_PMKID, (char *) &p, 8);
449 }
450
451 static void
452 wpa_driver_ralink_event_wireless_custom(struct wpa_driver_ralink_data *drv,
453                                         void *ctx, char *custom)
454 {
455         union wpa_event_data data;
456         u8 *req_ies = NULL, *resp_ies = NULL;
457
458         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
459
460         wpa_printf(MSG_DEBUG, "Custom wireless event: '%s'", custom);
461
462         os_memset(&data, 0, sizeof(data));
463         /* Host AP driver */
464         if (os_strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) {
465                 /* receive a MICFAILURE report */
466                 data.michael_mic_failure.unicast =
467                         os_strstr(custom, " unicast") != NULL;
468                 /* TODO: parse parameters(?) */
469                 wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, &data);
470         } else if (os_strncmp(custom, "ASSOCINFO_ReqIEs=", 17) == 0) {
471                 /* receive assoc. req. IEs */
472                 char *spos;
473                 int bytes;
474
475                 spos = custom + 17;
476                 /*get IE's length */
477                 /*
478                  * bytes = strlen(spos); ==> bug, bytes may less than original
479                  * size by using this way to get size. snowpin 20070312
480                  * if (!bytes)
481                  *      return;
482                  */
483                 bytes = drv->assoc_req_ies_len;
484
485                 req_ies = os_malloc(bytes);
486                 if (req_ies == NULL)
487                         return;
488                 os_memcpy(req_ies, spos, bytes);
489                 data.assoc_info.req_ies = req_ies;
490                 data.assoc_info.req_ies_len = bytes;
491
492                 /* skip the '\0' byte */
493                 spos += bytes + 1;
494
495                 data.assoc_info.resp_ies = NULL;
496                 data.assoc_info.resp_ies_len = 0;
497
498                 if (os_strncmp(spos, " RespIEs=", 9) == 0) {
499                         /* receive assoc. resp. IEs */
500                         spos += 9;
501                         /* get IE's length */
502                         bytes = os_strlen(spos);
503                         if (!bytes)
504                                 goto done;
505
506                         resp_ies = os_malloc(bytes);
507                         if (resp_ies == NULL)
508                                 goto done;
509                         os_memcpy(resp_ies, spos, bytes);
510                         data.assoc_info.resp_ies = resp_ies;
511                         data.assoc_info.resp_ies_len = bytes;
512                 }
513
514                 wpa_supplicant_event(ctx, EVENT_ASSOCINFO, &data);
515
516         done:
517                 /* free allocated memory */
518                 os_free(resp_ies);
519                 os_free(req_ies);
520         }
521 }
522
523 static void ralink_interface_up(struct wpa_driver_ralink_data *drv)
524 {
525         union wpa_event_data event;
526         int enable_wpa_supplicant = 0;
527         drv->g_driver_down = 0;
528         os_memset(&event, 0, sizeof(event));
529         os_snprintf(event.interface_status.ifname,
530                     sizeof(event.interface_status.ifname), "%s", drv->ifname);
531
532         event.interface_status.ievent = EVENT_INTERFACE_ADDED;
533         wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
534
535         if (drv->ap_scan == 1)
536                 enable_wpa_supplicant = 1;
537         else
538                 enable_wpa_supplicant = 2;
539         /* trigger driver support wpa_supplicant */
540         if (ralink_set_oid(drv, RT_OID_WPA_SUPPLICANT_SUPPORT,
541                            (PCHAR) &enable_wpa_supplicant, sizeof(UCHAR)) < 0)
542         {
543                 wpa_printf(MSG_INFO, "RALINK: Failed to set "
544                            "RT_OID_WPA_SUPPLICANT_SUPPORT(%d)",
545                            (int) enable_wpa_supplicant);
546                 wpa_printf(MSG_ERROR, "ralink. Driver does not support "
547                            "wpa_supplicant");
548         }
549 }
550
551 static void
552 wpa_driver_ralink_event_wireless(struct wpa_driver_ralink_data *drv,
553                                  void *ctx, char *data, int len)
554 {
555         struct iw_event iwe_buf, *iwe = &iwe_buf;
556         char *pos, *end, *custom, *buf, *assoc_info_buf, *info_pos;
557 #if 0
558         BOOLEAN ieee8021x_required_key = FALSE;
559 #endif
560
561         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
562
563         assoc_info_buf = info_pos = NULL;
564         pos = data;
565         end = data + len;
566
567         while (pos + IW_EV_LCP_LEN <= end) {
568                 /* Event data may be unaligned, so make a local, aligned copy
569                  * before processing. */
570                 os_memcpy(&iwe_buf, pos, IW_EV_LCP_LEN);
571                 wpa_printf(MSG_DEBUG, "Wireless event: cmd=0x%x len=%d",
572                            iwe->cmd, iwe->len);
573                 if (iwe->len <= IW_EV_LCP_LEN)
574                         return;
575
576                 custom = pos + IW_EV_POINT_LEN;
577
578                 if (drv->we_version_compiled > 18 && iwe->cmd == IWEVCUSTOM) {
579                         /* WE-19 removed the pointer from struct iw_point */
580                         char *dpos = (char *) &iwe_buf.u.data.length;
581                         int dlen = dpos - (char *) &iwe_buf;
582                         os_memcpy(dpos, pos + IW_EV_LCP_LEN,
583                                   sizeof(struct iw_event) - dlen);
584                 } else {
585                         os_memcpy(&iwe_buf, pos, sizeof(struct iw_event));
586                         custom += IW_EV_POINT_OFF;
587                 }
588
589                 switch (iwe->cmd) {
590                 case IWEVCUSTOM:
591                         if (custom + iwe->u.data.length > end)
592                                 return;
593                         buf = os_malloc(iwe->u.data.length + 1);
594                         if (buf == NULL)
595                                 return;
596                         os_memcpy(buf, custom, iwe->u.data.length);
597                         buf[iwe->u.data.length] = '\0';
598
599                         if (drv->ap_scan == 1) {
600                                 if ((iwe->u.data.flags == RT_ASSOC_EVENT_FLAG)
601                                     || (iwe->u.data.flags ==
602                                         RT_REQIE_EVENT_FLAG) ||
603                                     (iwe->u.data.flags == RT_RESPIE_EVENT_FLAG)
604                                     || (iwe->u.data.flags ==
605                                         RT_ASSOCINFO_EVENT_FLAG)) {
606                                         if (drv->scanning_done == 0) {
607                                                 os_free(buf);
608                                                 return;
609                                         }
610                                 }
611                         }
612
613                         if (iwe->u.data.flags == RT_ASSOC_EVENT_FLAG) {
614                                 wpa_supplicant_event(ctx, EVENT_ASSOC, NULL);
615                                 wpa_printf(MSG_DEBUG, "Custom wireless event: "
616                                            "receive ASSOCIATED_EVENT !!!");
617                         } else if (iwe->u.data.flags == RT_REQIE_EVENT_FLAG) {
618                                 wpa_printf(MSG_DEBUG, "Custom wireless event: "
619                                            "receive ReqIEs !!!");
620                                 drv->assoc_req_ies =
621                                         os_malloc(iwe->u.data.length);
622                                 if (drv->assoc_req_ies == NULL) {
623                                         os_free(buf);
624                                         return;
625                                 }
626
627                                 drv->assoc_req_ies_len = iwe->u.data.length;
628                                 os_memcpy(drv->assoc_req_ies, custom,
629                                           iwe->u.data.length);
630                         } else if (iwe->u.data.flags == RT_RESPIE_EVENT_FLAG) {
631                                 wpa_printf(MSG_DEBUG, "Custom wireless event: "
632                                            "receive RespIEs !!!");
633                                 drv->assoc_resp_ies =
634                                         os_malloc(iwe->u.data.length);
635                                 if (drv->assoc_resp_ies == NULL) {
636                                         os_free(drv->assoc_req_ies);
637                                         drv->assoc_req_ies = NULL;
638                                         os_free(buf);
639                                         return;
640                                 }
641
642                                 drv->assoc_resp_ies_len = iwe->u.data.length;
643                                 os_memcpy(drv->assoc_resp_ies, custom,
644                                           iwe->u.data.length);
645                         } else if (iwe->u.data.flags ==
646                                    RT_ASSOCINFO_EVENT_FLAG) {
647                                 wpa_printf(MSG_DEBUG, "Custom wireless event: "
648                                            "receive ASSOCINFO_EVENT !!!");
649
650                                 assoc_info_buf =
651                                         os_zalloc(drv->assoc_req_ies_len +
652                                                   drv->assoc_resp_ies_len + 1);
653
654                                 if (assoc_info_buf == NULL) {
655                                         os_free(drv->assoc_req_ies);
656                                         drv->assoc_req_ies = NULL;
657                                         os_free(drv->assoc_resp_ies);
658                                         drv->assoc_resp_ies = NULL;
659                                         os_free(buf);
660                                         return;
661                                 }
662
663                                 if (drv->assoc_req_ies) {
664                                         os_memcpy(assoc_info_buf,
665                                                   drv->assoc_req_ies,
666                                                   drv->assoc_req_ies_len);
667                                 }
668                                 info_pos = assoc_info_buf +
669                                         drv->assoc_req_ies_len;
670                                 if (drv->assoc_resp_ies) {
671                                         os_memcpy(info_pos,
672                                                   drv->assoc_resp_ies,
673                                                   drv->assoc_resp_ies_len);
674                                 }
675                                 assoc_info_buf[drv->assoc_req_ies_len +
676                                                drv->assoc_resp_ies_len] = '\0';
677                                 wpa_driver_ralink_event_wireless_custom(
678                                         drv, ctx, assoc_info_buf);
679                                 os_free(drv->assoc_req_ies);
680                                 drv->assoc_req_ies = NULL;
681                                 os_free(drv->assoc_resp_ies);
682                                 drv->assoc_resp_ies = NULL;
683                                 os_free(assoc_info_buf);
684                         } else if (iwe->u.data.flags == RT_DISASSOC_EVENT_FLAG)
685                         {
686                                 wpa_printf(MSG_DEBUG, "Custom wireless event: "
687                                            "receive DISASSOCIATED_EVENT !!!");
688                                 wpa_supplicant_event(ctx, EVENT_DISASSOC,
689                                                      NULL);
690                         } else if (iwe->u.data.flags == RT_PMKIDCAND_FLAG) {
691                                 wpa_printf(MSG_DEBUG, "Custom wireless event: "
692                                            "receive PMKIDCAND_EVENT !!!");
693                                 wpa_driver_ralink_event_pmkid(
694                                         drv, (const u8 *) custom,
695                                         iwe->u.data.length);
696                         } else if (iwe->u.data.flags == RT_INTERFACE_DOWN) {
697                                 drv->g_driver_down = 1;
698                                 eloop_terminate();
699                         } else if (iwe->u.data.flags == RT_INTERFACE_UP) {
700                                 ralink_interface_up(drv);
701                         } else {
702                                 wpa_driver_ralink_event_wireless_custom(
703                                         drv, ctx, buf);
704                         }
705                         os_free(buf);
706                         break;
707                 }
708
709                 pos += iwe->len;
710         }
711 }
712
713 static void
714 wpa_driver_ralink_event_rtm_newlink(void *ctx, struct ifinfomsg *ifi, 
715                                     u8 *buf, size_t len)
716 {
717         struct wpa_driver_ralink_data *drv = ctx;
718         int attrlen, rta_len;
719         struct rtattr *attr;
720
721         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
722
723         wpa_hexdump(MSG_DEBUG, "ifi: ", (u8 *) ifi, sizeof(struct ifinfomsg));
724
725         attrlen = len;
726         wpa_printf(MSG_DEBUG, "attrlen=%d", attrlen);
727         attr = (struct rtattr *) buf;
728         wpa_hexdump(MSG_DEBUG, "attr1: ", (u8 *) attr, sizeof(struct rtattr));
729         rta_len = RTA_ALIGN(sizeof(struct rtattr));
730         wpa_hexdump(MSG_DEBUG, "attr2: ", (u8 *)attr,rta_len);
731         while (RTA_OK(attr, attrlen)) {
732                 wpa_printf(MSG_DEBUG, "rta_type=%02x\n", attr->rta_type);
733                 if (attr->rta_type == IFLA_WIRELESS) {
734                         wpa_driver_ralink_event_wireless(
735                                 drv, ctx,
736                                 ((char *) attr) + rta_len,
737                                 attr->rta_len - rta_len);
738                 }
739                 attr = RTA_NEXT(attr, attrlen);
740                 wpa_hexdump(MSG_DEBUG, "attr3: ",
741                             (u8 *) attr, sizeof(struct rtattr));
742         }
743 }
744
745 static int
746 ralink_get_we_version_compiled(struct wpa_driver_ralink_data *drv)
747 {
748         struct iwreq iwr;
749         UINT we_version_compiled = 0;
750
751         os_memset(&iwr, 0, sizeof(iwr));
752         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
753         iwr.u.data.pointer = (caddr_t) &we_version_compiled;
754         iwr.u.data.flags = RT_OID_WE_VERSION_COMPILED;
755
756         if (ioctl(drv->ioctl_sock, RT_PRIV_IOCTL, &iwr) < 0) {
757                 wpa_printf(MSG_DEBUG, "%s: failed", __func__);
758                 return -1;
759         }
760
761         drv->we_version_compiled = we_version_compiled;
762
763         return 0;
764 }
765
766 static void * wpa_driver_ralink_init(void *ctx, const char *ifname)
767 {
768         int s;
769         struct wpa_driver_ralink_data *drv;
770         struct ifreq ifr;
771         UCHAR enable_wpa_supplicant = 0;
772         struct netlink_config *cfg;
773
774         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
775
776         /* open socket to kernel */
777         if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
778                 perror("socket");
779                 return NULL;
780         }
781         /* do it */
782         os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
783
784         if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
785                 perror(ifr.ifr_name);
786                 return NULL;
787         }
788
789         drv = os_zalloc(sizeof(*drv));
790         if (drv == NULL)
791                 return NULL;
792
793         drv->scanning_done = 1;
794         drv->ap_scan = 1; /* for now - let's assume ap_scan=1 is used */
795         drv->ctx = ctx;
796         os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
797         drv->ioctl_sock = s;
798         drv->g_driver_down = 0;
799
800         cfg = os_zalloc(sizeof(*cfg));
801         if (cfg == NULL) {
802                 close(drv->ioctl_sock);
803                 os_free(drv);
804                 return NULL;
805         }
806         cfg->ctx = drv;
807         cfg->newlink_cb = wpa_driver_ralink_event_rtm_newlink;
808         drv->netlink = netlink_init(cfg);
809         if (drv->netlink == NULL) {
810                 os_free(cfg);
811                 close(drv->ioctl_sock);
812                 os_free(drv);
813                 return NULL;
814         }
815
816         drv->no_of_pmkid = 4; /* Number of PMKID saved supported */
817
818         linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1);
819         ralink_get_we_version_compiled(drv);
820         wpa_driver_ralink_flush_pmkid(drv);
821
822         if (drv->ap_scan == 1)
823                 enable_wpa_supplicant = 1;
824         else
825                 enable_wpa_supplicant = 2;
826         /* trigger driver support wpa_supplicant */
827         if (ralink_set_oid(drv, RT_OID_WPA_SUPPLICANT_SUPPORT,
828                            (PCHAR) &enable_wpa_supplicant, sizeof(UCHAR)) < 0)
829         {
830                 wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
831                            "RT_OID_WPA_SUPPLICANT_SUPPORT(%d)",
832                            (int) enable_wpa_supplicant);
833                 wpa_printf(MSG_ERROR, "RALINK: Driver does not support "
834                            "wpa_supplicant");
835                 close(s);
836                 close(drv->ioctl_sock);
837                 os_free(drv);
838                 return NULL;
839         }
840
841         if (drv->ap_scan == 1)
842                 drv->scanning_done = 0;
843
844         return drv;
845 }
846
847 static void wpa_driver_ralink_deinit(void *priv)
848 {
849         struct wpa_driver_ralink_data *drv = priv;
850         UCHAR enable_wpa_supplicant;
851
852         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
853
854         enable_wpa_supplicant = 0;
855
856         if (drv->g_driver_down == 0) {
857                 /* trigger driver disable wpa_supplicant support */
858                 if (ralink_set_oid(drv, RT_OID_WPA_SUPPLICANT_SUPPORT,
859                                    (char *) &enable_wpa_supplicant,
860                                    sizeof(BOOLEAN)) < 0) {
861                         wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
862                                    "RT_OID_WPA_SUPPLICANT_SUPPORT(%d)",
863                                    (int) enable_wpa_supplicant);
864                 }
865
866                 wpa_driver_ralink_flush_pmkid(drv);
867
868                 sleep(1);
869                 /* linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 0); */
870         }
871
872         eloop_cancel_timeout(wpa_driver_ralink_scan_timeout, drv, drv->ctx);
873         netlink_deinit(drv->netlink);
874         close(drv->ioctl_sock);
875         os_free(drv);
876 }
877
878 static void wpa_driver_ralink_scan_timeout(void *eloop_ctx, void *timeout_ctx)
879 {
880         struct wpa_driver_ralink_data *drv = eloop_ctx;
881
882         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
883
884         wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
885         wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
886
887         drv->scanning_done = 1;
888
889 }
890
891 static int wpa_driver_ralink_scan(void *priv,
892                                   struct wpa_driver_scan_params *params)
893 {
894         struct wpa_driver_ralink_data *drv = priv;
895         struct iwreq iwr;
896         int ret = 0;
897
898         if (drv->g_driver_down == 1)
899                 return -1;
900
901         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
902
903 #if 0
904         if (ssid_len > IW_ESSID_MAX_SIZE) {
905                 wpa_printf(MSG_DEBUG, "%s: too long SSID (%lu)",
906                            __FUNCTION__, (unsigned long) ssid_len);
907                 return -1;
908         }
909
910         /* wpa_driver_ralink_set_ssid(drv, ssid, ssid_len); */
911 #endif
912
913         if (ralink_set_oid(drv, RT_OID_WPS_PROBE_REQ_IE,
914                            (char *) params->extra_ies, params->extra_ies_len) <
915             0) {
916                 wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
917                            "RT_OID_WPS_PROBE_REQ_IE");
918         }
919
920         os_memset(&iwr, 0, sizeof(iwr));
921         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
922
923         if (ioctl(drv->ioctl_sock, SIOCSIWSCAN, &iwr) < 0) {
924                 perror("ioctl[SIOCSIWSCAN]");
925                 ret = -1;
926         }
927
928         /* Not all drivers generate "scan completed" wireless event, so try to
929          * read results after a timeout. */
930         eloop_cancel_timeout(wpa_driver_ralink_scan_timeout, drv, drv->ctx);
931         eloop_register_timeout(4, 0, wpa_driver_ralink_scan_timeout, drv,
932                                drv->ctx);
933
934         drv->scanning_done = 0;
935
936         return ret;
937 }
938
939 static struct wpa_scan_results *
940 wpa_driver_ralink_get_scan_results(void *priv)
941 {
942         struct wpa_driver_ralink_data *drv = priv;
943         UCHAR *buf = NULL;
944         size_t buf_len;
945         NDIS_802_11_BSSID_LIST_EX *wsr;
946         NDIS_WLAN_BSSID_EX *wbi;
947         struct iwreq iwr;
948         size_t ap_num;
949         u8 *pos;
950         struct wpa_scan_results *res;
951
952         if (drv->g_driver_down == 1)
953                 return NULL;
954         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
955
956         if (drv->we_version_compiled >= 17)
957                 buf_len = 8192;
958         else
959                 buf_len = 4096;
960
961         for (;;) {
962                 buf = os_zalloc(buf_len);
963                 iwr.u.data.length = buf_len;
964                 if (buf == NULL)
965                         return NULL;
966
967                 wsr = (NDIS_802_11_BSSID_LIST_EX *) buf;
968
969                 wsr->NumberOfItems = 0;
970                 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
971                 iwr.u.data.pointer = (void *) buf;
972                 iwr.u.data.flags = OID_802_11_BSSID_LIST;
973
974                 if (ioctl(drv->ioctl_sock, RT_PRIV_IOCTL, &iwr) == 0)
975                         break;
976
977                 if (errno == E2BIG && buf_len < 65535) {
978                         os_free(buf);
979                         buf = NULL;
980                         buf_len *= 2;
981                         if (buf_len > 65535)
982                                 buf_len = 65535; /* 16-bit length field */
983                         wpa_printf(MSG_DEBUG, "Scan results did not fit - "
984                                    "trying larger buffer (%lu bytes)",
985                                    (unsigned long) buf_len);
986                 } else {
987                         perror("ioctl[RT_PRIV_IOCTL]");
988                         os_free(buf);
989                         return NULL;
990                 }
991         }
992
993         res = os_zalloc(sizeof(*res));
994         if (res == NULL) {
995                 os_free(buf);
996                 return NULL;
997         }
998
999         res->res = os_zalloc(wsr->NumberOfItems *
1000                              sizeof(struct wpa_scan_res *));
1001         if (res->res == NULL) {
1002                 os_free(res);
1003                 os_free(buf);
1004                 return NULL;
1005         }
1006
1007         for (ap_num = 0, wbi = wsr->Bssid; ap_num < wsr->NumberOfItems;
1008              ++ap_num) {
1009                 struct wpa_scan_res *r = NULL;
1010                 size_t extra_len = 0, var_ie_len = 0;
1011                 u8 *pos2;
1012
1013                 /* SSID data element */
1014                 extra_len += 2 + wbi->Ssid.SsidLength;
1015                 var_ie_len = wbi->IELength - sizeof(NDIS_802_11_FIXED_IEs);
1016                 r = os_zalloc(sizeof(*r) + extra_len + var_ie_len);
1017                 if (r == NULL)
1018                         break;
1019                 res->res[res->num++] = r;
1020
1021                 wpa_printf(MSG_DEBUG, "SSID - %s", wbi->Ssid.Ssid);
1022                 /* get ie's */
1023                 wpa_hexdump(MSG_DEBUG, "RALINK: AP IEs",
1024                             (u8 *) &wbi->IEs[0], wbi->IELength);
1025
1026                 os_memcpy(r->bssid, wbi->MacAddress, ETH_ALEN);
1027
1028                 extra_len += (2 + wbi->Ssid.SsidLength);
1029                 r->ie_len = extra_len + var_ie_len;
1030                 pos2 = (u8 *) (r + 1);
1031
1032                 /*
1033                  * Generate a fake SSID IE since the driver did not report
1034                  * a full IE list.
1035                  */
1036                 *pos2++ = WLAN_EID_SSID;
1037                 *pos2++ = wbi->Ssid.SsidLength;
1038                 os_memcpy(pos2, wbi->Ssid.Ssid, wbi->Ssid.SsidLength);
1039                 pos2 += wbi->Ssid.SsidLength;
1040
1041                 r->freq = (wbi->Configuration.DSConfig / 1000);
1042
1043                 pos = (u8 *) wbi + sizeof(*wbi) - 1;
1044
1045                 pos += sizeof(NDIS_802_11_FIXED_IEs) - 2;
1046                 os_memcpy(&(r->caps), pos, 2);
1047                 pos += 2;
1048
1049                 if (wbi->IELength > sizeof(NDIS_802_11_FIXED_IEs))
1050                         os_memcpy(pos2, pos, var_ie_len);
1051
1052                 wbi = (NDIS_WLAN_BSSID_EX *) ((u8 *) wbi + wbi->Length);
1053         }
1054
1055         os_free(buf);
1056         return res;
1057 }
1058
1059 static int ralink_set_auth_mode(struct wpa_driver_ralink_data *drv,
1060                                 NDIS_802_11_AUTHENTICATION_MODE mode)
1061 {
1062         NDIS_802_11_AUTHENTICATION_MODE auth_mode = mode;
1063
1064         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1065
1066         if (ralink_set_oid(drv, OID_802_11_AUTHENTICATION_MODE,
1067                            (char *) &auth_mode, sizeof(auth_mode)) < 0) {
1068                 wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
1069                            "OID_802_11_AUTHENTICATION_MODE (%d)",
1070                            (int) auth_mode);
1071                 return -1;
1072         }
1073         return 0;
1074 }
1075
1076 static int ralink_set_encr_type(struct wpa_driver_ralink_data *drv,
1077                                 NDIS_802_11_WEP_STATUS encr_type)
1078 {
1079         NDIS_802_11_WEP_STATUS wep_status = encr_type;
1080
1081         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1082
1083         if (ralink_set_oid(drv, OID_802_11_WEP_STATUS,
1084                            (char *) &wep_status, sizeof(wep_status)) < 0) {
1085                 wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
1086                            "OID_802_11_WEP_STATUS (%d)",
1087                            (int) wep_status);
1088                 return -1;
1089         }
1090         return 0;
1091 }
1092
1093
1094 static int wpa_driver_ralink_remove_key(struct wpa_driver_ralink_data *drv,
1095                                         int key_idx, const u8 *addr,
1096                                         const u8 *bssid, int pairwise)
1097 {
1098         NDIS_802_11_REMOVE_KEY rkey;
1099         NDIS_802_11_KEY_INDEX _index;
1100         int res, res2;
1101
1102         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1103
1104         os_memset(&rkey, 0, sizeof(rkey));
1105
1106         rkey.Length = sizeof(rkey);
1107         rkey.KeyIndex = key_idx;
1108
1109         if (pairwise)
1110                 rkey.KeyIndex |= 1 << 30;
1111
1112         os_memcpy(rkey.BSSID, bssid, ETH_ALEN);
1113
1114         res = ralink_set_oid(drv, OID_802_11_REMOVE_KEY, (char *) &rkey,
1115                              sizeof(rkey));
1116
1117         /* AlbertY@20060210 removed it */
1118         if (0 /* !pairwise */) {
1119                 res2 = ralink_set_oid(drv, OID_802_11_REMOVE_WEP,
1120                                       (char *) &_index, sizeof(_index));
1121         } else
1122                 res2 = 0;
1123
1124         if (res < 0 && res2 < 0)
1125                 return res;
1126         return 0;
1127 }
1128
1129 static int wpa_driver_ralink_add_wep(struct wpa_driver_ralink_data *drv,
1130                                      int pairwise, int key_idx, int set_tx,
1131                                      const u8 *key, size_t key_len)
1132 {
1133         NDIS_802_11_WEP *wep;
1134         size_t len;
1135         int res;
1136
1137         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1138
1139         len = 12 + key_len;
1140         wep = os_zalloc(len);
1141         if (wep == NULL)
1142                 return -1;
1143
1144         wep->Length = len;
1145         wep->KeyIndex = key_idx;
1146
1147         if (set_tx)
1148                 wep->KeyIndex |= 0x80000000;
1149
1150         wep->KeyLength = key_len;
1151         os_memcpy(wep->KeyMaterial, key, key_len);
1152
1153         wpa_hexdump_key(MSG_MSGDUMP, "RALINK: OID_802_11_ADD_WEP",
1154                         (const u8 *) wep, len);
1155         res = ralink_set_oid(drv, OID_802_11_ADD_WEP, (char *) wep, len);
1156
1157         os_free(wep);
1158
1159         return res;
1160 }
1161
1162 static int wpa_driver_ralink_set_key(const char *ifname, void *priv,
1163                                      enum wpa_alg alg, const u8 *addr,
1164                                      int key_idx, int set_tx,
1165                                      const u8 *seq, size_t seq_len,
1166                                      const u8 *key, size_t key_len)
1167 {
1168         struct wpa_driver_ralink_data *drv = priv;
1169         size_t len, i;
1170         NDIS_802_11_KEY *nkey;
1171         int res, pairwise;
1172         u8 bssid[ETH_ALEN];
1173
1174         if (drv->g_driver_down == 1)
1175                 return -1;
1176
1177         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1178
1179         drv->bAddWepKey = FALSE;
1180
1181         if (addr == NULL || os_memcmp(addr, "\xff\xff\xff\xff\xff\xff",
1182                                       ETH_ALEN) == 0) {
1183                 /* Group Key */
1184                 pairwise = 0;
1185                 wpa_driver_ralink_get_bssid(drv, bssid);
1186         } else {
1187                 /* Pairwise Key */
1188                 pairwise = 1;
1189                 os_memcpy(bssid, addr, ETH_ALEN);
1190         }
1191
1192         if (alg == WPA_ALG_NONE || key_len == 0) {
1193                 return wpa_driver_ralink_remove_key(drv, key_idx, addr, bssid,
1194                                                     pairwise);
1195         }
1196
1197         if (alg == WPA_ALG_WEP) {
1198                 drv->bAddWepKey = TRUE;
1199                 return wpa_driver_ralink_add_wep(drv, pairwise, key_idx,
1200                                                  set_tx, key, key_len);
1201         }
1202
1203         len = 12 + 6 + 6 + 8 + key_len;
1204
1205         nkey = os_zalloc(len);
1206         if (nkey == NULL)
1207                 return -1;
1208
1209         nkey->Length = len;
1210         nkey->KeyIndex = key_idx;
1211
1212         if (set_tx)
1213                 nkey->KeyIndex |= 1 << 31;
1214
1215         if (pairwise)
1216                 nkey->KeyIndex |= 1 << 30;
1217
1218         if (seq && seq_len)
1219                 nkey->KeyIndex |= 1 << 29;
1220
1221         nkey->KeyLength = key_len;
1222         os_memcpy(nkey->BSSID, bssid, ETH_ALEN);
1223
1224         if (seq && seq_len) {
1225                 for (i = 0; i < seq_len; i++)
1226                         nkey->KeyRSC |= seq[i] << (i * 8);
1227         }
1228         if (alg == WPA_ALG_TKIP && key_len == 32) {
1229                 os_memcpy(nkey->KeyMaterial, key, 16);
1230                 os_memcpy(nkey->KeyMaterial + 16, key + 24, 8);
1231                 os_memcpy(nkey->KeyMaterial + 24, key + 16, 8);
1232         } else {
1233                 os_memcpy(nkey->KeyMaterial, key, key_len);
1234         }
1235
1236         wpa_printf(MSG_DEBUG, "%s: alg=%d key_idx=%d set_tx=%d seq_len=%lu "
1237                    "key_len=%lu", __FUNCTION__, alg, key_idx, set_tx,
1238                    (unsigned long) seq_len, (unsigned long) key_len);
1239
1240         wpa_hexdump_key(MSG_MSGDUMP, "RALINK: OID_802_11_ADD_KEY",
1241                         (const u8 *) nkey, len);
1242         res = ralink_set_oid(drv, OID_802_11_ADD_KEY, (char *) nkey, len);
1243         os_free(nkey);
1244
1245         return res;
1246 }
1247
1248 static int wpa_driver_ralink_disassociate(void *priv, const u8 *addr,
1249                                         int reason_code)
1250 {
1251         struct wpa_driver_ralink_data *drv = priv;
1252
1253         if (drv->g_driver_down == 1)
1254                 return -1;
1255         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1256         if (ralink_set_oid(drv, OID_802_11_DISASSOCIATE, "    ", 4) < 0) {
1257                 wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
1258                            "OID_802_11_DISASSOCIATE");
1259         }
1260
1261         return 0;
1262 }
1263
1264 static int wpa_driver_ralink_deauthenticate(void *priv, const u8 *addr,
1265                                           int reason_code)
1266 {
1267         struct wpa_driver_ralink_data *drv = priv;
1268
1269         wpa_printf(MSG_DEBUG, "g_driver_down = %d", drv->g_driver_down);
1270
1271         if (drv->g_driver_down == 1)
1272                 return -1;
1273
1274         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1275         if (ralink_get_new_driver_flag(drv) == 0) {
1276                 return wpa_driver_ralink_disassociate(priv, addr, reason_code);
1277         } else {
1278                 MLME_DEAUTH_REQ_STRUCT mlme;
1279                 os_memset(&mlme, 0, sizeof(MLME_DEAUTH_REQ_STRUCT));
1280                 mlme.Reason = reason_code;
1281                 os_memcpy(mlme.Addr, addr, MAC_ADDR_LEN);
1282                 return ralink_set_oid(drv, OID_802_11_DEAUTHENTICATION,
1283                                       (char *) &mlme,
1284                                       sizeof(MLME_DEAUTH_REQ_STRUCT));
1285         }
1286 }
1287
1288 static int wpa_driver_ralink_set_gen_ie(void *priv, const u8 *ie,
1289                                         size_t ie_len)
1290 {
1291         struct wpa_driver_ralink_data *drv = priv;
1292         struct iwreq iwr;
1293         int ret = 0;
1294
1295         os_memset(&iwr, 0, sizeof(iwr));
1296         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1297         iwr.u.data.pointer = (caddr_t) ie;
1298         iwr.u.data.length = ie_len;
1299
1300         wpa_hexdump(MSG_DEBUG, "wpa_driver_ralink_set_gen_ie: ",
1301                     (u8 *) ie, ie_len);
1302
1303         if (ioctl(drv->ioctl_sock, SIOCSIWGENIE, &iwr) < 0) {
1304                 perror("ioctl[SIOCSIWGENIE]");
1305                 ret = -1;
1306         }
1307
1308         return ret;
1309 }
1310
1311 static int
1312 wpa_driver_ralink_associate(void *priv,
1313                             struct wpa_driver_associate_params *params)
1314 {
1315         struct wpa_driver_ralink_data *drv = priv;
1316
1317         NDIS_802_11_NETWORK_INFRASTRUCTURE mode;
1318         NDIS_802_11_AUTHENTICATION_MODE auth_mode;
1319         NDIS_802_11_WEP_STATUS encr;
1320         BOOLEAN         ieee8021xMode;
1321         BOOLEAN         ieee8021x_required_key = TRUE;
1322
1323         if (drv->g_driver_down == 1)
1324                 return -1;
1325         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1326
1327         if (params->mode == IEEE80211_MODE_IBSS)
1328                 mode = Ndis802_11IBSS;
1329         else
1330                 mode = Ndis802_11Infrastructure;
1331
1332         if (ralink_set_oid(drv, OID_802_11_INFRASTRUCTURE_MODE,
1333                          (char *) &mode, sizeof(mode)) < 0) {
1334                 wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
1335                            "OID_802_11_INFRASTRUCTURE_MODE (%d)",
1336                            (int) mode);
1337                 /* Try to continue anyway */
1338         }
1339
1340         if (params->key_mgmt_suite == KEY_MGMT_WPS) {
1341                 UCHAR enable_wps = 0x80;
1342                 /* trigger driver support wpa_supplicant */
1343                 if (ralink_set_oid(drv, RT_OID_WPA_SUPPLICANT_SUPPORT,
1344                                    (PCHAR) &enable_wps, sizeof(UCHAR)) < 0) {
1345                         wpa_printf(MSG_INFO, "RALINK: Failed to set "
1346                                    "RT_OID_WPA_SUPPLICANT_SUPPORT (%d)",
1347                                    (int) enable_wps);
1348                 }
1349
1350                 wpa_driver_ralink_set_gen_ie(priv, params->wpa_ie,
1351                                              params->wpa_ie_len);
1352
1353                 ralink_set_auth_mode(drv, Ndis802_11AuthModeOpen);
1354
1355                 ralink_set_encr_type(drv, Ndis802_11EncryptionDisabled);
1356         } else {
1357 #ifdef CONFIG_WPS
1358                 UCHAR enable_wpa_supplicant;
1359
1360                 if (drv->ap_scan == 1)
1361                         enable_wpa_supplicant = 0x01;
1362                 else
1363                         enable_wpa_supplicant = 0x02;
1364
1365                 /* trigger driver support wpa_supplicant */
1366                 if (ralink_set_oid(drv, RT_OID_WPA_SUPPLICANT_SUPPORT,
1367                                    (PCHAR) &enable_wpa_supplicant,
1368                                    sizeof(UCHAR)) < 0) {
1369                         wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
1370                                    "RT_OID_WPA_SUPPLICANT_SUPPORT (%d)",
1371                                    (int) enable_wpa_supplicant);
1372                 }
1373
1374                 wpa_driver_ralink_set_gen_ie(priv, (u8 *) "", 0);
1375 #endif /* CONFIG_WPS */
1376
1377                 if (params->wpa_ie == NULL || params->wpa_ie_len == 0) {
1378                         if (params->auth_alg & WPA_AUTH_ALG_SHARED) {
1379                                 if (params->auth_alg & WPA_AUTH_ALG_OPEN)
1380                                         auth_mode = Ndis802_11AuthModeAutoSwitch;
1381                                 else
1382                                         auth_mode = Ndis802_11AuthModeShared;
1383                         } else
1384                                 auth_mode = Ndis802_11AuthModeOpen;
1385                 } else if (params->wpa_ie[0] == WLAN_EID_RSN) {
1386                         if (params->key_mgmt_suite == KEY_MGMT_PSK)
1387                                 auth_mode = Ndis802_11AuthModeWPA2PSK;
1388                         else
1389                                 auth_mode = Ndis802_11AuthModeWPA2;
1390                 } else {
1391                         if (params->key_mgmt_suite == KEY_MGMT_WPA_NONE)
1392                                 auth_mode = Ndis802_11AuthModeWPANone;
1393                         else if (params->key_mgmt_suite == KEY_MGMT_PSK)
1394                                 auth_mode = Ndis802_11AuthModeWPAPSK;
1395                         else
1396                                 auth_mode = Ndis802_11AuthModeWPA;
1397                 }
1398
1399                 switch (params->pairwise_suite) {
1400                 case CIPHER_CCMP:
1401                         encr = Ndis802_11Encryption3Enabled;
1402                         break;
1403                 case CIPHER_TKIP:
1404                         encr = Ndis802_11Encryption2Enabled;
1405                         break;
1406                 case CIPHER_WEP40:
1407                 case CIPHER_WEP104:
1408                         encr = Ndis802_11Encryption1Enabled;
1409                         break;
1410                 case CIPHER_NONE:
1411                         if (params->group_suite == CIPHER_CCMP)
1412                                 encr = Ndis802_11Encryption3Enabled;
1413                         else if (params->group_suite == CIPHER_TKIP)
1414                                 encr = Ndis802_11Encryption2Enabled;
1415                         else
1416                                 encr = Ndis802_11EncryptionDisabled;
1417                         break;
1418                 default:
1419                         encr = Ndis802_11EncryptionDisabled;
1420                         break;
1421                 }
1422
1423                 ralink_set_auth_mode(drv, auth_mode);
1424
1425                 /* notify driver that IEEE8021x mode is enabled */
1426                 if (params->key_mgmt_suite == KEY_MGMT_802_1X_NO_WPA) {
1427                         ieee8021xMode = TRUE;
1428                         if (drv->bAddWepKey)
1429                                 ieee8021x_required_key = FALSE;
1430                 } else
1431                         ieee8021xMode = FALSE;
1432
1433                 if (ralink_set_oid(drv, OID_802_11_SET_IEEE8021X_REQUIRE_KEY,
1434                                    (char *) &ieee8021x_required_key,
1435                                    sizeof(BOOLEAN)) < 0) {
1436                         wpa_printf(MSG_DEBUG, "ERROR: Failed to set "
1437                                    "OID_802_11_SET_IEEE8021X_REQUIRE_KEY(%d)",
1438                                    (int) ieee8021x_required_key);
1439                 } else {
1440                         wpa_printf(MSG_DEBUG, "ieee8021x_required_key is %s",
1441                                    ieee8021x_required_key ? "TRUE" : "FALSE");
1442                 }
1443
1444                 if (ralink_set_oid(drv, OID_802_11_SET_IEEE8021X,
1445                                    (char *) &ieee8021xMode, sizeof(BOOLEAN)) <
1446                     0) {
1447                         wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
1448                                    "OID_802_11_SET_IEEE8021X(%d)",
1449                                    (int) ieee8021xMode);
1450                 }
1451
1452                 ralink_set_encr_type(drv, encr);
1453
1454                 if ((ieee8021xMode == FALSE) &&
1455                     (encr == Ndis802_11Encryption1Enabled)) {
1456                         /* static WEP */
1457                         int enabled = 0;
1458                         if (ralink_set_oid(drv, OID_802_11_DROP_UNENCRYPTED,
1459                                            (char *) &enabled, sizeof(enabled))
1460                             < 0) {
1461                                 wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
1462                                            "OID_802_11_DROP_UNENCRYPTED(%d)",
1463                                            (int) encr);
1464                         }
1465                 }
1466         }
1467
1468         return wpa_driver_ralink_set_ssid(drv, params->ssid, params->ssid_len);
1469 }
1470
1471 static int
1472 wpa_driver_ralink_set_countermeasures(void *priv, int enabled)
1473 {
1474         struct wpa_driver_ralink_data *drv = priv;
1475         if (drv->g_driver_down == 1)
1476                 return -1;
1477         wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
1478         return ralink_set_oid(drv, OID_SET_COUNTERMEASURES, (char *) &enabled,
1479                               sizeof(int));
1480 }
1481
1482 const struct wpa_driver_ops wpa_driver_ralink_ops = {
1483         .name = "ralink",
1484         .desc = "Ralink Wireless Client driver",
1485         .get_bssid = wpa_driver_ralink_get_bssid,
1486         .get_ssid = wpa_driver_ralink_get_ssid,
1487         .set_key = wpa_driver_ralink_set_key,
1488         .init = wpa_driver_ralink_init,
1489         .deinit = wpa_driver_ralink_deinit,
1490         .set_countermeasures    = wpa_driver_ralink_set_countermeasures,
1491         .scan2 = wpa_driver_ralink_scan,
1492         .get_scan_results2 = wpa_driver_ralink_get_scan_results,
1493         .deauthenticate = wpa_driver_ralink_deauthenticate,
1494         .disassociate = wpa_driver_ralink_disassociate,
1495         .associate = wpa_driver_ralink_associate,
1496         .add_pmkid = wpa_driver_ralink_add_pmkid,
1497         .remove_pmkid = wpa_driver_ralink_remove_pmkid,
1498         .flush_pmkid = wpa_driver_ralink_flush_pmkid,
1499 };