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