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