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