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