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;
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
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};
1506