1/*
2 * WPA Supplicant - driver interaction with BSD net80211 layer
3 * Copyright (c) 2004, Sam Leffler <sam@errno.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * Alternatively, this software may be distributed under the terms of BSD
10 * license.
11 *
12 * See README and COPYING for more details.
13 *
14 * $FreeBSD$
15 */
16
17#include <stdlib.h>
18#include <stdio.h>
19#include <unistd.h>
20#include <string.h>
21#include <sys/ioctl.h>
22#include <errno.h>
23
24#include "common.h"
25#include "driver.h"
26#include "eloop.h"
27#include "l2_packet.h"
28#include "ieee802_11_defs.h"
29
30#include <sys/socket.h>
31#include <net/if.h>
32#include <net/if_media.h>
33#include <net/ethernet.h>
34
35#include <net80211/ieee80211_ioctl.h>
36
37struct wpa_driver_bsd_data {
38	int	sock;			/* open socket for 802.11 ioctls */
39	int	route;			/* routing socket for events */
40	char	ifname[IFNAMSIZ+1];	/* interface name */
41	unsigned int ifindex;		/* interface index */
42	void	*ctx;
43	int	prev_roaming;		/* roaming state to restore on deinit */
44	int	prev_privacy;		/* privacy state to restore on deinit */
45	int	prev_wpa;		/* wpa state to restore on deinit */
46	int	prev_scanvalid;		/* scan valid to restore on deinit */
47	uint8_t	lastssid[IEEE80211_NWID_LEN];
48	int	lastssid_len;
49	uint32_t drivercaps;		/* general driver capabilities */
50	uint32_t cryptocaps;		/* hardware crypto support */
51	enum ieee80211_opmode opmode;	/* operation mode */
52};
53
54static enum ieee80211_opmode
55get80211opmode(struct wpa_driver_bsd_data *drv)
56{
57	struct ifmediareq ifmr;
58
59	(void) memset(&ifmr, 0, sizeof(ifmr));
60	(void) strncpy(ifmr.ifm_name, drv->ifname, sizeof(ifmr.ifm_name));
61
62	if (ioctl(drv->sock, SIOCGIFMEDIA, (caddr_t)&ifmr) >= 0) {
63		if (ifmr.ifm_current & IFM_IEEE80211_ADHOC) {
64			if (ifmr.ifm_current & IFM_FLAG0)
65				return IEEE80211_M_AHDEMO;
66			else
67				return IEEE80211_M_IBSS;
68		}
69		if (ifmr.ifm_current & IFM_IEEE80211_HOSTAP)
70			return IEEE80211_M_HOSTAP;
71		if (ifmr.ifm_current & IFM_IEEE80211_MONITOR)
72			return IEEE80211_M_MONITOR;
73		if (ifmr.ifm_current & IFM_IEEE80211_MBSS)
74			return IEEE80211_M_MBSS;
75	}
76	return IEEE80211_M_STA;
77}
78
79static int
80set80211var(struct wpa_driver_bsd_data *drv, int op, const void *arg, int arg_len)
81{
82	struct ieee80211req ireq;
83
84	memset(&ireq, 0, sizeof(ireq));
85	strncpy(ireq.i_name, drv->ifname, IFNAMSIZ);
86	ireq.i_type = op;
87	ireq.i_len = arg_len;
88	ireq.i_data = (void *) arg;
89
90	if (ioctl(drv->sock, SIOCS80211, &ireq) < 0) {
91		fprintf(stderr, "ioctl[SIOCS80211, op %u, len %u]: %s\n",
92			op, arg_len, strerror(errno));
93		return -1;
94	}
95	return 0;
96}
97
98static int
99get80211var(struct wpa_driver_bsd_data *drv, int op, void *arg, int arg_len)
100{
101	struct ieee80211req ireq;
102
103	memset(&ireq, 0, sizeof(ireq));
104	strncpy(ireq.i_name, drv->ifname, IFNAMSIZ);
105	ireq.i_type = op;
106	ireq.i_len = arg_len;
107	ireq.i_data = arg;
108
109	if (ioctl(drv->sock, SIOCG80211, &ireq) < 0) {
110		fprintf(stderr, "ioctl[SIOCG80211, op %u, len %u]: %s\n",
111			op, arg_len, strerror(errno));
112		return -1;
113	}
114	return ireq.i_len;
115}
116
117static int
118set80211param(struct wpa_driver_bsd_data *drv, int op, int arg)
119{
120	struct ieee80211req ireq;
121
122	memset(&ireq, 0, sizeof(ireq));
123	strncpy(ireq.i_name, drv->ifname, IFNAMSIZ);
124	ireq.i_type = op;
125	ireq.i_val = arg;
126
127	if (ioctl(drv->sock, SIOCS80211, &ireq) < 0) {
128		fprintf(stderr, "ioctl[SIOCS80211, op %u, arg 0x%x]: %s\n",
129			op, arg, strerror(errno));
130		return -1;
131	}
132	return 0;
133}
134
135static int
136get80211param(struct wpa_driver_bsd_data *drv, int op)
137{
138	struct ieee80211req ireq;
139
140	memset(&ireq, 0, sizeof(ireq));
141	strncpy(ireq.i_name, drv->ifname, IFNAMSIZ);
142	ireq.i_type = op;
143
144	if (ioctl(drv->sock, SIOCG80211, &ireq) < 0) {
145		fprintf(stderr, "ioctl[SIOCG80211, op %u]: %s\n",
146			op, strerror(errno));
147		return -1;
148	}
149	return ireq.i_val;
150}
151
152static int
153getifflags(struct wpa_driver_bsd_data *drv, int *flags)
154{
155	struct ifreq ifr;
156
157	memset(&ifr, 0, sizeof(ifr));
158	strncpy(ifr.ifr_name, drv->ifname, sizeof (ifr.ifr_name));
159	if (ioctl(drv->sock, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
160		perror("SIOCGIFFLAGS");
161		return errno;
162	}
163	*flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16);
164	return 0;
165}
166
167static int
168setifflags(struct wpa_driver_bsd_data *drv, int flags)
169{
170	struct ifreq ifr;
171
172	memset(&ifr, 0, sizeof(ifr));
173	strncpy(ifr.ifr_name, drv->ifname, sizeof (ifr.ifr_name));
174	ifr.ifr_flags = flags & 0xffff;
175	ifr.ifr_flagshigh = flags >> 16;
176	if (ioctl(drv->sock, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) {
177		perror("SIOCSIFFLAGS");
178		return errno;
179	}
180	return 0;
181}
182
183static int
184wpa_driver_bsd_get_bssid(void *priv, u8 *bssid)
185{
186	struct wpa_driver_bsd_data *drv = priv;
187
188	return get80211var(drv, IEEE80211_IOC_BSSID,
189		bssid, IEEE80211_ADDR_LEN) < 0 ? -1 : 0;
190}
191
192#if 0
193static int
194wpa_driver_bsd_set_bssid(void *priv, const char *bssid)
195{
196	struct wpa_driver_bsd_data *drv = priv;
197
198	return set80211var(drv, IEEE80211_IOC_BSSID,
199		bssid, IEEE80211_ADDR_LEN);
200}
201#endif
202
203static int
204wpa_driver_bsd_get_ssid(void *priv, u8 *ssid)
205{
206	struct wpa_driver_bsd_data *drv = priv;
207
208	return get80211var(drv, IEEE80211_IOC_SSID,
209		ssid, IEEE80211_NWID_LEN);
210}
211
212static int
213wpa_driver_bsd_set_ssid(void *priv, const char *ssid,
214			     size_t ssid_len)
215{
216	struct wpa_driver_bsd_data *drv = priv;
217
218	return set80211var(drv, IEEE80211_IOC_SSID, ssid, ssid_len);
219}
220
221static int
222wpa_driver_bsd_set_wpa_ie(struct wpa_driver_bsd_data *drv,
223	const u8 *wpa_ie, size_t wpa_ie_len)
224{
225	struct ieee80211req ireq;
226
227	memset(&ireq, 0, sizeof(ireq));
228	strncpy(ireq.i_name, drv->ifname, IFNAMSIZ);
229	ireq.i_type = IEEE80211_IOC_APPIE;
230	ireq.i_val = IEEE80211_APPIE_WPA;
231	ireq.i_len = wpa_ie_len;
232	ireq.i_data = (void *) wpa_ie;
233	if (ioctl(drv->sock, SIOCS80211, &ireq) < 0) {
234		fprintf(stderr,
235		    "ioctl[IEEE80211_IOC_APPIE:IEEE80211_APPIE_WPA]: %s\n",
236		    strerror(errno));
237		return -1;
238	}
239	return 0;
240}
241
242static int
243wpa_driver_bsd_set_wpa_internal(void *priv, int wpa, int privacy)
244{
245	struct wpa_driver_bsd_data *drv = priv;
246	int ret = 0;
247
248	wpa_printf(MSG_DEBUG, "%s: wpa=%d privacy=%d",
249		__FUNCTION__, wpa, privacy);
250
251	if (!wpa && wpa_driver_bsd_set_wpa_ie(drv, NULL, 0) < 0)
252		ret = -1;
253	if (set80211param(drv, IEEE80211_IOC_PRIVACY, privacy) < 0)
254		ret = -1;
255	if (set80211param(drv, IEEE80211_IOC_WPA, wpa) < 0)
256		ret = -1;
257
258	return ret;
259}
260
261static int
262wpa_driver_bsd_del_key(struct wpa_driver_bsd_data *drv, int key_idx,
263		       const unsigned char *addr)
264{
265	struct ieee80211req_del_key wk;
266
267	memset(&wk, 0, sizeof(wk));
268	if (addr != NULL &&
269	    bcmp(addr, "\xff\xff\xff\xff\xff\xff", IEEE80211_ADDR_LEN) != 0) {
270		struct ether_addr ea;
271
272		memcpy(&ea, addr, IEEE80211_ADDR_LEN);
273		wpa_printf(MSG_DEBUG, "%s: addr=%s keyidx=%d",
274			__func__, ether_ntoa(&ea), key_idx);
275		memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN);
276		wk.idk_keyix = (uint8_t) IEEE80211_KEYIX_NONE;
277	} else {
278		wpa_printf(MSG_DEBUG, "%s: keyidx=%d", __func__, key_idx);
279		wk.idk_keyix = key_idx;
280	}
281	return set80211var(drv, IEEE80211_IOC_DELKEY, &wk, sizeof(wk));
282}
283
284static int
285wpa_driver_bsd_set_key(const char *ifname, void *priv, enum wpa_alg alg,
286		       const unsigned char *addr, int key_idx, int set_tx,
287		       const u8 *seq, size_t seq_len,
288		       const u8 *key, size_t key_len)
289{
290	struct wpa_driver_bsd_data *drv = priv;
291	struct ieee80211req_key wk;
292	struct ether_addr ea;
293	char *alg_name;
294	u_int8_t cipher;
295
296	if (alg == WPA_ALG_NONE)
297		return wpa_driver_bsd_del_key(drv, key_idx, addr);
298
299	switch (alg) {
300	case WPA_ALG_WEP:
301		alg_name = "WEP";
302		cipher = IEEE80211_CIPHER_WEP;
303		break;
304	case WPA_ALG_TKIP:
305		alg_name = "TKIP";
306		cipher = IEEE80211_CIPHER_TKIP;
307		break;
308	case WPA_ALG_CCMP:
309		alg_name = "CCMP";
310		cipher = IEEE80211_CIPHER_AES_CCM;
311		break;
312	default:
313		wpa_printf(MSG_DEBUG, "%s: unknown/unsupported algorithm %d",
314			__func__, alg);
315		return -1;
316	}
317
318	memcpy(&ea, addr, IEEE80211_ADDR_LEN);
319	wpa_printf(MSG_DEBUG,
320	    "%s: alg=%s addr=%s key_idx=%d set_tx=%d seq_len=%zu key_len=%zu",
321	    __func__, alg_name, ether_ntoa(&ea), key_idx, set_tx,
322	    seq_len, key_len);
323
324	if (seq_len > sizeof(u_int64_t)) {
325		wpa_printf(MSG_DEBUG, "%s: seq_len %zu too big",
326			__func__, seq_len);
327		return -2;
328	}
329	if (key_len > sizeof(wk.ik_keydata)) {
330		wpa_printf(MSG_DEBUG, "%s: key length %zu too big",
331			__func__, key_len);
332		return -3;
333	}
334
335	memset(&wk, 0, sizeof(wk));
336	wk.ik_type = cipher;
337	wk.ik_flags = IEEE80211_KEY_RECV;
338	if (set_tx)
339		wk.ik_flags |= IEEE80211_KEY_XMIT;
340	memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
341	/*
342	 * Deduce whether group/global or unicast key by checking
343	 * the address (yech).  Note also that we can only mark global
344	 * keys default; doing this for a unicast key is an error.
345	 */
346	if (bcmp(addr, "\xff\xff\xff\xff\xff\xff", IEEE80211_ADDR_LEN) == 0) {
347		wk.ik_flags |= IEEE80211_KEY_GROUP;
348		wk.ik_keyix = key_idx;
349	} else {
350		wk.ik_keyix = (key_idx == 0 ? IEEE80211_KEYIX_NONE : key_idx);
351	}
352	if (wk.ik_keyix != IEEE80211_KEYIX_NONE && set_tx)
353		wk.ik_flags |= IEEE80211_KEY_DEFAULT;
354	/*
355	 * Ignore replay failures in IBSS and AHDEMO mode.
356	 */
357	if (drv->opmode == IEEE80211_M_IBSS ||
358	    drv->opmode == IEEE80211_M_AHDEMO)
359		wk.ik_flags |= IEEE80211_KEY_NOREPLAY;
360	wk.ik_keylen = key_len;
361	memcpy(&wk.ik_keyrsc, seq, seq_len);
362	wk.ik_keyrsc = le64toh(wk.ik_keyrsc);
363	memcpy(wk.ik_keydata, key, key_len);
364
365	return set80211var(drv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk));
366}
367
368static int
369wpa_driver_bsd_set_countermeasures(void *priv, int enabled)
370{
371	struct wpa_driver_bsd_data *drv = priv;
372
373	wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
374	return set80211param(drv, IEEE80211_IOC_COUNTERMEASURES, enabled);
375}
376
377
378static int
379wpa_driver_bsd_set_drop_unencrypted(void *priv, int enabled)
380{
381	struct wpa_driver_bsd_data *drv = priv;
382
383	wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
384	return set80211param(drv, IEEE80211_IOC_DROPUNENCRYPTED, enabled);
385}
386
387static int
388wpa_driver_bsd_set_auth_alg(void *priv, int auth_alg)
389{
390	struct wpa_driver_bsd_data *drv = priv;
391	int authmode;
392
393	if ((auth_alg & WPA_AUTH_ALG_OPEN) &&
394	    (auth_alg & WPA_AUTH_ALG_SHARED))
395		authmode = IEEE80211_AUTH_AUTO;
396	else if (auth_alg & WPA_AUTH_ALG_SHARED)
397		authmode = IEEE80211_AUTH_SHARED;
398	else
399		authmode = IEEE80211_AUTH_OPEN;
400
401	wpa_printf(MSG_DEBUG, "%s alg 0x%x authmode %u",
402		__func__, auth_alg, authmode);
403
404	return set80211param(drv, IEEE80211_IOC_AUTHMODE, authmode);
405}
406
407static int
408wpa_driver_bsd_deauthenticate(void *priv, const u8 *addr, int reason_code)
409{
410	struct wpa_driver_bsd_data *drv = priv;
411	struct ieee80211req_mlme mlme;
412
413	drv->lastssid_len = 0;
414
415	wpa_printf(MSG_DEBUG, "%s", __func__);
416	memset(&mlme, 0, sizeof(mlme));
417	mlme.im_op = IEEE80211_MLME_DEAUTH;
418	mlme.im_reason = reason_code;
419	memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
420	return set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme));
421}
422
423static int
424wpa_driver_bsd_disassociate(void *priv, const u8 *addr, int reason_code)
425{
426	struct wpa_driver_bsd_data *drv = priv;
427	struct ieee80211req_mlme mlme;
428
429	drv->lastssid_len = 0;
430
431	wpa_printf(MSG_DEBUG, "%s", __func__);
432	memset(&mlme, 0, sizeof(mlme));
433	mlme.im_op = IEEE80211_MLME_DISASSOC;
434	mlme.im_reason = reason_code;
435	memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
436	return set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme));
437}
438
439static int
440wpa_driver_bsd_associate(void *priv, struct wpa_driver_associate_params *params)
441{
442	struct wpa_driver_bsd_data *drv = priv;
443	struct ieee80211req_mlme mlme;
444	int flags, privacy;
445
446	wpa_printf(MSG_DEBUG,
447		"%s: ssid '%.*s' wpa ie len %u pairwise %u group %u key mgmt %u"
448		, __func__
449		, params->ssid_len, params->ssid
450		, params->wpa_ie_len
451		, params->pairwise_suite
452		, params->group_suite
453		, params->key_mgmt_suite
454	);
455
456	/* NB: interface must be marked UP to associate */
457	if (getifflags(drv, &flags) != 0) {
458		wpa_printf(MSG_DEBUG, "%s did not mark interface UP", __func__);
459		return -1;
460	}
461	if ((flags & IFF_UP) == 0 && setifflags(drv, flags | IFF_UP) != 0) {
462		wpa_printf(MSG_DEBUG, "%s unable to mark interface UP",
463		    __func__);
464		return -1;
465	}
466
467        if (wpa_driver_bsd_set_drop_unencrypted(drv, params->drop_unencrypted)
468            < 0)
469                return -1;
470	if (wpa_driver_bsd_set_auth_alg(drv, params->auth_alg) < 0)
471		return -1;
472	/* XXX error handling is wrong but unclear what to do... */
473	if (wpa_driver_bsd_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0)
474		return -1;
475
476	privacy = !(params->pairwise_suite == CIPHER_NONE &&
477	    params->group_suite == CIPHER_NONE &&
478	    params->key_mgmt_suite == KEY_MGMT_NONE &&
479	    params->wpa_ie_len == 0);
480	wpa_printf(MSG_DEBUG, "%s: set PRIVACY %u", __func__, privacy);
481
482	if (set80211param(drv, IEEE80211_IOC_PRIVACY, privacy) < 0)
483		return -1;
484
485	if (params->wpa_ie_len &&
486	    set80211param(drv, IEEE80211_IOC_WPA,
487			  params->wpa_ie[0] == WLAN_EID_RSN ? 2 : 1) < 0)
488		return -1;
489
490	memset(&mlme, 0, sizeof(mlme));
491	mlme.im_op = IEEE80211_MLME_ASSOC;
492	if (params->ssid != NULL)
493		memcpy(mlme.im_ssid, params->ssid, params->ssid_len);
494	mlme.im_ssid_len = params->ssid_len;
495	if (params->bssid != NULL)
496		memcpy(mlme.im_macaddr, params->bssid, IEEE80211_ADDR_LEN);
497	if (set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)) < 0)
498		return -1;
499	memcpy(drv->lastssid, params->ssid, params->ssid_len);
500	drv->lastssid_len = params->ssid_len;
501	return 0;
502}
503
504static int
505wpa_driver_bsd_scan(void *priv, struct wpa_driver_scan_params *params)
506{
507	struct wpa_driver_bsd_data *drv = priv;
508	struct ieee80211_scan_req sr;
509	int i;
510	int flags;
511
512	/* XXX not true but easiest to perpetuate the myth */
513	/* NB: interface must be marked UP to do a scan */
514	if (getifflags(drv, &flags) != 0) {
515		wpa_printf(MSG_DEBUG, "%s did not mark interface UP", __func__);
516		return -1;
517	}
518	if ((flags & IFF_UP) == 0 && setifflags(drv, flags | IFF_UP) != 0) {
519		wpa_printf(MSG_DEBUG, "%s unable to mark interface UP",
520		    __func__);
521		return -1;
522	}
523
524	memset(&sr, 0, sizeof(sr));
525	sr.sr_flags = IEEE80211_IOC_SCAN_ACTIVE
526		    | IEEE80211_IOC_SCAN_ONCE
527		    | IEEE80211_IOC_SCAN_NOJOIN
528		    ;
529	sr.sr_duration = IEEE80211_IOC_SCAN_FOREVER;
530	if (params->num_ssids > 0) {
531		sr.sr_nssid = params->num_ssids;
532#if 0
533		/* Boundary check is done by upper layer */
534		if (sr.sr_nssid > IEEE80211_IOC_SCAN_MAX_SSID)
535			sr.sr_nssid = IEEE80211_IOC_SCAN_MAX_SSID;
536#endif
537		/* NB: check scan cache first */
538		sr.sr_flags |= IEEE80211_IOC_SCAN_CHECK;
539}
540	for (i = 0; i < sr.sr_nssid; i++) {
541		sr.sr_ssid[i].len = params->ssids[i].ssid_len;
542		os_memcpy(sr.sr_ssid[i].ssid, params->ssids[i].ssid,
543			  sr.sr_ssid[i].len);
544	}
545	/* NB: net80211 delivers a scan complete event so no need to poll */
546	return set80211var(drv, IEEE80211_IOC_SCAN_REQ, &sr, sizeof(sr));
547}
548
549#include <net/route.h>
550#include <net80211/ieee80211_freebsd.h>
551
552static void
553wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
554{
555	struct wpa_driver_bsd_data *drv = sock_ctx;
556	char buf[2048];
557	struct if_announcemsghdr *ifan;
558	struct if_msghdr *ifm;
559	struct rt_msghdr *rtm;
560	union wpa_event_data event;
561	struct ieee80211_michael_event *mic;
562	int n;
563
564	n = read(sock, buf, sizeof(buf));
565	if (n < 0) {
566		if (errno != EINTR && errno != EAGAIN)
567			perror("read(PF_ROUTE)");
568		return;
569	}
570
571	rtm = (struct rt_msghdr *) buf;
572	if (rtm->rtm_version != RTM_VERSION) {
573		wpa_printf(MSG_DEBUG, "Routing message version %d not "
574			"understood\n", rtm->rtm_version);
575		return;
576	}
577	memset(&event, 0, sizeof(event));
578	switch (rtm->rtm_type) {
579	case RTM_IFANNOUNCE:
580		ifan = (struct if_announcemsghdr *) rtm;
581		if (ifan->ifan_index != drv->ifindex)
582			break;
583		strlcpy(event.interface_status.ifname, drv->ifname,
584			sizeof(event.interface_status.ifname));
585		switch (ifan->ifan_what) {
586		case IFAN_DEPARTURE:
587			event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
588		default:
589			return;
590		}
591		wpa_printf(MSG_DEBUG, "RTM_IFANNOUNCE: Interface '%s' %s",
592			   event.interface_status.ifname,
593			   ifan->ifan_what == IFAN_DEPARTURE ?
594				"removed" : "added");
595		wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);
596		break;
597	case RTM_IEEE80211:
598		ifan = (struct if_announcemsghdr *) rtm;
599		if (ifan->ifan_index != drv->ifindex)
600			break;
601		switch (ifan->ifan_what) {
602		case RTM_IEEE80211_ASSOC:
603		case RTM_IEEE80211_REASSOC:
604			wpa_supplicant_event(ctx, EVENT_ASSOC, NULL);
605			break;
606		case RTM_IEEE80211_DISASSOC:
607			wpa_supplicant_event(ctx, EVENT_DISASSOC, NULL);
608			break;
609		case RTM_IEEE80211_SCAN:
610			wpa_supplicant_event(ctx, EVENT_SCAN_RESULTS, NULL);
611			break;
612		case RTM_IEEE80211_REPLAY:
613			/* ignore */
614			break;
615		case RTM_IEEE80211_MICHAEL:
616			mic = (struct ieee80211_michael_event *) &ifan[1];
617			wpa_printf(MSG_DEBUG,
618				"Michael MIC failure wireless event: "
619				"keyix=%u src_addr=" MACSTR, mic->iev_keyix,
620				MAC2STR(mic->iev_src));
621
622			memset(&event, 0, sizeof(event));
623			event.michael_mic_failure.unicast =
624				!IEEE80211_IS_MULTICAST(mic->iev_dst);
625			wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE,
626				&event);
627			break;
628		}
629		break;
630	case RTM_IFINFO:
631		ifm = (struct if_msghdr *) rtm;
632		if (ifm->ifm_index != drv->ifindex)
633			break;
634		if ((rtm->rtm_flags & RTF_UP) == 0) {
635			strlcpy(event.interface_status.ifname, drv->ifname,
636				sizeof(event.interface_status.ifname));
637			event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
638			wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' DOWN",
639				   event.interface_status.ifname);
640			wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);
641		}
642		break;
643	}
644}
645
646static int
647getmaxrate(const uint8_t rates[15], uint8_t nrates)
648{
649	int i, maxrate = -1;
650
651	for (i = 0; i < nrates; i++) {
652		int rate = rates[i] & IEEE80211_RATE_VAL;
653		if (rate > maxrate)
654			rate = maxrate;
655	}
656	return maxrate;
657}
658
659/* unalligned little endian access */
660#define LE_READ_4(p)					\
661	((u_int32_t)					\
662	 ((((const u_int8_t *)(p))[0]      ) |		\
663	  (((const u_int8_t *)(p))[1] <<  8) |		\
664	  (((const u_int8_t *)(p))[2] << 16) |		\
665	  (((const u_int8_t *)(p))[3] << 24)))
666
667static int __inline
668iswpaoui(const u_int8_t *frm)
669{
670	return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI);
671}
672
673
674static void
675wpa_driver_bsd_add_scan_entry(struct wpa_scan_results *res,
676                              struct ieee80211req_scan_result *sr)
677{
678        struct wpa_scan_res *result, **tmp;
679        size_t extra_len;
680        u8 *pos;
681
682        extra_len = 2 + sr->isr_ssid_len;
683        extra_len += 2 + sr->isr_nrates;
684        extra_len += 3; /* ERP IE */
685        extra_len += sr->isr_ie_len;
686
687        result = os_zalloc(sizeof(*result) + extra_len);
688        if (result == NULL)
689                return;
690        os_memcpy(result->bssid, sr->isr_bssid, ETH_ALEN);
691        result->freq = sr->isr_freq;
692        result->beacon_int = sr->isr_intval;
693        result->caps = sr->isr_capinfo;
694        result->qual = sr->isr_rssi;
695        result->noise = sr->isr_noise;
696        /*
697         * the rssi value reported by the kernel is in 0.5dB steps relative to
698         * the reported noise floor. see ieee80211_node.h for details.
699         */
700        result->level = sr->isr_rssi / 2 + sr->isr_noise;
701
702        pos = (u8 *)(result + 1);
703
704        *pos++ = WLAN_EID_SSID;
705        *pos++ = sr->isr_ssid_len;
706        os_memcpy(pos, sr + 1, sr->isr_ssid_len);
707        pos += sr->isr_ssid_len;
708
709        /*
710         * Deal all rates as supported rate.
711         * Because net80211 doesn't report extended supported rate or not.
712         */
713        *pos++ = WLAN_EID_SUPP_RATES;
714        *pos++ = sr->isr_nrates;
715        os_memcpy(pos, sr->isr_rates, sr->isr_nrates);
716       pos += sr->isr_nrates;
717
718        *pos++ = WLAN_EID_ERP_INFO;
719        *pos++ = 1;
720        *pos++ = sr->isr_erp;
721
722        os_memcpy(pos, (u8 *)(sr + 1) + sr->isr_ssid_len, sr->isr_ie_len);
723        pos += sr->isr_ie_len;
724
725        result->ie_len = pos - (u8 *)(result + 1);
726
727        tmp = os_realloc(res->res,
728                         (res->num + 1) * sizeof(struct wpa_scan_res *));
729        if (tmp == NULL) {
730                os_free(result);
731                return;
732        }
733        tmp[res->num++] = result;
734        res->res = tmp;
735}
736
737static struct wpa_scan_results *
738wpa_driver_bsd_get_scan_results2(void *priv)
739{
740	struct ieee80211req_scan_result *sr;
741	struct wpa_scan_results *res;
742	int len, rest;
743	uint8_t buf[24*1024], *pos;
744
745	len = get80211var(priv, IEEE80211_IOC_SCAN_RESULTS, buf, 24*1024);
746	if (len < 0)
747		return NULL;
748
749	res = os_zalloc(sizeof(*res));
750	if (res == NULL)
751		return NULL;
752
753	pos = buf;
754	rest = len;
755	while (rest >= sizeof(struct ieee80211req_scan_result)) {
756		sr = (struct ieee80211req_scan_result *)pos;
757		wpa_driver_bsd_add_scan_entry(res, sr);
758		pos += sr->isr_len;
759		rest -= sr->isr_len;
760	}
761
762	wpa_printf(MSG_DEBUG, "Received %d bytes of scan results (%lu BSSes)",
763		len, (unsigned long)res->num);
764
765	return (res);
766}
767
768
769#define	GETPARAM(drv, param, v) \
770	(((v) = get80211param(drv, param)) != -1)
771#define	IEEE80211_C_BGSCAN	0x20000000
772
773/*
774 * Set the scan cache valid threshold to 1.5 x bg scan interval
775 * to force all scan requests to consult the cache unless they
776 * explicitly bypass it.
777 */
778static int
779setscanvalid(struct wpa_driver_bsd_data *drv)
780{
781	int bgscan, scanvalid;
782
783	if (!GETPARAM(drv, IEEE80211_IOC_SCANVALID, drv->prev_scanvalid) ||
784	    !GETPARAM(drv, IEEE80211_IOC_BGSCAN_INTERVAL, bgscan))
785		return -1;
786	scanvalid = 3*bgscan/2;
787	return (drv->prev_scanvalid < scanvalid) ?
788	    set80211param(drv, IEEE80211_IOC_SCANVALID, scanvalid) : 0;
789}
790
791static void *
792wpa_driver_bsd_init(void *ctx, const char *ifname)
793{
794	struct wpa_driver_bsd_data *drv;
795	struct ieee80211_devcaps_req devcaps;
796	int flags;
797
798	drv = malloc(sizeof(*drv));
799	if (drv == NULL)
800		return NULL;
801	memset(drv, 0, sizeof(*drv));
802	/*
803	 * NB: We require the interface name be mappable to an index.
804	 *     This implies we do not support having wpa_supplicant
805	 *     wait for an interface to appear.  This seems ok; that
806	 *     doesn't belong here; it's really the job of devd.
807	 */
808	drv->ifindex = if_nametoindex(ifname);
809	if (drv->ifindex == 0) {
810		wpa_printf(MSG_DEBUG, "%s: interface %s does not exist",
811			   __func__, ifname);
812		goto fail1;
813	}
814	drv->sock = socket(PF_INET, SOCK_DGRAM, 0);
815	if (drv->sock < 0)
816		goto fail1;
817	drv->ctx = ctx;
818	strncpy(drv->ifname, ifname, sizeof(drv->ifname));
819
820	/*
821	 * Mark the interface as down to ensure wpa_supplicant has exclusive
822	 * access to the net80211 state machine, do this before opening the
823	 * route socket to avoid a false event that the interface disappeared.
824	 */
825	if (getifflags(drv, &flags) == 0)
826		(void) setifflags(drv, flags &~ IFF_UP);
827
828	drv->route = socket(PF_ROUTE, SOCK_RAW, 0);
829	if (drv->route < 0)
830		goto fail;
831	eloop_register_read_sock(drv->route,
832		wpa_driver_bsd_event_receive, ctx, drv);
833
834	if (get80211var(drv, IEEE80211_IOC_DEVCAPS, &devcaps, sizeof(devcaps)) < 0) {
835		wpa_printf(MSG_DEBUG,
836		    "%s: failed to get device capabilities: %s",
837		    __func__, strerror(errno));
838		goto fail;
839	}
840	drv->drivercaps = devcaps.dc_drivercaps;
841	drv->cryptocaps = devcaps.dc_cryptocaps;
842
843	if (!GETPARAM(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming)) {
844		wpa_printf(MSG_DEBUG, "%s: failed to get roaming state: %s",
845			__func__, strerror(errno));
846		goto fail;
847	}
848	if (!GETPARAM(drv, IEEE80211_IOC_PRIVACY, drv->prev_privacy)) {
849		wpa_printf(MSG_DEBUG, "%s: failed to get privacy state: %s",
850			__func__, strerror(errno));
851		goto fail;
852	}
853	if (!GETPARAM(drv, IEEE80211_IOC_WPA, drv->prev_wpa)) {
854		wpa_printf(MSG_DEBUG, "%s: failed to get wpa state: %s",
855			__func__, strerror(errno));
856		goto fail;
857	}
858	if (set80211param(drv, IEEE80211_IOC_ROAMING, IEEE80211_ROAMING_MANUAL) < 0) {
859		wpa_printf(MSG_DEBUG, "%s: failed to set wpa_supplicant-based "
860			   "roaming: %s", __func__, strerror(errno));
861		goto fail;
862	}
863	if (drv->drivercaps & IEEE80211_C_BGSCAN) {
864		/*
865		 * Driver does background scanning; force the scan valid
866		 * setting to 1.5 x bg scan interval so the scan cache is
867		 * always consulted before we force a foreground scan.
868		 */
869		if (setscanvalid(drv) < 0) {
870			wpa_printf(MSG_DEBUG,
871			    "%s: warning, failed to set scanvalid, scanning "
872			    "may be suboptimal: %s", __func__, strerror(errno));
873		}
874	}
875	if (set80211param(drv, IEEE80211_IOC_WPA, 1+2) < 0) {
876		wpa_printf(MSG_DEBUG, "%s: failed to enable WPA support %s",
877			   __func__, strerror(errno));
878		goto fail;
879	}
880	drv->opmode = get80211opmode(drv);
881
882	return drv;
883fail:
884	close(drv->sock);
885fail1:
886	free(drv);
887	return NULL;
888}
889#undef GETPARAM
890
891static void
892wpa_driver_bsd_deinit(void *priv)
893{
894	struct wpa_driver_bsd_data *drv = priv;
895	int flags;
896
897	/* NB: mark interface down */
898	if (getifflags(drv, &flags) == 0)
899		(void) setifflags(drv, flags &~ IFF_UP);
900
901	wpa_driver_bsd_set_wpa_internal(drv, drv->prev_wpa, drv->prev_privacy);
902	if (set80211param(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming) < 0) {
903		/* NB: don't whinge if device ejected or equivalent */
904		if (errno != ENXIO)
905			wpa_printf(MSG_DEBUG, "%s: failed to restore roaming "
906			    "state", __func__);
907	}
908	if (drv->drivercaps & IEEE80211_C_BGSCAN) {
909		/* XXX check return value */
910		(void) set80211param(drv, IEEE80211_IOC_SCANVALID,
911		    drv->prev_scanvalid);
912	}
913
914	(void) close(drv->route);		/* ioctl socket */
915	(void) close(drv->sock);		/* event socket */
916	free(drv);
917}
918
919
920struct wpa_driver_ops wpa_driver_bsd_ops = {
921	.name			= "bsd",
922	.desc			= "BSD 802.11 support (Atheros, etc.)",
923	.init			= wpa_driver_bsd_init,
924	.deinit			= wpa_driver_bsd_deinit,
925	.get_bssid		= wpa_driver_bsd_get_bssid,
926	.get_ssid		= wpa_driver_bsd_get_ssid,
927	.set_key		= wpa_driver_bsd_set_key,
928	.set_countermeasures	= wpa_driver_bsd_set_countermeasures,
929	.scan2			= wpa_driver_bsd_scan,
930	.get_scan_results2	= wpa_driver_bsd_get_scan_results2,
931	.deauthenticate		= wpa_driver_bsd_deauthenticate,
932	.disassociate		= wpa_driver_bsd_disassociate,
933	.associate		= wpa_driver_bsd_associate,
934};
935