DragonFly BSD: Fix driver_bsd.c build
[mech_eap.git] / src / drivers / driver_bsd.c
1 /*
2  * WPA Supplicant - driver interaction with BSD net80211 layer
3  * Copyright (c) 2004, Sam Leffler <sam@errno.com>
4  * Copyright (c) 2004, 2Wire, Inc
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 #include "includes.h"
17 #include <sys/ioctl.h>
18
19 #include "common.h"
20 #include "driver.h"
21 #include "eloop.h"
22 #include "ieee802_11_defs.h"
23
24 #include <net/if.h>
25
26 #ifdef __NetBSD__
27 #include <net/if_ether.h>
28 #else
29 #include <net/ethernet.h>
30 #endif
31 #include <net/route.h>
32
33 #ifdef __DragonFly__
34 #include <netproto/802_11/ieee80211_ioctl.h>
35 #include <netproto/802_11/ieee80211_dragonfly.h>
36 #else /* __DragonFly__ */
37 #include <net80211/ieee80211.h>
38 #include <net80211/ieee80211_crypto.h>
39 #include <net80211/ieee80211_ioctl.h>
40 #endif /* __DragonFly__ */
41 #if __FreeBSD__
42 #include <net80211/ieee80211_freebsd.h>
43 #endif
44 #if __NetBSD__
45 #include <net80211/ieee80211_netbsd.h>
46 #endif
47
48 /* Generic functions for hostapd and wpa_supplicant */
49
50 static int
51 bsd_set80211var(int s, const char *ifname, int op, const void *arg, int arg_len)
52 {
53         struct ieee80211req ireq;
54
55         os_memset(&ireq, 0, sizeof(ireq));
56         os_strlcpy(ireq.i_name, ifname, sizeof(ireq.i_name));
57         ireq.i_type = op;
58         ireq.i_len = arg_len;
59         ireq.i_data = (void *) arg;
60
61         if (ioctl(s, SIOCS80211, &ireq) < 0) {
62                 fprintf(stderr, "ioctl[SIOCS80211, op %u, len %u]: %s\n",
63                         op, arg_len, strerror(errno));
64                 return -1;
65         }
66         return 0;
67 }
68
69 static int
70 bsd_get80211var(int s, const char *ifname, int op, void *arg, int arg_len)
71 {
72         struct ieee80211req ireq;
73
74         os_memset(&ireq, 0, sizeof(ireq));
75         os_strlcpy(ireq.i_name, ifname, sizeof(ireq.i_name));
76         ireq.i_type = op;
77         ireq.i_len = arg_len;
78         ireq.i_data = arg;
79
80         if (ioctl(s, SIOCG80211, &ireq) < 0) {
81                 fprintf(stderr, "ioctl[SIOCG80211, op %u, len %u]: %s\n",
82                         op, arg_len, strerror(errno));
83                 return -1;
84         }
85         return ireq.i_len;
86 }
87
88 static int
89 bsd_set80211param(int s, const char *ifname, int op, int arg)
90 {
91         struct ieee80211req ireq;
92
93         os_memset(&ireq, 0, sizeof(ireq));
94         os_strlcpy(ireq.i_name, ifname, sizeof(ireq.i_name));
95         ireq.i_type = op;
96         ireq.i_val = arg;
97
98         if (ioctl(s, SIOCS80211, &ireq) < 0) {
99                 fprintf(stderr, "ioctl[SIOCS80211, op %u, arg 0x%x]: %s\n",
100                         op, arg, strerror(errno));
101                 return -1;
102         }
103         return 0;
104 }
105
106 static int
107 bsd_get_ssid(int s, const char *ifname, u8 *ssid)
108 {
109 #ifdef SIOCG80211NWID
110         struct ieee80211_nwid nwid;
111         struct ifreq ifr;
112
113         os_memset(&ifr, 0, sizeof(ifr));
114         os_strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
115         ifr.ifr_data = (void *)&nwid;
116         if (ioctl(s, SIOCG80211NWID, &ifr) < 0 ||
117             nwid.i_len > IEEE80211_NWID_LEN)
118                 return -1;
119         os_memcpy(ssid, nwid.i_nwid, nwid.i_len);
120         return nwid.i_len;
121 #else
122         return bsd_get80211var(s, ifname, IEEE80211_IOC_SSID,
123                 ssid, IEEE80211_NWID_LEN);
124 #endif
125 }
126
127 static int
128 bsd_set_ssid(int s, const char *ifname, const u8 *ssid, size_t ssid_len)
129 {
130 #ifdef SIOCS80211NWID
131         struct ieee80211_nwid nwid;
132         struct ifreq ifr;
133
134         os_memcpy(nwid.i_nwid, ssid, ssid_len);
135         nwid.i_len = ssid_len;
136         os_memset(&ifr, 0, sizeof(ifr));
137         os_strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
138         ifr.ifr_data = (void *)&nwid;
139         return ioctl(s, SIOCS80211NWID, &ifr);
140 #else
141         return bsd_set80211var(s, ifname, IEEE80211_IOC_SSID, ssid, ssid_len);
142 #endif
143 }
144
145
146 #ifdef HOSTAPD
147
148 /*
149  * Avoid conflicts with hostapd definitions by undefining couple of defines
150  * from net80211 header files.
151  */
152 #undef RSN_VERSION
153 #undef WPA_VERSION
154 #undef WPA_OUI_TYPE
155
156 #include "l2_packet/l2_packet.h"
157 #include "../../hostapd/hostapd.h"
158 #include "../../hostapd/config.h"
159 #include "../../hostapd/eapol_sm.h"
160 #include "../../hostapd/sta_flags.h"
161
162 struct bsd_driver_data {
163         struct hostapd_data *hapd;              /* back pointer */
164
165         char    iface[IFNAMSIZ + 1];
166         struct l2_packet_data *sock_xmit;       /* raw packet xmit socket */
167         int     ioctl_sock;                     /* socket for ioctl() use */
168         int     wext_sock;                      /* socket for wireless events */
169 };
170
171 static int bsd_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
172                           int reason_code);
173
174 static int
175 set80211var(struct bsd_driver_data *drv, int op, const void *arg, int arg_len)
176 {
177         return bsd_set80211var(drv->ioctl_sock, drv->iface, op, arg, arg_len);
178 }
179
180 static int
181 get80211var(struct bsd_driver_data *drv, int op, void *arg, int arg_len)
182 {
183         return bsd_get80211var(drv->ioctl_sock, drv->iface, op, arg, arg_len);
184 }
185
186 static int
187 set80211param(struct bsd_driver_data *drv, int op, int arg)
188 {
189         return bsd_set80211param(drv->ioctl_sock, drv->iface, op, arg);
190 }
191
192 static const char *
193 ether_sprintf(const u8 *addr)
194 {
195         static char buf[sizeof(MACSTR)];
196
197         if (addr != NULL)
198                 snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
199         else
200                 snprintf(buf, sizeof(buf), MACSTR, 0,0,0,0,0,0);
201         return buf;
202 }
203
204 /*
205  * Configure WPA parameters.
206  */
207 static int
208 bsd_configure_wpa(struct bsd_driver_data *drv)
209 {
210         static const char *ciphernames[] =
211                 { "WEP", "TKIP", "AES-OCB", "AES-CCM", "CKIP", "NONE" };
212         struct hostapd_data *hapd = drv->hapd;
213         struct hostapd_bss_config *conf = hapd->conf;
214         int v;
215
216         switch (conf->wpa_group) {
217         case WPA_CIPHER_CCMP:
218                 v = IEEE80211_CIPHER_AES_CCM;
219                 break;
220         case WPA_CIPHER_TKIP:
221                 v = IEEE80211_CIPHER_TKIP;
222                 break;
223         case WPA_CIPHER_WEP104:
224                 v = IEEE80211_CIPHER_WEP;
225                 break;
226         case WPA_CIPHER_WEP40:
227                 v = IEEE80211_CIPHER_WEP;
228                 break;
229         case WPA_CIPHER_NONE:
230                 v = IEEE80211_CIPHER_NONE;
231                 break;
232         default:
233                 printf("Unknown group key cipher %u\n",
234                         conf->wpa_group);
235                 return -1;
236         }
237         wpa_printf(MSG_DEBUG, "%s: group key cipher=%s (%u)",
238                    __func__, ciphernames[v], v);
239         if (set80211param(drv, IEEE80211_IOC_MCASTCIPHER, v)) {
240                 printf("Unable to set group key cipher to %u (%s)\n",
241                         v, ciphernames[v]);
242                 return -1;
243         }
244         if (v == IEEE80211_CIPHER_WEP) {
245                 /* key length is done only for specific ciphers */
246                 v = (conf->wpa_group == WPA_CIPHER_WEP104 ? 13 : 5);
247                 if (set80211param(drv, IEEE80211_IOC_MCASTKEYLEN, v)) {
248                         printf("Unable to set group key length to %u\n", v);
249                         return -1;
250                 }
251         }
252
253         v = 0;
254         if (conf->wpa_pairwise & WPA_CIPHER_CCMP)
255                 v |= 1<<IEEE80211_CIPHER_AES_CCM;
256         if (conf->wpa_pairwise & WPA_CIPHER_TKIP)
257                 v |= 1<<IEEE80211_CIPHER_TKIP;
258         if (conf->wpa_pairwise & WPA_CIPHER_NONE)
259                 v |= 1<<IEEE80211_CIPHER_NONE;
260         wpa_printf(MSG_DEBUG, "%s: pairwise key ciphers=0x%x", __func__, v);
261         if (set80211param(drv, IEEE80211_IOC_UCASTCIPHERS, v)) {
262                 printf("Unable to set pairwise key ciphers to 0x%x\n", v);
263                 return -1;
264         }
265
266         wpa_printf(MSG_DEBUG, "%s: key management algorithms=0x%x",
267                    __func__, conf->wpa_key_mgmt);
268         if (set80211param(drv, IEEE80211_IOC_KEYMGTALGS, conf->wpa_key_mgmt)) {
269                 printf("Unable to set key management algorithms to 0x%x\n",
270                         conf->wpa_key_mgmt);
271                 return -1;
272         }
273
274         v = 0;
275         if (conf->rsn_preauth)
276                 v |= BIT(0);
277         wpa_printf(MSG_DEBUG, "%s: rsn capabilities=0x%x",
278                    __func__, conf->rsn_preauth);
279         if (set80211param(drv, IEEE80211_IOC_RSNCAPS, v)) {
280                 printf("Unable to set RSN capabilities to 0x%x\n", v);
281                 return -1;
282         }
283
284         wpa_printf(MSG_DEBUG, "%s: enable WPA= 0x%x", __func__, conf->wpa);
285         if (set80211param(drv, IEEE80211_IOC_WPA, conf->wpa)) {
286                 printf("Unable to set WPA to %u\n", conf->wpa);
287                 return -1;
288         }
289         return 0;
290 }
291
292
293 static int
294 bsd_set_iface_flags(void *priv, int dev_up)
295 {
296         struct bsd_driver_data *drv = priv;
297         struct ifreq ifr;
298
299         wpa_printf(MSG_DEBUG, "%s: dev_up=%d", __func__, dev_up);
300
301         if (drv->ioctl_sock < 0)
302                 return -1;
303
304         memset(&ifr, 0, sizeof(ifr));
305         os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name));
306
307         if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, &ifr) != 0) {
308                 perror("ioctl[SIOCGIFFLAGS]");
309                 return -1;
310         }
311
312         if (dev_up)
313                 ifr.ifr_flags |= IFF_UP;
314         else
315                 ifr.ifr_flags &= ~IFF_UP;
316
317         if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, &ifr) != 0) {
318                 perror("ioctl[SIOCSIFFLAGS]");
319                 return -1;
320         }
321
322         if (dev_up) {
323                 memset(&ifr, 0, sizeof(ifr));
324                 os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name));
325                 ifr.ifr_mtu = HOSTAPD_MTU;
326                 if (ioctl(drv->ioctl_sock, SIOCSIFMTU, &ifr) != 0) {
327                         perror("ioctl[SIOCSIFMTU]");
328                         printf("Setting MTU failed - trying to survive with "
329                                "current value\n");
330                 }
331         }
332
333         return 0;
334 }
335
336 static int
337 bsd_set_ieee8021x(const char *ifname, void *priv, int enabled)
338 {
339         struct bsd_driver_data *drv = priv;
340         struct hostapd_data *hapd = drv->hapd;
341         struct hostapd_bss_config *conf = hapd->conf;
342
343         wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
344
345         if (!enabled) {
346                 /* XXX restore state */
347                 return set80211param(priv, IEEE80211_IOC_AUTHMODE,
348                         IEEE80211_AUTH_AUTO);
349         }
350         if (!conf->wpa && !conf->ieee802_1x) {
351                 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER,
352                         HOSTAPD_LEVEL_WARNING, "No 802.1X or WPA enabled!");
353                 return -1;
354         }
355         if (conf->wpa && bsd_configure_wpa(drv) != 0) {
356                 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER,
357                         HOSTAPD_LEVEL_WARNING, "Error configuring WPA state!");
358                 return -1;
359         }
360         if (set80211param(priv, IEEE80211_IOC_AUTHMODE,
361                 (conf->wpa ?  IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) {
362                 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER,
363                         HOSTAPD_LEVEL_WARNING, "Error enabling WPA/802.1X!");
364                 return -1;
365         }
366         return bsd_set_iface_flags(priv, 1);
367 }
368
369 static int
370 bsd_set_privacy(const char *ifname, void *priv, int enabled)
371 {
372         struct bsd_driver_data *drv = priv;
373
374         wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
375
376         return set80211param(drv, IEEE80211_IOC_PRIVACY, enabled);
377 }
378
379 static int
380 bsd_set_sta_authorized(void *priv, const u8 *addr, int authorized)
381 {
382         struct bsd_driver_data *drv = priv;
383         struct ieee80211req_mlme mlme;
384
385         wpa_printf(MSG_DEBUG, "%s: addr=%s authorized=%d",
386                    __func__, ether_sprintf(addr), authorized);
387
388         if (authorized)
389                 mlme.im_op = IEEE80211_MLME_AUTHORIZE;
390         else
391                 mlme.im_op = IEEE80211_MLME_UNAUTHORIZE;
392         mlme.im_reason = 0;
393         memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
394         return set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme));
395 }
396
397 static int
398 bsd_sta_set_flags(void *priv, const u8 *addr, int total_flags, int flags_or,
399                   int flags_and)
400 {
401         /* For now, only support setting Authorized flag */
402         if (flags_or & WLAN_STA_AUTHORIZED)
403                 return bsd_set_sta_authorized(priv, addr, 1);
404         if (!(flags_and & WLAN_STA_AUTHORIZED))
405                 return bsd_set_sta_authorized(priv, addr, 0);
406         return 0;
407 }
408
409 static int
410 bsd_del_key(void *priv, const u8 *addr, int key_idx)
411 {
412         struct bsd_driver_data *drv = priv;
413         struct ieee80211req_del_key wk;
414
415         wpa_printf(MSG_DEBUG, "%s: addr=%s key_idx=%d",
416                    __func__, ether_sprintf(addr), key_idx);
417
418         memset(&wk, 0, sizeof(wk));
419         if (addr != NULL) {
420                 memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN);
421                 wk.idk_keyix = (u_int8_t) IEEE80211_KEYIX_NONE; /* XXX */
422         } else {
423                 wk.idk_keyix = key_idx;
424         }
425
426         return set80211var(drv, IEEE80211_IOC_DELKEY, &wk, sizeof(wk));
427 }
428
429 static int
430 bsd_set_key(const char *ifname, void *priv, wpa_alg alg,
431             const u8 *addr, int key_idx, int set_tx, const u8 *seq,
432             size_t seq_len, const u8 *key, size_t key_len)
433 {
434         struct bsd_driver_data *drv = priv;
435         struct ieee80211req_key wk;
436         u_int8_t cipher;
437
438         if (alg == WPA_ALG_NONE)
439                 return bsd_del_key(drv, addr, key_idx);
440
441         wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%s key_idx=%d",
442                    __func__, alg, ether_sprintf(addr), key_idx);
443
444         if (alg == WPA_ALG_WEP)
445                 cipher = IEEE80211_CIPHER_WEP;
446         else if (alg == WPA_ALG_TKIP)
447                 cipher = IEEE80211_CIPHER_TKIP;
448         else if (alg == WPA_ALG_CCMP)
449                 cipher = IEEE80211_CIPHER_AES_CCM;
450         else {
451                 printf("%s: unknown/unsupported algorithm %d\n",
452                         __func__, alg);
453                 return -1;
454         }
455
456         if (key_len > sizeof(wk.ik_keydata)) {
457                 printf("%s: key length %d too big\n", __func__, (int) key_len);
458                 return -3;
459         }
460
461         memset(&wk, 0, sizeof(wk));
462         wk.ik_type = cipher;
463         wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT;
464         if (addr == NULL) {
465                 memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
466                 wk.ik_keyix = key_idx;
467                 wk.ik_flags |= IEEE80211_KEY_DEFAULT;
468         } else {
469                 memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
470                 wk.ik_keyix = IEEE80211_KEYIX_NONE;
471         }
472         wk.ik_keylen = key_len;
473         memcpy(wk.ik_keydata, key, key_len);
474
475         return set80211var(drv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk));
476 }
477
478
479 static int
480 bsd_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx,
481                u8 *seq)
482 {
483         struct bsd_driver_data *drv = priv;
484         struct ieee80211req_key wk;
485
486         wpa_printf(MSG_DEBUG, "%s: addr=%s idx=%d",
487                    __func__, ether_sprintf(addr), idx);
488
489         memset(&wk, 0, sizeof(wk));
490         if (addr == NULL)
491                 memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
492         else
493                 memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
494         wk.ik_keyix = idx;
495
496         if (get80211var(drv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk)) < 0) {
497                 printf("Failed to get encryption.\n");
498                 return -1;
499         }
500
501 #ifdef WORDS_BIGENDIAN
502         {
503                 /*
504                  * wk.ik_keytsc is in host byte order (big endian), need to
505                  * swap it to match with the byte order used in WPA.
506                  */
507                 int i;
508                 u8 tmp[WPA_KEY_RSC_LEN];
509                 memcpy(tmp, &wk.ik_keytsc, sizeof(wk.ik_keytsc));
510                 for (i = 0; i < WPA_KEY_RSC_LEN; i++) {
511                         seq[i] = tmp[WPA_KEY_RSC_LEN - i - 1];
512                 }
513         }
514 #else /* WORDS_BIGENDIAN */
515         memcpy(seq, &wk.ik_keytsc, sizeof(wk.ik_keytsc));
516 #endif /* WORDS_BIGENDIAN */
517         return 0;
518 }
519
520
521 static int 
522 bsd_flush(void *priv)
523 {
524         u8 allsta[IEEE80211_ADDR_LEN];
525
526         memset(allsta, 0xff, IEEE80211_ADDR_LEN);
527         return bsd_sta_deauth(priv, NULL, allsta, IEEE80211_REASON_AUTH_LEAVE);
528 }
529
530
531 static int
532 bsd_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data,
533                          const u8 *addr)
534 {
535         struct bsd_driver_data *drv = priv;
536         struct ieee80211req_sta_stats stats;
537
538         memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN);
539         if (get80211var(drv, IEEE80211_IOC_STA_STATS, &stats, sizeof(stats)) > 0) {
540                 /* XXX? do packets counts include non-data frames? */
541                 data->rx_packets = stats.is_stats.ns_rx_data;
542                 data->rx_bytes = stats.is_stats.ns_rx_bytes;
543                 data->tx_packets = stats.is_stats.ns_tx_data;
544                 data->tx_bytes = stats.is_stats.ns_tx_bytes;
545         }
546         return 0;
547 }
548
549 static int
550 bsd_set_opt_ie(const char *ifname, void *priv, const u8 *ie, size_t ie_len)
551 {
552         /*
553          * Do nothing; we setup parameters at startup that define the
554          * contents of the beacon information element.
555          */
556         return 0;
557 }
558
559 static int
560 bsd_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, int reason_code)
561 {
562         struct bsd_driver_data *drv = priv;
563         struct ieee80211req_mlme mlme;
564
565         wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d",
566                    __func__, ether_sprintf(addr), reason_code);
567
568         mlme.im_op = IEEE80211_MLME_DEAUTH;
569         mlme.im_reason = reason_code;
570         memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
571         return set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme));
572 }
573
574 static int
575 bsd_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
576                  int reason_code)
577 {
578         struct bsd_driver_data *drv = priv;
579         struct ieee80211req_mlme mlme;
580
581         wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d",
582                    __func__, ether_sprintf(addr), reason_code);
583
584         mlme.im_op = IEEE80211_MLME_DISASSOC;
585         mlme.im_reason = reason_code;
586         memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
587         return set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme));
588 }
589
590 static int
591 bsd_new_sta(struct bsd_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN])
592 {
593         struct hostapd_data *hapd = drv->hapd;
594         struct ieee80211req_wpaie ie;
595         int ielen = 0;
596         u8 *iebuf = NULL;
597
598         /*
599          * Fetch and validate any negotiated WPA/RSN parameters.
600          */
601         memset(&ie, 0, sizeof(ie));
602         memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN);
603         if (get80211var(drv, IEEE80211_IOC_WPAIE, &ie, sizeof(ie)) < 0) {
604                 printf("Failed to get WPA/RSN information element.\n");
605                 goto no_ie;
606         }
607         iebuf = ie.wpa_ie;
608         ielen = ie.wpa_ie[1];
609         if (ielen == 0)
610                 iebuf = NULL;
611         else
612                 ielen += 2;
613
614 no_ie:
615         return hostapd_notif_assoc(hapd, addr, iebuf, ielen);
616 }
617
618 static void
619 bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx)
620 {
621         struct bsd_driver_data *drv = ctx;
622         struct hostapd_data *hapd = drv->hapd;
623         char buf[2048];
624         struct if_announcemsghdr *ifan;
625         struct rt_msghdr *rtm;
626         struct ieee80211_michael_event *mic;
627         struct ieee80211_join_event *join;
628         struct ieee80211_leave_event *leave;
629         int n;
630
631         n = read(sock, buf, sizeof(buf));
632         if (n < 0) {
633                 if (errno != EINTR && errno != EAGAIN)
634                         perror("read(PF_ROUTE)");
635                 return;
636         }
637
638         rtm = (struct rt_msghdr *) buf;
639         if (rtm->rtm_version != RTM_VERSION) {
640                 wpa_printf(MSG_DEBUG, "Routing message version %d not "
641                         "understood\n", rtm->rtm_version);
642                 return;
643         }
644         ifan = (struct if_announcemsghdr *) rtm;
645         switch (rtm->rtm_type) {
646         case RTM_IEEE80211:
647                 switch (ifan->ifan_what) {
648                 case RTM_IEEE80211_ASSOC:
649                 case RTM_IEEE80211_REASSOC:
650                 case RTM_IEEE80211_DISASSOC:
651                 case RTM_IEEE80211_SCAN:
652                         break;
653                 case RTM_IEEE80211_LEAVE:
654                         leave = (struct ieee80211_leave_event *) &ifan[1];
655                         hostapd_notif_disassoc(drv->hapd, leave->iev_addr);
656                         break;
657                 case RTM_IEEE80211_JOIN:
658 #ifdef RTM_IEEE80211_REJOIN
659                 case RTM_IEEE80211_REJOIN:
660 #endif
661                         join = (struct ieee80211_join_event *) &ifan[1];
662                         bsd_new_sta(drv, join->iev_addr);
663                         break;
664                 case RTM_IEEE80211_REPLAY:
665                         /* ignore */
666                         break;
667                 case RTM_IEEE80211_MICHAEL:
668                         mic = (struct ieee80211_michael_event *) &ifan[1];
669                         wpa_printf(MSG_DEBUG,
670                                 "Michael MIC failure wireless event: "
671                                 "keyix=%u src_addr=" MACSTR, mic->iev_keyix,
672                                 MAC2STR(mic->iev_src));
673                         hostapd_michael_mic_failure(hapd, mic->iev_src);
674                         break;
675                 }
676                 break;
677         }
678 }
679
680 static int
681 bsd_wireless_event_init(struct bsd_driver_data *drv)
682 {
683         int s;
684
685         drv->wext_sock = -1;
686
687         s = socket(PF_ROUTE, SOCK_RAW, 0);
688         if (s < 0) {
689                 perror("socket(PF_ROUTE,SOCK_RAW)");
690                 return -1;
691         }
692         eloop_register_read_sock(s, bsd_wireless_event_receive, drv, NULL);
693         drv->wext_sock = s;
694
695         return 0;
696 }
697
698 static void
699 bsd_wireless_event_deinit(struct bsd_driver_data *drv)
700 {
701         if (drv->wext_sock < 0)
702                 return;
703         eloop_unregister_read_sock(drv->wext_sock);
704         close(drv->wext_sock);
705 }
706
707
708 static int
709 bsd_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len,
710                int encrypt, const u8 *own_addr)
711 {
712         struct bsd_driver_data *drv = priv;
713         unsigned char buf[3000];
714         unsigned char *bp = buf;
715         struct l2_ethhdr *eth;
716         size_t len;
717         int status;
718
719         /*
720          * Prepend the Etherent header.  If the caller left us
721          * space at the front we could just insert it but since
722          * we don't know we copy to a local buffer.  Given the frequency
723          * and size of frames this probably doesn't matter.
724          */
725         len = data_len + sizeof(struct l2_ethhdr);
726         if (len > sizeof(buf)) {
727                 bp = malloc(len);
728                 if (bp == NULL) {
729                         printf("EAPOL frame discarded, cannot malloc temp "
730                                "buffer of size %u!\n", (unsigned int) len);
731                         return -1;
732                 }
733         }
734         eth = (struct l2_ethhdr *) bp;
735         memcpy(eth->h_dest, addr, ETH_ALEN);
736         memcpy(eth->h_source, own_addr, ETH_ALEN);
737         eth->h_proto = htons(ETH_P_EAPOL);
738         memcpy(eth+1, data, data_len);
739
740         wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", bp, len);
741
742         status = l2_packet_send(drv->sock_xmit, addr, ETH_P_EAPOL, bp, len);
743
744         if (bp != buf)
745                 free(bp);
746         return status;
747 }
748
749 static void
750 handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)
751 {
752         struct bsd_driver_data *drv = ctx;
753         hostapd_eapol_receive(drv->hapd, src_addr,
754                               buf + sizeof(struct l2_ethhdr),
755                               len - sizeof(struct l2_ethhdr));
756 }
757
758 static int
759 hostapd_bsd_get_ssid(const char *ifname, void *priv, u8 *buf, int len)
760 {
761         struct bsd_driver_data *drv = priv;
762         int ssid_len;
763
764         ssid_len = bsd_get_ssid(drv->ioctl_sock, drv->iface, buf);
765         wpa_printf(MSG_DEBUG, "%s: ssid=\"%.*s\"", __func__, ssid_len, buf);
766
767         return ssid_len;
768 }
769
770 static int
771 hostapd_bsd_set_ssid(const char *ifname, void *priv, const u8 *buf, int len)
772 {
773         struct bsd_driver_data *drv = priv;
774
775         wpa_printf(MSG_DEBUG, "%s: ssid=\"%.*s\"", __func__, len, buf);
776
777         return bsd_set_ssid(drv->ioctl_sock, drv->iface, buf, len);
778 }
779
780 static void *
781 bsd_init(struct hostapd_data *hapd, struct wpa_init_params *params)
782 {
783         struct bsd_driver_data *drv;
784
785         drv = os_zalloc(sizeof(struct bsd_driver_data));
786         if (drv == NULL) {
787                 printf("Could not allocate memory for bsd driver data\n");
788                 goto bad;
789         }
790
791         drv->hapd = hapd;
792         drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
793         if (drv->ioctl_sock < 0) {
794                 perror("socket[PF_INET,SOCK_DGRAM]");
795                 goto bad;
796         }
797         memcpy(drv->iface, params->ifname, sizeof(drv->iface));
798
799         drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL,
800                                         handle_read, drv, 1);
801         if (drv->sock_xmit == NULL)
802                 goto bad;
803         if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr))
804                 goto bad;
805
806         bsd_set_iface_flags(drv, 0);    /* mark down during setup */
807         if (bsd_wireless_event_init(drv))
808                 goto bad;
809
810         return drv;
811 bad:
812         if (drv->sock_xmit != NULL)
813                 l2_packet_deinit(drv->sock_xmit);
814         if (drv->ioctl_sock >= 0)
815                 close(drv->ioctl_sock);
816         if (drv != NULL)
817                 free(drv);
818         return NULL;
819 }
820
821
822 static void
823 bsd_deinit(void *priv)
824 {
825         struct bsd_driver_data *drv = priv;
826
827         bsd_wireless_event_deinit(drv);
828         (void) bsd_set_iface_flags(drv, 0);
829         if (drv->ioctl_sock >= 0)
830                 close(drv->ioctl_sock);
831         if (drv->sock_xmit != NULL)
832                 l2_packet_deinit(drv->sock_xmit);
833         free(drv);
834 }
835
836 const struct wpa_driver_ops wpa_driver_bsd_ops = {
837         .name                   = "bsd",
838         .hapd_init              = bsd_init,
839         .hapd_deinit            = bsd_deinit,
840         .set_ieee8021x          = bsd_set_ieee8021x,
841         .set_privacy            = bsd_set_privacy,
842         .hapd_set_key           = bsd_set_key,
843         .get_seqnum             = bsd_get_seqnum,
844         .flush                  = bsd_flush,
845         .set_generic_elem       = bsd_set_opt_ie,
846         .sta_set_flags          = bsd_sta_set_flags,
847         .read_sta_data          = bsd_read_sta_driver_data,
848         .hapd_send_eapol        = bsd_send_eapol,
849         .sta_disassoc           = bsd_sta_disassoc,
850         .sta_deauth             = bsd_sta_deauth,
851         .hapd_set_ssid          = hostapd_bsd_set_ssid,
852         .hapd_get_ssid          = hostapd_bsd_get_ssid,
853 };
854
855 #else /* HOSTAPD */
856
857 struct wpa_driver_bsd_data {
858         int     sock;                   /* open socket for 802.11 ioctls */
859         int     route;                  /* routing socket for events */
860         char    ifname[IFNAMSIZ+1];     /* interface name */
861         unsigned int ifindex;           /* interface index */
862         void    *ctx;
863         int     prev_roaming;           /* roaming state to restore on deinit */
864         int     prev_privacy;           /* privacy state to restore on deinit */
865         int     prev_wpa;               /* wpa state to restore on deinit */
866 };
867
868 static int
869 set80211var(struct wpa_driver_bsd_data *drv, int op, const void *arg, int arg_len)
870 {
871         return bsd_set80211var(drv->sock, drv->ifname, op, arg, arg_len);
872 }
873
874 static int
875 get80211var(struct wpa_driver_bsd_data *drv, int op, void *arg, int arg_len)
876 {
877         return bsd_get80211var(drv->sock, drv->ifname, op, arg, arg_len);
878 }
879
880 static int
881 set80211param(struct wpa_driver_bsd_data *drv, int op, int arg)
882 {
883         return bsd_set80211param(drv->sock, drv->ifname, op, arg);
884 }
885
886 static int
887 get80211param(struct wpa_driver_bsd_data *drv, int op)
888 {
889         struct ieee80211req ireq;
890
891         os_memset(&ireq, 0, sizeof(ireq));
892         os_strlcpy(ireq.i_name, drv->ifname, sizeof(ireq.i_name));
893         ireq.i_type = op;
894
895         if (ioctl(drv->sock, SIOCG80211, &ireq) < 0) {
896                 fprintf(stderr, "ioctl[SIOCG80211, op %u]: %s\n",
897                         op, strerror(errno));
898                 return -1;
899         }
900         return ireq.i_val;
901 }
902
903 static int
904 getifflags(struct wpa_driver_bsd_data *drv, int *flags)
905 {
906         struct ifreq ifr;
907
908         os_memset(&ifr, 0, sizeof(ifr));
909         os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name));
910         if (ioctl(drv->sock, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
911                 perror("SIOCGIFFLAGS");
912                 return errno;
913         }
914         *flags = ifr.ifr_flags & 0xffff;
915         return 0;
916 }
917
918 static int
919 setifflags(struct wpa_driver_bsd_data *drv, int flags)
920 {
921         struct ifreq ifr;
922
923         os_memset(&ifr, 0, sizeof(ifr));
924         os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name));
925         ifr.ifr_flags = flags & 0xffff;
926         if (ioctl(drv->sock, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) {
927                 perror("SIOCSIFFLAGS");
928                 return errno;
929         }
930         return 0;
931 }
932
933 static int
934 wpa_driver_bsd_get_bssid(void *priv, u8 *bssid)
935 {
936         struct wpa_driver_bsd_data *drv = priv;
937 #ifdef SIOCG80211BSSID
938         struct ieee80211_bssid bs;
939
940         os_strncpy(bs.i_name, drv->ifname, sizeof(bs.i_name));
941         if (ioctl(drv->sock, SIOCG80211BSSID, &bs) < 0)
942                 return -1;
943         os_memcpy(bssid, bs.i_bssid, sizeof(bs.i_bssid));
944         return 0;
945 #else
946         return get80211var(drv, IEEE80211_IOC_BSSID,
947                 bssid, IEEE80211_ADDR_LEN) < 0 ? -1 : 0;
948 #endif
949 }
950
951 #if 0
952 static int
953 wpa_driver_bsd_set_bssid(void *priv, const char *bssid)
954 {
955         struct wpa_driver_bsd_data *drv = priv;
956
957         return set80211var(drv, IEEE80211_IOC_BSSID,
958                 bssid, IEEE80211_ADDR_LEN);
959 }
960 #endif
961
962 static int
963 wpa_driver_bsd_get_ssid(void *priv, u8 *ssid)
964 {
965         struct wpa_driver_bsd_data *drv = priv;
966
967         return bsd_get_ssid(drv->sock, drv->ifname, ssid);
968 }
969
970 static int
971 wpa_driver_bsd_set_ssid(void *priv, const u8 *ssid,
972                              size_t ssid_len)
973 {
974         struct wpa_driver_bsd_data *drv = priv;
975
976         return bsd_set_ssid(drv->sock, drv->ifname, ssid, ssid_len);
977 }
978
979 static int
980 wpa_driver_bsd_set_wpa_ie(struct wpa_driver_bsd_data *drv,
981         const u8 *wpa_ie, size_t wpa_ie_len)
982 {
983         return set80211var(drv, IEEE80211_IOC_OPTIE, wpa_ie, wpa_ie_len);
984 }
985
986 static int
987 wpa_driver_bsd_set_wpa_internal(void *priv, int wpa, int privacy)
988 {
989         struct wpa_driver_bsd_data *drv = priv;
990         int ret = 0;
991
992         wpa_printf(MSG_DEBUG, "%s: wpa=%d privacy=%d",
993                 __FUNCTION__, wpa, privacy);
994
995         if (!wpa && wpa_driver_bsd_set_wpa_ie(drv, NULL, 0) < 0)
996                 ret = -1;
997         if (set80211param(drv, IEEE80211_IOC_PRIVACY, privacy) < 0)
998                 ret = -1;
999         if (set80211param(drv, IEEE80211_IOC_WPA, wpa) < 0)
1000                 ret = -1;
1001
1002         return ret;
1003 }
1004
1005 static int
1006 wpa_driver_bsd_set_wpa(void *priv, int enabled)
1007 {
1008         wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
1009
1010         return wpa_driver_bsd_set_wpa_internal(priv, enabled ? 3 : 0, enabled);
1011 }
1012
1013 static int
1014 wpa_driver_bsd_del_key(struct wpa_driver_bsd_data *drv, int key_idx,
1015                        const unsigned char *addr)
1016 {
1017         struct ieee80211req_del_key wk;
1018
1019         os_memset(&wk, 0, sizeof(wk));
1020         if (addr != NULL &&
1021             bcmp(addr, "\xff\xff\xff\xff\xff\xff", IEEE80211_ADDR_LEN) != 0) {
1022                 struct ether_addr ea;
1023
1024                 os_memcpy(&ea, addr, IEEE80211_ADDR_LEN);
1025                 wpa_printf(MSG_DEBUG, "%s: addr=%s keyidx=%d",
1026                         __func__, ether_ntoa(&ea), key_idx);
1027                 os_memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN);
1028                 wk.idk_keyix = (uint8_t) IEEE80211_KEYIX_NONE;
1029         } else {
1030                 wpa_printf(MSG_DEBUG, "%s: keyidx=%d", __func__, key_idx);
1031                 wk.idk_keyix = key_idx;
1032         }
1033         return set80211var(drv, IEEE80211_IOC_DELKEY, &wk, sizeof(wk));
1034 }
1035
1036 static int
1037 wpa_driver_bsd_set_key(void *priv, wpa_alg alg,
1038                        const unsigned char *addr, int key_idx, int set_tx,
1039                        const u8 *seq, size_t seq_len,
1040                        const u8 *key, size_t key_len)
1041 {
1042         struct wpa_driver_bsd_data *drv = priv;
1043         struct ieee80211req_key wk;
1044         struct ether_addr ea;
1045         char *alg_name;
1046         u_int8_t cipher;
1047
1048         if (alg == WPA_ALG_NONE)
1049                 return wpa_driver_bsd_del_key(drv, key_idx, addr);
1050
1051         switch (alg) {
1052         case WPA_ALG_WEP:
1053                 alg_name = "WEP";
1054                 cipher = IEEE80211_CIPHER_WEP;
1055                 break;
1056         case WPA_ALG_TKIP:
1057                 alg_name = "TKIP";
1058                 cipher = IEEE80211_CIPHER_TKIP;
1059                 break;
1060         case WPA_ALG_CCMP:
1061                 alg_name = "CCMP";
1062                 cipher = IEEE80211_CIPHER_AES_CCM;
1063                 break;
1064         default:
1065                 wpa_printf(MSG_DEBUG, "%s: unknown/unsupported algorithm %d",
1066                         __func__, alg);
1067                 return -1;
1068         }
1069
1070         os_memcpy(&ea, addr, IEEE80211_ADDR_LEN);
1071         wpa_printf(MSG_DEBUG,
1072                 "%s: alg=%s addr=%s key_idx=%d set_tx=%d seq_len=%zu key_len=%zu",
1073                 __func__, alg_name, ether_ntoa(&ea), key_idx, set_tx,
1074                 seq_len, key_len);
1075
1076         if (seq_len > sizeof(u_int64_t)) {
1077                 wpa_printf(MSG_DEBUG, "%s: seq_len %zu too big",
1078                         __func__, seq_len);
1079                 return -2;
1080         }
1081         if (key_len > sizeof(wk.ik_keydata)) {
1082                 wpa_printf(MSG_DEBUG, "%s: key length %zu too big",
1083                         __func__, key_len);
1084                 return -3;
1085         }
1086
1087         os_memset(&wk, 0, sizeof(wk));
1088         wk.ik_type = cipher;
1089         wk.ik_flags = IEEE80211_KEY_RECV;
1090         if (set_tx)
1091                 wk.ik_flags |= IEEE80211_KEY_XMIT;
1092         os_memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
1093         /*
1094          * Deduce whether group/global or unicast key by checking
1095          * the address (yech).  Note also that we can only mark global
1096          * keys default; doing this for a unicast key is an error.
1097          */
1098         if (bcmp(addr, "\xff\xff\xff\xff\xff\xff", IEEE80211_ADDR_LEN) == 0) {
1099                 wk.ik_flags |= IEEE80211_KEY_GROUP;
1100                 wk.ik_keyix = key_idx;
1101         } else {
1102                 wk.ik_keyix = (key_idx == 0 ? IEEE80211_KEYIX_NONE : key_idx);
1103         }
1104         if (wk.ik_keyix != IEEE80211_KEYIX_NONE && set_tx)
1105                 wk.ik_flags |= IEEE80211_KEY_DEFAULT;
1106         wk.ik_keylen = key_len;
1107         os_memcpy(&wk.ik_keyrsc, seq, seq_len);
1108         os_memcpy(wk.ik_keydata, key, key_len);
1109
1110         return set80211var(drv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk));
1111 }
1112
1113 static int
1114 wpa_driver_bsd_set_countermeasures(void *priv, int enabled)
1115 {
1116         struct wpa_driver_bsd_data *drv = priv;
1117
1118         wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
1119         return set80211param(drv, IEEE80211_IOC_COUNTERMEASURES, enabled);
1120 }
1121
1122
1123 static int
1124 wpa_driver_bsd_set_drop_unencrypted(void *priv, int enabled)
1125 {
1126         struct wpa_driver_bsd_data *drv = priv;
1127
1128         wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
1129         return set80211param(drv, IEEE80211_IOC_DROPUNENCRYPTED, enabled);
1130 }
1131
1132 static int
1133 wpa_driver_bsd_deauthenticate(void *priv, const u8 *addr, int reason_code)
1134 {
1135         struct wpa_driver_bsd_data *drv = priv;
1136         struct ieee80211req_mlme mlme;
1137
1138         wpa_printf(MSG_DEBUG, "%s", __func__);
1139         os_memset(&mlme, 0, sizeof(mlme));
1140         mlme.im_op = IEEE80211_MLME_DEAUTH;
1141         mlme.im_reason = reason_code;
1142         os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
1143         return set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme));
1144 }
1145
1146 static int
1147 wpa_driver_bsd_disassociate(void *priv, const u8 *addr, int reason_code)
1148 {
1149         struct wpa_driver_bsd_data *drv = priv;
1150         struct ieee80211req_mlme mlme;
1151
1152         wpa_printf(MSG_DEBUG, "%s", __func__);
1153         os_memset(&mlme, 0, sizeof(mlme));
1154         mlme.im_op = IEEE80211_MLME_DISASSOC;
1155         mlme.im_reason = reason_code;
1156         os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
1157         return set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme));
1158 }
1159
1160 static int
1161 wpa_driver_bsd_associate(void *priv, struct wpa_driver_associate_params *params)
1162 {
1163         struct wpa_driver_bsd_data *drv = priv;
1164         struct ieee80211req_mlme mlme;
1165         int privacy;
1166
1167         wpa_printf(MSG_DEBUG,
1168                 "%s: ssid '%.*s' wpa ie len %u pairwise %u group %u key mgmt %u"
1169                 , __func__
1170                    , (unsigned int) params->ssid_len, params->ssid
1171                 , (unsigned int) params->wpa_ie_len
1172                 , params->pairwise_suite
1173                 , params->group_suite
1174                 , params->key_mgmt_suite
1175         );
1176
1177         /* XXX error handling is wrong but unclear what to do... */
1178         if (wpa_driver_bsd_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0)
1179                 return -1;
1180
1181         privacy = !(params->pairwise_suite == CIPHER_NONE &&
1182             params->group_suite == CIPHER_NONE &&
1183             params->key_mgmt_suite == KEY_MGMT_NONE &&
1184             params->wpa_ie_len == 0);
1185         wpa_printf(MSG_DEBUG, "%s: set PRIVACY %u", __func__, privacy);
1186
1187         if (set80211param(drv, IEEE80211_IOC_PRIVACY, privacy) < 0)
1188                 return -1;
1189
1190         if (params->wpa_ie_len &&
1191             set80211param(drv, IEEE80211_IOC_WPA,
1192                           params->wpa_ie[0] == WLAN_EID_RSN ? 2 : 1) < 0)
1193                 return -1;
1194
1195         os_memset(&mlme, 0, sizeof(mlme));
1196         mlme.im_op = IEEE80211_MLME_ASSOC;
1197         if (params->ssid != NULL)
1198                 os_memcpy(mlme.im_ssid, params->ssid, params->ssid_len);
1199         mlme.im_ssid_len = params->ssid_len;
1200         if (params->bssid != NULL)
1201                 os_memcpy(mlme.im_macaddr, params->bssid, IEEE80211_ADDR_LEN);
1202         if (set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)) < 0)
1203                 return -1;
1204         return 0;
1205 }
1206
1207 static int
1208 wpa_driver_bsd_set_auth_alg(void *priv, int auth_alg)
1209 {
1210         struct wpa_driver_bsd_data *drv = priv;
1211         int authmode;
1212
1213         if ((auth_alg & AUTH_ALG_OPEN_SYSTEM) &&
1214             (auth_alg & AUTH_ALG_SHARED_KEY))
1215                 authmode = IEEE80211_AUTH_AUTO;
1216         else if (auth_alg & AUTH_ALG_SHARED_KEY)
1217                 authmode = IEEE80211_AUTH_SHARED;
1218         else
1219                 authmode = IEEE80211_AUTH_OPEN;
1220
1221         return set80211param(drv, IEEE80211_IOC_AUTHMODE, authmode);
1222 }
1223
1224 static int
1225 wpa_driver_bsd_scan(void *priv, const u8 *ssid, size_t ssid_len)
1226 {
1227         struct wpa_driver_bsd_data *drv = priv;
1228         int flags;
1229
1230         /* NB: interface must be marked UP to do a scan */
1231         if (getifflags(drv, &flags) != 0 || setifflags(drv, flags | IFF_UP) != 0)
1232                 return -1;
1233
1234         /* set desired ssid before scan */
1235         if (wpa_driver_bsd_set_ssid(drv, ssid, ssid_len) < 0)
1236                 return -1;
1237
1238         /* NB: net80211 delivers a scan complete event so no need to poll */
1239         return set80211param(drv, IEEE80211_IOC_SCAN_REQ, 0);
1240 }
1241
1242 static void
1243 wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx)
1244 {
1245         struct wpa_driver_bsd_data *drv = sock_ctx;
1246         char buf[2048];
1247         struct if_announcemsghdr *ifan;
1248         struct if_msghdr *ifm;
1249         struct rt_msghdr *rtm;
1250         union wpa_event_data event;
1251         struct ieee80211_michael_event *mic;
1252         int n;
1253
1254         n = read(sock, buf, sizeof(buf));
1255         if (n < 0) {
1256                 if (errno != EINTR && errno != EAGAIN)
1257                         perror("read(PF_ROUTE)");
1258                 return;
1259         }
1260
1261         rtm = (struct rt_msghdr *) buf;
1262         if (rtm->rtm_version != RTM_VERSION) {
1263                 wpa_printf(MSG_DEBUG, "Routing message version %d not "
1264                         "understood\n", rtm->rtm_version);
1265                 return;
1266         }
1267         os_memset(&event, 0, sizeof(event));
1268         switch (rtm->rtm_type) {
1269         case RTM_IFANNOUNCE:
1270                 ifan = (struct if_announcemsghdr *) rtm;
1271                 if (ifan->ifan_index != drv->ifindex)
1272                         break;
1273                 strlcpy(event.interface_status.ifname, drv->ifname,
1274                         sizeof(event.interface_status.ifname));
1275                 switch (ifan->ifan_what) {
1276                 case IFAN_DEPARTURE:
1277                         event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
1278                 default:
1279                         return;
1280                 }
1281                 wpa_printf(MSG_DEBUG, "RTM_IFANNOUNCE: Interface '%s' %s",
1282                            event.interface_status.ifname,
1283                            ifan->ifan_what == IFAN_DEPARTURE ?
1284                                 "removed" : "added");
1285                 wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);
1286                 break;
1287         case RTM_IEEE80211:
1288                 ifan = (struct if_announcemsghdr *) rtm;
1289                 if (ifan->ifan_index != drv->ifindex)
1290                         break;
1291                 switch (ifan->ifan_what) {
1292                 case RTM_IEEE80211_ASSOC:
1293                 case RTM_IEEE80211_REASSOC:
1294                         wpa_supplicant_event(ctx, EVENT_ASSOC, NULL);
1295                         break;
1296                 case RTM_IEEE80211_DISASSOC:
1297                         wpa_supplicant_event(ctx, EVENT_DISASSOC, NULL);
1298                         break;
1299                 case RTM_IEEE80211_SCAN:
1300                         wpa_supplicant_event(ctx, EVENT_SCAN_RESULTS, NULL);
1301                         break;
1302                 case RTM_IEEE80211_REPLAY:
1303                         /* ignore */
1304                         break;
1305                 case RTM_IEEE80211_MICHAEL:
1306                         mic = (struct ieee80211_michael_event *) &ifan[1];
1307                         wpa_printf(MSG_DEBUG,
1308                                 "Michael MIC failure wireless event: "
1309                                 "keyix=%u src_addr=" MACSTR, mic->iev_keyix,
1310                                 MAC2STR(mic->iev_src));
1311
1312                         os_memset(&event, 0, sizeof(event));
1313                         event.michael_mic_failure.unicast =
1314                                 !IEEE80211_IS_MULTICAST(mic->iev_dst);
1315                         wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE,
1316                                 &event);
1317                         break;
1318                 }
1319                 break;
1320         case RTM_IFINFO:
1321                 ifm = (struct if_msghdr *) rtm;
1322                 if (ifm->ifm_index != drv->ifindex)
1323                         break;
1324                 if ((rtm->rtm_flags & RTF_UP) == 0) {
1325                         strlcpy(event.interface_status.ifname, drv->ifname,
1326                                 sizeof(event.interface_status.ifname));
1327                         event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
1328                         wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' DOWN",
1329                                    event.interface_status.ifname);
1330                         wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);
1331                 }
1332                 break;
1333         }
1334 }
1335
1336 static void
1337 wpa_driver_bsd_add_scan_entry(struct wpa_scan_results *res,
1338                               struct ieee80211req_scan_result *sr)
1339 {
1340         struct wpa_scan_res *result, **tmp;
1341         size_t extra_len;
1342         u8 *pos;
1343
1344         extra_len = 2 + sr->isr_ssid_len;
1345         extra_len += 2 + sr->isr_nrates;
1346         extra_len += 3; /* ERP IE */
1347         extra_len += sr->isr_ie_len;
1348
1349         result = os_zalloc(sizeof(*result) + extra_len);
1350         if (result == NULL)
1351                 return;
1352         os_memcpy(result->bssid, sr->isr_bssid, ETH_ALEN);
1353         result->freq = sr->isr_freq;
1354         result->beacon_int = sr->isr_intval;
1355         result->caps = sr->isr_capinfo;
1356         result->qual = sr->isr_rssi;
1357         result->noise = sr->isr_noise;
1358
1359         pos = (u8 *)(result + 1);
1360
1361         *pos++ = WLAN_EID_SSID;
1362         *pos++ = sr->isr_ssid_len;
1363         os_memcpy(pos, sr + 1, sr->isr_ssid_len);
1364         pos += sr->isr_ssid_len;
1365
1366         /*
1367          * Deal all rates as supported rate.
1368          * Because net80211 doesn't report extended supported rate or not.
1369          */
1370         *pos++ = WLAN_EID_SUPP_RATES;
1371         *pos++ = sr->isr_nrates;
1372         os_memcpy(pos, sr->isr_rates, sr->isr_nrates);
1373         pos += sr->isr_nrates;
1374
1375         *pos++ = WLAN_EID_ERP_INFO;
1376         *pos++ = 1;
1377         *pos++ = sr->isr_erp;
1378
1379         os_memcpy(pos, (u8 *)(sr + 1) + sr->isr_ssid_len, sr->isr_ie_len);
1380         pos += sr->isr_ie_len;
1381
1382         result->ie_len = pos - (u8 *)(result + 1);
1383
1384         tmp = os_realloc(res->res,
1385                          (res->num + 1) * sizeof(struct wpa_scan_res *));
1386         if (tmp == NULL) {
1387                 os_free(result);
1388                 return;
1389         }
1390         tmp[res->num++] = result;
1391         res->res = tmp;
1392 }
1393
1394 struct wpa_scan_results *
1395 wpa_driver_bsd_get_scan_results2(void *priv)
1396 {
1397         struct wpa_driver_bsd_data *drv = priv;
1398         struct ieee80211req_scan_result *sr;
1399         struct wpa_scan_results *res;
1400         int len, rest;
1401         uint8_t buf[24*1024], *pos;
1402
1403         len = get80211var(drv, IEEE80211_IOC_SCAN_RESULTS, buf, 24*1024);
1404         if (len < 0)
1405                 return NULL;
1406
1407         res = os_zalloc(sizeof(*res));
1408         if (res == NULL)
1409                 return NULL;
1410
1411         pos = buf;
1412         rest = len;
1413         while (rest >= sizeof(struct ieee80211req_scan_result)) {
1414                 sr = (struct ieee80211req_scan_result *)pos;
1415                 wpa_driver_bsd_add_scan_entry(res, sr);
1416                 pos += sr->isr_len;
1417                 rest -= sr->isr_len;
1418         }
1419
1420         wpa_printf(MSG_DEBUG, "Received %d bytes of scan results (%lu BSSes)",
1421                    len, (unsigned long)res->num);
1422
1423         return res;
1424 }
1425
1426 static void *
1427 wpa_driver_bsd_init(void *ctx, const char *ifname)
1428 {
1429 #define GETPARAM(drv, param, v) \
1430         (((v) = get80211param(drv, param)) != -1)
1431         struct wpa_driver_bsd_data *drv;
1432
1433         drv = os_zalloc(sizeof(*drv));
1434         if (drv == NULL)
1435                 return NULL;
1436         /*
1437          * NB: We require the interface name be mappable to an index.
1438          *     This implies we do not support having wpa_supplicant
1439          *     wait for an interface to appear.  This seems ok; that
1440          *     doesn't belong here; it's really the job of devd.
1441          */
1442         drv->ifindex = if_nametoindex(ifname);
1443         if (drv->ifindex == 0) {
1444                 wpa_printf(MSG_DEBUG, "%s: interface %s does not exist",
1445                            __func__, ifname);
1446                 goto fail1;
1447         }
1448         drv->sock = socket(PF_INET, SOCK_DGRAM, 0);
1449         if (drv->sock < 0)
1450                 goto fail1;
1451         drv->route = socket(PF_ROUTE, SOCK_RAW, 0);
1452         if (drv->route < 0)
1453                 goto fail;
1454         eloop_register_read_sock(drv->route,
1455                 wpa_driver_bsd_event_receive, ctx, drv);
1456
1457         drv->ctx = ctx;
1458         os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
1459
1460         if (!GETPARAM(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming)) {
1461                 wpa_printf(MSG_DEBUG, "%s: failed to get roaming state: %s",
1462                         __func__, strerror(errno));
1463                 goto fail;
1464         }
1465         if (!GETPARAM(drv, IEEE80211_IOC_PRIVACY, drv->prev_privacy)) {
1466                 wpa_printf(MSG_DEBUG, "%s: failed to get privacy state: %s",
1467                         __func__, strerror(errno));
1468                 goto fail;
1469         }
1470         if (!GETPARAM(drv, IEEE80211_IOC_WPA, drv->prev_wpa)) {
1471                 wpa_printf(MSG_DEBUG, "%s: failed to get wpa state: %s",
1472                         __func__, strerror(errno));
1473                 goto fail;
1474         }
1475         if (set80211param(drv, IEEE80211_IOC_ROAMING, IEEE80211_ROAMING_MANUAL) < 0) {
1476                 wpa_printf(MSG_DEBUG, "%s: failed to set wpa_supplicant-based "
1477                            "roaming: %s", __func__, strerror(errno));
1478                 goto fail;
1479         }
1480
1481         if (set80211param(drv, IEEE80211_IOC_WPA, 1+2) < 0) {
1482                 wpa_printf(MSG_DEBUG, "%s: failed to enable WPA support %s",
1483                            __func__, strerror(errno));
1484                 goto fail;
1485         }
1486
1487         return drv;
1488 fail:
1489         close(drv->sock);
1490 fail1:
1491         os_free(drv);
1492         return NULL;
1493 #undef GETPARAM
1494 }
1495
1496 static void
1497 wpa_driver_bsd_deinit(void *priv)
1498 {
1499         struct wpa_driver_bsd_data *drv = priv;
1500         int flags;
1501
1502         eloop_unregister_read_sock(drv->route);
1503
1504         /* NB: mark interface down */
1505         if (getifflags(drv, &flags) == 0)
1506                 (void) setifflags(drv, flags &~ IFF_UP);
1507
1508         wpa_driver_bsd_set_wpa_internal(drv, drv->prev_wpa, drv->prev_privacy);
1509         if (set80211param(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming) < 0)
1510                 wpa_printf(MSG_DEBUG, "%s: failed to restore roaming state",
1511                         __func__);
1512
1513         (void) close(drv->route);               /* ioctl socket */
1514         (void) close(drv->sock);                /* event socket */
1515         os_free(drv);
1516 }
1517
1518
1519 const struct wpa_driver_ops wpa_driver_bsd_ops = {
1520         .name                   = "bsd",
1521         .desc                   = "BSD 802.11 support",
1522         .init                   = wpa_driver_bsd_init,
1523         .deinit                 = wpa_driver_bsd_deinit,
1524         .get_bssid              = wpa_driver_bsd_get_bssid,
1525         .get_ssid               = wpa_driver_bsd_get_ssid,
1526         .set_wpa                = wpa_driver_bsd_set_wpa,
1527         .set_key                = wpa_driver_bsd_set_key,
1528         .set_countermeasures    = wpa_driver_bsd_set_countermeasures,
1529         .set_drop_unencrypted   = wpa_driver_bsd_set_drop_unencrypted,
1530         .scan                   = wpa_driver_bsd_scan,
1531         .get_scan_results2      = wpa_driver_bsd_get_scan_results2,
1532         .deauthenticate         = wpa_driver_bsd_deauthenticate,
1533         .disassociate           = wpa_driver_bsd_disassociate,
1534         .associate              = wpa_driver_bsd_associate,
1535         .set_auth_alg           = wpa_driver_bsd_set_auth_alg,
1536 };
1537
1538 #endif /* HOSTAPD */