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