6d99b3f11a013f23a71c4ed2d4d166be4b5cefa0
[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 "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_strlcpy(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_strlcpy(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_strlcpy(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_strlcpy(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_strlcpy(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                                         os_free(buf);
616                                         return;
617                                 }
618
619                                 drv->assoc_req_ies_len = iwe->u.data.length;
620                                 os_memcpy(drv->assoc_req_ies, custom,
621                                           iwe->u.data.length);
622                         } else if (iwe->u.data.flags == RT_RESPIE_EVENT_FLAG) {
623                                 wpa_printf(MSG_DEBUG, "Custom wireless event: "
624                                            "receive RespIEs !!!");
625                                 drv->assoc_resp_ies =
626                                         os_malloc(iwe->u.data.length);
627                                 if (drv->assoc_resp_ies == NULL) {
628                                         os_free(drv->assoc_req_ies);
629                                         drv->assoc_req_ies = NULL;
630                                         os_free(buf);
631                                         return;
632                                 }
633
634                                 drv->assoc_resp_ies_len = iwe->u.data.length;
635                                 os_memcpy(drv->assoc_resp_ies, custom,
636                                           iwe->u.data.length);
637                         } else if (iwe->u.data.flags ==
638                                    RT_ASSOCINFO_EVENT_FLAG) {
639                                 wpa_printf(MSG_DEBUG, "Custom wireless event: "
640                                            "receive ASSOCINFO_EVENT !!!");
641
642                                 assoc_info_buf =
643                                         os_zalloc(drv->assoc_req_ies_len +
644                                                   drv->assoc_resp_ies_len + 1);
645
646                                 if (assoc_info_buf == NULL) {
647                                         os_free(drv->assoc_req_ies);
648                                         drv->assoc_req_ies = NULL;
649                                         os_free(drv->assoc_resp_ies);
650                                         drv->assoc_resp_ies = NULL;
651                                         os_free(buf);
652                                         return;
653                                 }
654
655                                 if (drv->assoc_req_ies) {
656                                         os_memcpy(assoc_info_buf,
657                                                   drv->assoc_req_ies,
658                                                   drv->assoc_req_ies_len);
659                                 }
660                                 info_pos = assoc_info_buf +
661                                         drv->assoc_req_ies_len;
662                                 if (drv->assoc_resp_ies) {
663                                         os_memcpy(info_pos,
664                                                   drv->assoc_resp_ies,
665                                                   drv->assoc_resp_ies_len);
666                                 }
667                                 assoc_info_buf[drv->assoc_req_ies_len +
668                                                drv->assoc_resp_ies_len] = '\0';
669                                 wpa_driver_ralink_event_wireless_custom(
670                                         drv, ctx, assoc_info_buf);
671                                 os_free(drv->assoc_req_ies);
672                                 drv->assoc_req_ies = NULL;
673                                 os_free(drv->assoc_resp_ies);
674                                 drv->assoc_resp_ies = NULL;
675                                 os_free(assoc_info_buf);
676                         } else if (iwe->u.data.flags == RT_DISASSOC_EVENT_FLAG)
677                         {
678                                 wpa_printf(MSG_DEBUG, "Custom wireless event: "
679                                            "receive DISASSOCIATED_EVENT !!!");
680                                 wpa_supplicant_event(ctx, EVENT_DISASSOC,
681                                                      NULL);
682                         } else if (iwe->u.data.flags == RT_PMKIDCAND_FLAG) {
683                                 wpa_printf(MSG_DEBUG, "Custom wireless event: "
684                                            "receive PMKIDCAND_EVENT !!!");
685                                 wpa_driver_ralink_event_pmkid(
686                                         drv, (const u8 *) custom,
687                                         iwe->u.data.length);
688                         } else if (iwe->u.data.flags == RT_INTERFACE_DOWN) {
689                                 drv->g_driver_down = 1;
690                                 eloop_terminate();
691                         } else if (iwe->u.data.flags == RT_REPORT_AP_INFO) {
692                                 if (drv->ap_scan != 1) {
693                                         typedef struct PACKED {
694                                                 UCHAR bssid[MAC_ADDR_LEN];
695                                                 UCHAR ssid[MAX_LEN_OF_SSID];
696                                                 INT ssid_len;
697                                                 UCHAR wpa_ie[40];
698                                                 INT wpa_ie_len;
699                                                 UCHAR rsn_ie[40];
700                                                 INT rsn_ie_len;
701                                                 INT freq;
702                                                 USHORT caps;
703                                         } *PAPINFO;
704
705                                         wpa_printf(MSG_DEBUG, "Custom wireless"
706                                                    " event: receive "
707                                                    "RT_REPORT_AP_INFO !!!");
708                                         //printf("iwe->u.data.length = %d\n", iwe->u.data.length);
709                                         //wpa_hexdump(MSG_DEBUG, "AP_Info: ", buf, iwe->u.data.length);
710 #if 0
711                                         wpa_s->num_scan_results = 1;
712                                         if (wpa_s->scan_results)
713                                                 os_free(wpa_s->scan_results);
714                                         wpa_s->scan_results = os_malloc(sizeof(struct wpa_scan_result) + 1);
715                                         if (wpa_s->scan_results) {
716                                                 PAPINFO pApInfo = (PAPINFO)buf;
717                                                 os_memcpy(wpa_s->scan_results[0].bssid, pApInfo->bssid, ETH_ALEN);
718                                                 os_memcpy(wpa_s->scan_results[0].ssid, pApInfo->ssid, pApInfo->ssid_len);
719                                                 wpa_s->scan_results[0].ssid_len = pApInfo->ssid_len;
720                                                 if (pApInfo->wpa_ie_len > 0) {
721                                                         os_memcpy(wpa_s->scan_results[0].wpa_ie, pApInfo->wpa_ie, pApInfo->wpa_ie_len);
722                                                         wpa_s->scan_results[0].wpa_ie_len = pApInfo->wpa_ie_len;
723                                                 } else if (pApInfo->rsn_ie_len > 0) {
724                                                         os_memcpy(wpa_s->scan_results[0].rsn_ie, pApInfo->rsn_ie, pApInfo->rsn_ie_len);
725                                                         wpa_s->scan_results[0].rsn_ie_len = pApInfo->rsn_ie_len;
726                                                 }
727                                                 wpa_s->scan_results[0].caps = pApInfo->caps;
728                                                 wpa_s->scan_results[0].freq = pApInfo->freq;
729                                         } else {
730                                                 wpa_printf("wpa_s->scan_"
731                                                            "results fail to "
732                                                            "os_malloc!!\n");
733                                         }
734 #endif
735                                 }
736                         } else {
737                                 wpa_driver_ralink_event_wireless_custom(
738                                         drv, ctx, buf);
739                         }
740                         os_free(buf);
741                         break;
742                 }
743
744                 pos += iwe->len;
745         }
746 }
747
748 static void
749 wpa_driver_ralink_event_rtm_newlink(struct wpa_driver_ralink_data *drv,
750                                     void *ctx, struct nlmsghdr *h, int len)
751 {
752         struct ifinfomsg *ifi;
753         int attrlen, nlmsg_len, rta_len;
754         struct rtattr * attr;
755
756         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
757
758         if (len < (int) sizeof(*ifi))
759                 return;
760
761         ifi = NLMSG_DATA(h);
762         wpa_hexdump(MSG_DEBUG, "ifi: ", (u8 *) ifi, sizeof(struct ifinfomsg));
763
764         nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
765
766         attrlen = h->nlmsg_len - nlmsg_len;
767         wpa_printf(MSG_DEBUG, "attrlen=%d", attrlen);
768         if (attrlen < 0)
769                 return;
770
771         attr = (struct rtattr *) (((char *) ifi) + nlmsg_len);
772         wpa_hexdump(MSG_DEBUG, "attr1: ", (u8 *) attr, sizeof(struct rtattr));
773         rta_len = RTA_ALIGN(sizeof(struct rtattr));
774         wpa_hexdump(MSG_DEBUG, "attr2: ", (u8 *)attr,rta_len);
775         while (RTA_OK(attr, attrlen)) {
776                 wpa_printf(MSG_DEBUG, "rta_type=%02x\n", attr->rta_type);
777                 if (attr->rta_type == IFLA_WIRELESS) {
778                         wpa_driver_ralink_event_wireless(
779                                 drv, ctx,
780                                 ((char *) attr) + rta_len,
781                                 attr->rta_len - rta_len);
782                 }
783                 attr = RTA_NEXT(attr, attrlen);
784                 wpa_hexdump(MSG_DEBUG, "attr3: ",
785                             (u8 *) attr, sizeof(struct rtattr));
786         }
787 }
788
789 static void wpa_driver_ralink_event_receive(int sock, void *ctx,
790                                             void *sock_ctx)
791 {
792         char buf[8192];
793         int left;
794         struct sockaddr_nl from;
795         socklen_t fromlen;
796         struct nlmsghdr *h;
797
798         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
799
800         fromlen = sizeof(from);
801         left = recvfrom(sock, buf, sizeof(buf), MSG_DONTWAIT,
802                         (struct sockaddr *) &from, &fromlen);
803
804         if (left < 0) {
805                 if (errno != EINTR && errno != EAGAIN)
806                         perror("recvfrom(netlink)");
807                 return;
808         }
809
810         h = (struct nlmsghdr *) buf;
811         wpa_hexdump(MSG_DEBUG, "h: ", (u8 *)h, h->nlmsg_len);
812
813         while (left >= (int) sizeof(*h)) {
814                 int len, plen;
815
816                 len = h->nlmsg_len;
817                 plen = len - sizeof(*h);
818                 if (len > left || plen < 0) {
819                         wpa_printf(MSG_DEBUG, "Malformed netlink message: "
820                                    "len=%d left=%d plen=%d", len, left, plen);
821                         break;
822                 }
823
824                 switch (h->nlmsg_type) {
825                 case RTM_NEWLINK:
826                         wpa_driver_ralink_event_rtm_newlink(ctx, sock_ctx, h,
827                                                             plen);
828                         break;
829                 }
830
831                 len = NLMSG_ALIGN(len);
832                 left -= len;
833                 h = (struct nlmsghdr *) ((char *) h + len);
834         }
835
836         if (left > 0) {
837                 wpa_printf(MSG_DEBUG, "%d extra bytes in the end of netlink "
838                            "message", left);
839         }
840
841 }
842
843 static int
844 ralink_get_we_version_compiled(struct wpa_driver_ralink_data *drv)
845 {
846         struct iwreq iwr;
847         UINT we_version_compiled = 0;
848
849         os_memset(&iwr, 0, sizeof(iwr));
850         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
851         iwr.u.data.pointer = (caddr_t) &we_version_compiled;
852         iwr.u.data.flags = RT_OID_WE_VERSION_COMPILED;
853
854         if (ioctl(drv->ioctl_sock, RT_PRIV_IOCTL, &iwr) < 0) {
855                 wpa_printf(MSG_DEBUG, "%s: failed", __func__);
856                 return -1;
857         }
858
859         drv->we_version_compiled = we_version_compiled;
860
861         return 0;
862 }
863
864 static int
865 ralink_set_iface_flags(void *priv, int dev_up)
866 {
867         struct wpa_driver_ralink_data *drv = priv;
868         struct ifreq ifr;
869
870         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
871
872         if (drv->ioctl_sock < 0)
873                 return -1;
874
875         os_memset(&ifr, 0, sizeof(ifr));
876         os_snprintf(ifr.ifr_name, IFNAMSIZ, "%s", drv->ifname);
877
878         if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, &ifr) != 0) {
879                 perror("ioctl[SIOCGIFFLAGS]");
880                 return -1;
881         }
882
883         if (dev_up)
884                 ifr.ifr_flags |= IFF_UP;
885         else
886                 ifr.ifr_flags &= ~IFF_UP;
887
888         if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, &ifr) != 0) {
889                 perror("ioctl[SIOCSIFFLAGS]");
890                 return -1;
891         }
892
893         return 0;
894 }
895
896 static void * wpa_driver_ralink_init(void *ctx, const char *ifname)
897 {
898         int s;
899         struct wpa_driver_ralink_data *drv;
900         struct ifreq ifr;
901         struct sockaddr_nl local;
902         UCHAR enable_wpa_supplicant = 0;
903
904         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
905
906         /* open socket to kernel */
907         if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
908                 perror("socket");
909                 return NULL;
910         }
911         /* do it */
912         os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
913
914         if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
915                 perror(ifr.ifr_name);
916                 return NULL;
917         }
918
919         drv = os_zalloc(sizeof(*drv));
920         if (drv == NULL)
921                 return NULL;
922
923         drv->scanning_done = 1;
924         drv->ap_scan = 1; /* for now - let's assume ap_scan=1 is used */
925         drv->ctx = ctx;
926         os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
927         drv->ioctl_sock = s;
928         drv->g_driver_down = 0;
929
930         s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
931         if (s < 0) {
932                 perror("socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE)");
933                 close(drv->ioctl_sock);
934                 os_free(drv);
935                 return NULL;
936         }
937
938         os_memset(&local, 0, sizeof(local));
939         local.nl_family = AF_NETLINK;
940         local.nl_groups = RTMGRP_LINK;
941
942         if (bind(s, (struct sockaddr *) &local, sizeof(local)) < 0) {
943                 perror("bind(netlink)");
944                 close(s);
945                 close(drv->ioctl_sock);
946                 os_free(drv);
947                 return NULL;
948         }
949
950         eloop_register_read_sock(s, wpa_driver_ralink_event_receive, drv, ctx);
951         drv->event_sock = s;
952         drv->no_of_pmkid = 4; /* Number of PMKID saved supported */
953
954         ralink_set_iface_flags(drv, 1); /* mark up during setup */
955         ralink_get_we_version_compiled(drv);
956         wpa_driver_ralink_flush_pmkid(drv);
957
958         if (drv->ap_scan == 1)
959                 enable_wpa_supplicant = 1;
960         else
961                 enable_wpa_supplicant = 2;
962         /* trigger driver support wpa_supplicant */
963         if (ralink_set_oid(drv, RT_OID_WPA_SUPPLICANT_SUPPORT,
964                            (PCHAR) &enable_wpa_supplicant, sizeof(UCHAR)) < 0)
965         {
966                 wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
967                            "RT_OID_WPA_SUPPLICANT_SUPPORT(%d)",
968                            (int) enable_wpa_supplicant);
969                 wpa_printf(MSG_ERROR, "RALINK: Driver does not support "
970                            "wpa_supplicant");
971                 close(s);
972                 close(drv->ioctl_sock);
973                 os_free(drv);
974                 return NULL;
975         }
976
977         if (drv->ap_scan == 1)
978                 drv->scanning_done = 0;
979
980         return drv;
981 }
982
983 static void wpa_driver_ralink_deinit(void *priv)
984 {
985         struct wpa_driver_ralink_data *drv = priv;
986         UCHAR enable_wpa_supplicant;
987
988         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
989
990         enable_wpa_supplicant = 0;
991
992         if (drv->g_driver_down == 0) {
993                 /* trigger driver disable wpa_supplicant support */
994                 if (ralink_set_oid(drv, RT_OID_WPA_SUPPLICANT_SUPPORT,
995                                    (char *) &enable_wpa_supplicant,
996                                    sizeof(BOOLEAN)) < 0) {
997                         wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
998                                    "RT_OID_WPA_SUPPLICANT_SUPPORT(%d)",
999                                    (int) enable_wpa_supplicant);
1000                 }
1001
1002                 wpa_driver_ralink_flush_pmkid(drv);
1003
1004                 sleep(1);
1005                 ralink_set_iface_flags(drv, 0);
1006         }
1007
1008         eloop_cancel_timeout(wpa_driver_ralink_scan_timeout, drv, drv->ctx);
1009         eloop_unregister_read_sock(drv->event_sock);
1010         close(drv->event_sock);
1011         close(drv->ioctl_sock);
1012         os_free(drv);
1013 }
1014
1015 static void wpa_driver_ralink_scan_timeout(void *eloop_ctx, void *timeout_ctx)
1016 {
1017         struct wpa_driver_ralink_data *drv = eloop_ctx;
1018
1019         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1020
1021         wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
1022         wpa_supplicant_event(timeout_ctx, EVENT_SCAN_RESULTS, NULL);
1023
1024         drv->scanning_done = 1;
1025
1026 }
1027
1028 static int wpa_driver_ralink_scan(void *priv, const u8 *ssid, size_t ssid_len)
1029 {
1030         struct wpa_driver_ralink_data *drv = priv;
1031         struct iwreq iwr;
1032         int ret = 0;
1033
1034         if (drv->g_driver_down == 1)
1035                 return -1;
1036
1037         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1038
1039         if (ssid_len > IW_ESSID_MAX_SIZE) {
1040                 wpa_printf(MSG_DEBUG, "%s: too long SSID (%lu)",
1041                            __FUNCTION__, (unsigned long) ssid_len);
1042                 return -1;
1043         }
1044
1045         /* wpa_driver_ralink_set_ssid(drv, ssid, ssid_len); */
1046
1047         os_memset(&iwr, 0, sizeof(iwr));
1048         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1049
1050         if (ioctl(drv->ioctl_sock, SIOCSIWSCAN, &iwr) < 0) {
1051                 perror("ioctl[SIOCSIWSCAN]");
1052                 ret = -1;
1053         }
1054
1055         /* Not all drivers generate "scan completed" wireless event, so try to
1056          * read results after a timeout. */
1057         eloop_cancel_timeout(wpa_driver_ralink_scan_timeout, drv, drv->ctx);
1058         eloop_register_timeout(4, 0, wpa_driver_ralink_scan_timeout, drv,
1059                                drv->ctx);
1060
1061         drv->scanning_done = 0;
1062
1063         return ret;
1064 }
1065
1066 static int
1067 wpa_driver_ralink_get_scan_results(void *priv,
1068                                    struct wpa_scan_result *results,
1069                                    size_t max_size)
1070 {
1071         struct wpa_driver_ralink_data *drv = priv;
1072         UCHAR *buf = NULL;
1073         NDIS_802_11_BSSID_LIST_EX *wsr;
1074         NDIS_WLAN_BSSID_EX *wbi;
1075         struct iwreq iwr;
1076         int rv = 0;
1077         size_t ap_num;
1078         u8 *pos, *end;
1079
1080         if (drv->g_driver_down == 1)
1081                 return -1;
1082         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1083
1084         if (drv->we_version_compiled >= 17) {
1085                 buf = os_zalloc(8192);
1086                 iwr.u.data.length = 8192;
1087         } else {
1088                 buf = os_zalloc(4096);
1089                 iwr.u.data.length = 4096;
1090         }
1091         if (buf == NULL)
1092                 return -1;
1093
1094         wsr = (NDIS_802_11_BSSID_LIST_EX *) buf;
1095
1096         wsr->NumberOfItems = 0;
1097         os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1098         iwr.u.data.pointer = (void *) buf;
1099         iwr.u.data.flags = OID_802_11_BSSID_LIST;
1100
1101         if ((rv = ioctl(drv->ioctl_sock, RT_PRIV_IOCTL, &iwr)) < 0) {
1102                 wpa_printf(MSG_DEBUG, "ioctl fail: rv = %d", rv);
1103                 os_free(buf);
1104                 return -1;
1105         }
1106
1107         os_memset(results, 0, max_size * sizeof(struct wpa_scan_result));
1108
1109         for (ap_num = 0, wbi = wsr->Bssid; ap_num < wsr->NumberOfItems;
1110              ++ap_num) {
1111                 os_memcpy(results[ap_num].bssid, &wbi->MacAddress, ETH_ALEN);
1112                 os_memcpy(results[ap_num].ssid, wbi->Ssid.Ssid,
1113                           wbi->Ssid.SsidLength);
1114                 results[ap_num].ssid_len = wbi->Ssid.SsidLength;
1115                 results[ap_num].freq = (wbi->Configuration.DSConfig / 1000);
1116
1117                 /* get ie's */
1118                 wpa_hexdump(MSG_DEBUG, "RALINK: AP IEs",
1119                             (u8 *) wbi + sizeof(*wbi) - 1, wbi->IELength);
1120
1121                 pos = (u8 *) wbi + sizeof(*wbi) - 1;
1122                 end = (u8 *) wbi + sizeof(*wbi) + wbi->IELength;
1123
1124                 if (wbi->IELength < sizeof(NDIS_802_11_FIXED_IEs))
1125                         break;
1126
1127                 pos += sizeof(NDIS_802_11_FIXED_IEs) - 2;
1128                 os_memcpy(&results[ap_num].caps, pos, 2);
1129                 pos += 2;
1130
1131                 while (pos + 1 < end && pos + 2 + pos[1] <= end) {
1132                         u8 ielen = 2 + pos[1];
1133
1134                         if (ielen > SSID_MAX_WPA_IE_LEN) {
1135                                 pos += ielen;
1136                                 continue;
1137                         }
1138
1139                         if (pos[0] == WLAN_EID_VENDOR_SPECIFIC &&
1140                             pos[1] >= 4 &&
1141                             os_memcmp(pos + 2, "\x00\x50\xf2\x01", 4) == 0) {
1142                                 os_memcpy(results[ap_num].wpa_ie, pos, ielen);
1143                                 results[ap_num].wpa_ie_len = ielen;
1144                         } else if (pos[0] == WLAN_EID_RSN) {
1145                                 os_memcpy(results[ap_num].rsn_ie, pos, ielen);
1146                                 results[ap_num].rsn_ie_len = ielen;
1147                         }
1148                         pos += ielen;
1149                 }
1150
1151                 wbi = (NDIS_WLAN_BSSID_EX *) ((u8 *) wbi + wbi->Length);
1152         }
1153
1154         os_free(buf);
1155         return ap_num;
1156 }
1157
1158 static int ralink_set_auth_mode(struct wpa_driver_ralink_data *drv,
1159                                 NDIS_802_11_AUTHENTICATION_MODE mode)
1160 {
1161         NDIS_802_11_AUTHENTICATION_MODE auth_mode = mode;
1162
1163         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1164
1165         if (ralink_set_oid(drv, OID_802_11_AUTHENTICATION_MODE,
1166                            (char *) &auth_mode, sizeof(auth_mode)) < 0) {
1167                 wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
1168                            "OID_802_11_AUTHENTICATION_MODE (%d)",
1169                            (int) auth_mode);
1170                 return -1;
1171         }
1172         return 0;
1173 }
1174
1175 static int wpa_driver_ralink_remove_key(struct wpa_driver_ralink_data *drv,
1176                                         int key_idx, const u8 *addr,
1177                                         const u8 *bssid, int pairwise)
1178 {
1179         NDIS_802_11_REMOVE_KEY rkey;
1180         NDIS_802_11_KEY_INDEX _index;
1181         int res, res2;
1182
1183         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1184
1185         os_memset(&rkey, 0, sizeof(rkey));
1186
1187         rkey.Length = sizeof(rkey);
1188         rkey.KeyIndex = key_idx;
1189
1190         if (pairwise)
1191                 rkey.KeyIndex |= 1 << 30;
1192
1193         os_memcpy(rkey.BSSID, bssid, ETH_ALEN);
1194
1195         res = ralink_set_oid(drv, OID_802_11_REMOVE_KEY, (char *) &rkey,
1196                              sizeof(rkey));
1197
1198         /* AlbertY@20060210 removed it */
1199         if (0 /* !pairwise */) {
1200                 res2 = ralink_set_oid(drv, OID_802_11_REMOVE_WEP,
1201                                       (char *) &_index, sizeof(_index));
1202         } else
1203                 res2 = 0;
1204
1205         if (res < 0 && res2 < 0)
1206                 return res;
1207         return 0;
1208 }
1209
1210 static int wpa_driver_ralink_add_wep(struct wpa_driver_ralink_data *drv,
1211                                      int pairwise, int key_idx, int set_tx,
1212                                      const u8 *key, size_t key_len)
1213 {
1214         NDIS_802_11_WEP *wep;
1215         size_t len;
1216         int res;
1217
1218         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1219
1220         len = 12 + key_len;
1221         wep = os_zalloc(len);
1222         if (wep == NULL)
1223                 return -1;
1224
1225         wep->Length = len;
1226         wep->KeyIndex = key_idx;
1227
1228         if (set_tx)
1229                 wep->KeyIndex |= 0x80000000;
1230
1231         wep->KeyLength = key_len;
1232         os_memcpy(wep->KeyMaterial, key, key_len);
1233
1234         wpa_hexdump_key(MSG_MSGDUMP, "RALINK: OID_802_11_ADD_WEP",
1235                         (const u8 *) wep, len);
1236         res = ralink_set_oid(drv, OID_802_11_ADD_WEP, (char *) wep, len);
1237
1238         os_free(wep);
1239
1240         return res;
1241 }
1242
1243 static int wpa_driver_ralink_set_key(void *priv, wpa_alg alg, const u8 *addr,
1244                                      int key_idx, int set_tx,
1245                                      const u8 *seq, size_t seq_len,
1246                                      const u8 *key, size_t key_len)
1247 {
1248         struct wpa_driver_ralink_data *drv = priv;
1249         size_t len, i;
1250         NDIS_802_11_KEY *nkey;
1251         int res, pairwise;
1252         u8 bssid[ETH_ALEN];
1253
1254         if (drv->g_driver_down == 1)
1255                 return -1;
1256
1257         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1258
1259         if (addr == NULL || os_memcmp(addr, "\xff\xff\xff\xff\xff\xff",
1260                                       ETH_ALEN) == 0) {
1261                 /* Group Key */
1262                 pairwise = 0;
1263                 wpa_driver_ralink_get_bssid(drv, bssid);
1264         } else {
1265                 /* Pairwise Key */
1266                 pairwise = 1;
1267                 os_memcpy(bssid, addr, ETH_ALEN);
1268         }
1269
1270         if (alg == WPA_ALG_NONE || key_len == 0) {
1271                 return wpa_driver_ralink_remove_key(drv, key_idx, addr, bssid,
1272                                                     pairwise);
1273         }
1274
1275         if (alg == WPA_ALG_WEP) {
1276                 return wpa_driver_ralink_add_wep(drv, pairwise, key_idx,
1277                                                  set_tx, key, key_len);
1278         }
1279
1280         len = 12 + 6 + 6 + 8 + key_len;
1281
1282         nkey = os_zalloc(len);
1283         if (nkey == NULL)
1284                 return -1;
1285
1286         nkey->Length = len;
1287         nkey->KeyIndex = key_idx;
1288
1289         if (set_tx)
1290                 nkey->KeyIndex |= 1 << 31;
1291
1292         if (pairwise)
1293                 nkey->KeyIndex |= 1 << 30;
1294
1295         if (seq && seq_len)
1296                 nkey->KeyIndex |= 1 << 29;
1297
1298         nkey->KeyLength = key_len;
1299         os_memcpy(nkey->BSSID, bssid, ETH_ALEN);
1300
1301         if (seq && seq_len) {
1302                 for (i = 0; i < seq_len; i++)
1303                         nkey->KeyRSC |= seq[i] << (i * 8);
1304         }
1305         if (alg == WPA_ALG_TKIP && key_len == 32) {
1306                 os_memcpy(nkey->KeyMaterial, key, 16);
1307                 os_memcpy(nkey->KeyMaterial + 16, key + 24, 8);
1308                 os_memcpy(nkey->KeyMaterial + 24, key + 16, 8);
1309         } else {
1310                 os_memcpy(nkey->KeyMaterial, key, key_len);
1311         }
1312
1313         wpa_printf(MSG_DEBUG, "%s: alg=%d key_idx=%d set_tx=%d seq_len=%lu "
1314                    "key_len=%lu", __FUNCTION__, alg, key_idx, set_tx,
1315                    (unsigned long) seq_len, (unsigned long) key_len);
1316
1317         wpa_hexdump_key(MSG_MSGDUMP, "RALINK: OID_802_11_ADD_KEY",
1318                         (const u8 *) nkey, len);
1319         res = ralink_set_oid(drv, OID_802_11_ADD_KEY, (char *) nkey, len);
1320         os_free(nkey);
1321
1322         return res;
1323 }
1324
1325 static int wpa_driver_ralink_disassociate(void *priv, const u8 *addr,
1326                                         int reason_code)
1327 {
1328         struct wpa_driver_ralink_data *drv = priv;
1329
1330         if (drv->g_driver_down == 1)
1331                 return -1;
1332         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1333         if (ralink_set_oid(drv, OID_802_11_DISASSOCIATE, "    ", 4) < 0) {
1334                 wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
1335                            "OID_802_11_DISASSOCIATE");
1336         }
1337
1338         return 0;
1339 }
1340
1341 static int wpa_driver_ralink_deauthenticate(void *priv, const u8 *addr,
1342                                           int reason_code)
1343 {
1344         struct wpa_driver_ralink_data *drv = priv;
1345
1346         wpa_printf(MSG_DEBUG, "g_driver_down = %d", drv->g_driver_down);
1347
1348         if (drv->g_driver_down == 1)
1349                 return -1;
1350
1351         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1352         if (ralink_get_new_driver_flag(drv) == 0) {
1353                 return wpa_driver_ralink_disassociate(priv, addr, reason_code);
1354         } else {
1355                 MLME_DEAUTH_REQ_STRUCT mlme;
1356                 os_memset(&mlme, 0, sizeof(MLME_DEAUTH_REQ_STRUCT));
1357                 mlme.Reason = reason_code;
1358                 os_memcpy(mlme.Addr, addr, MAC_ADDR_LEN);
1359                 return ralink_set_oid(drv, OID_802_11_DEAUTHENTICATION,
1360                                       (char *) &mlme,
1361                                       sizeof(MLME_DEAUTH_REQ_STRUCT));
1362         }
1363 }
1364
1365 static int
1366 wpa_driver_ralink_associate(void *priv,
1367                             struct wpa_driver_associate_params *params)
1368 {
1369         struct wpa_driver_ralink_data *drv = priv;
1370
1371         NDIS_802_11_NETWORK_INFRASTRUCTURE mode;
1372         NDIS_802_11_AUTHENTICATION_MODE auth_mode;
1373         NDIS_802_11_WEP_STATUS encr;
1374         BOOLEAN         ieee8021xMode;
1375
1376         if (drv->g_driver_down == 1)
1377                 return -1;
1378         wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1379
1380         if (params->mode == IEEE80211_MODE_IBSS)
1381                 mode = Ndis802_11IBSS;
1382         else
1383                 mode = Ndis802_11Infrastructure;
1384
1385         if (ralink_set_oid(drv, OID_802_11_INFRASTRUCTURE_MODE,
1386                          (char *) &mode, sizeof(mode)) < 0) {
1387                 wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
1388                            "OID_802_11_INFRASTRUCTURE_MODE (%d)",
1389                            (int) mode);
1390                 /* Try to continue anyway */
1391         }
1392
1393         if (params->wpa_ie == NULL || params->wpa_ie_len == 0) {
1394                 if (params->auth_alg & AUTH_ALG_SHARED_KEY) {
1395                         if (params->auth_alg & AUTH_ALG_OPEN_SYSTEM)
1396                                 auth_mode = Ndis802_11AuthModeAutoSwitch;
1397                         else
1398                                 auth_mode = Ndis802_11AuthModeShared;
1399                 } else
1400                         auth_mode = Ndis802_11AuthModeOpen;
1401         } else if (params->wpa_ie[0] == WLAN_EID_RSN) {
1402                 if (params->key_mgmt_suite == KEY_MGMT_PSK)
1403                         auth_mode = Ndis802_11AuthModeWPA2PSK;
1404                 else
1405                         auth_mode = Ndis802_11AuthModeWPA2;
1406         } else {
1407                 if (params->key_mgmt_suite == KEY_MGMT_WPA_NONE)
1408                         auth_mode = Ndis802_11AuthModeWPANone;
1409                 else if (params->key_mgmt_suite == KEY_MGMT_PSK)
1410                         auth_mode = Ndis802_11AuthModeWPAPSK;
1411                 else
1412                         auth_mode = Ndis802_11AuthModeWPA;
1413         }
1414
1415         switch (params->pairwise_suite) {
1416         case CIPHER_CCMP:
1417                 encr = Ndis802_11Encryption3Enabled;
1418                 break;
1419         case CIPHER_TKIP:
1420                 encr = Ndis802_11Encryption2Enabled;
1421                 break;
1422         case CIPHER_WEP40:
1423         case CIPHER_WEP104:
1424                 encr = Ndis802_11Encryption1Enabled;
1425                 break;
1426         case CIPHER_NONE:
1427                 if (params->group_suite == CIPHER_CCMP)
1428                         encr = Ndis802_11Encryption3Enabled;
1429                 else if (params->group_suite == CIPHER_TKIP)
1430                         encr = Ndis802_11Encryption2Enabled;
1431                 else
1432                         encr = Ndis802_11EncryptionDisabled;
1433                 break;
1434         default:
1435                 encr = Ndis802_11EncryptionDisabled;
1436                 break;
1437         }
1438
1439         ralink_set_auth_mode(drv, auth_mode);
1440
1441         /* notify driver that IEEE8021x mode is enabled */
1442         if (params->key_mgmt_suite == KEY_MGMT_802_1X_NO_WPA)
1443                 ieee8021xMode = TRUE;
1444         else
1445                 ieee8021xMode = FALSE;
1446
1447         if (ralink_set_oid(drv, OID_802_11_SET_IEEE8021X,
1448                            (char *) &ieee8021xMode, sizeof(BOOLEAN)) < 0) {
1449                 wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
1450                            "OID_802_11_SET_IEEE8021X(%d)",
1451                            (int) ieee8021xMode);
1452         }
1453
1454         if (ralink_set_oid(drv, OID_802_11_WEP_STATUS,
1455                          (char *) &encr, sizeof(encr)) < 0) {
1456                 wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
1457                            "OID_802_11_WEP_STATUS(%d)",
1458                            (int) encr);
1459         }
1460
1461         if ((ieee8021xMode == FALSE) &&
1462             (encr == Ndis802_11Encryption1Enabled)) {
1463                 /* static WEP */
1464                 int enabled = 0;
1465                 if (ralink_set_oid(drv, OID_802_11_DROP_UNENCRYPTED,
1466                                    (char *) &enabled, sizeof(enabled)) < 0) {
1467                         wpa_printf(MSG_DEBUG, "RALINK: Failed to set "
1468                                    "OID_802_11_DROP_UNENCRYPTED(%d)",
1469                                    (int) encr);
1470                 }
1471         }
1472
1473         return wpa_driver_ralink_set_ssid(drv, params->ssid, params->ssid_len);
1474 }
1475
1476 static int
1477 wpa_driver_ralink_set_countermeasures(void *priv, int enabled)
1478 {
1479         struct wpa_driver_ralink_data *drv = priv;
1480         if (drv->g_driver_down == 1)
1481                 return -1;
1482         wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
1483         return ralink_set_oid(drv, OID_SET_COUNTERMEASURES, (char *) &enabled,
1484                               sizeof(int));
1485 }
1486
1487 const struct wpa_driver_ops wpa_driver_ralink_ops = {
1488         .name = "ralink",
1489         .desc = "Ralink Wireless Client driver",
1490         .get_bssid = wpa_driver_ralink_get_bssid,
1491         .get_ssid = wpa_driver_ralink_get_ssid,
1492         .set_key = wpa_driver_ralink_set_key,
1493         .init = wpa_driver_ralink_init,
1494         .deinit = wpa_driver_ralink_deinit,
1495         .set_countermeasures    = wpa_driver_ralink_set_countermeasures,
1496         .scan = wpa_driver_ralink_scan,
1497         .get_scan_results = wpa_driver_ralink_get_scan_results,
1498         .deauthenticate = wpa_driver_ralink_deauthenticate,
1499         .disassociate = wpa_driver_ralink_disassociate,
1500         .associate = wpa_driver_ralink_associate,
1501         .add_pmkid = wpa_driver_ralink_add_pmkid,
1502         .remove_pmkid = wpa_driver_ralink_remove_pmkid,
1503         .flush_pmkid = wpa_driver_ralink_flush_pmkid,
1504 };