]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - usr.sbin/wpa/hostapd/driver_freebsd.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / usr.sbin / wpa / hostapd / driver_freebsd.c
1 /*
2  * Host AP - 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  * $FreeBSD$
16  */
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <unistd.h>
20 #include <string.h>
21 #include <sys/ioctl.h>
22 #include <errno.h>
23
24 #include <sys/socket.h>
25 #include <net/if.h>
26 #include <netinet/in.h>
27
28 #include <net80211/ieee80211_ioctl.h>
29
30 #undef RSN_VERSION
31 #undef WPA_VERSION
32 #undef WPA_OUI_TYPE
33 #undef WME_OUI_TYPE
34
35 #include "hostapd.h"
36 #include "driver.h"
37 #include "ieee802_1x.h"
38 #include "ieee802_11_auth.h"
39 #include "eloop.h"
40 #include "sta_info.h"
41 #include "l2_packet/l2_packet.h"
42
43 #include "eapol_sm.h"
44 #include "wpa.h"
45 #include "radius/radius.h"
46 #include "ieee802_11.h"
47 #include "common.h"
48 #include "hostap_common.h"
49
50 struct bsd_driver_data {
51         struct hostapd_data *hapd;              /* back pointer */
52
53         char    iface[IFNAMSIZ + 1];
54         unsigned int ifindex;                   /* interface index */
55         struct l2_packet_data *sock_xmit;       /* raw packet xmit socket */
56         int     ioctl_sock;                     /* socket for ioctl() use */
57         int     wext_sock;                      /* socket for wireless events */
58 };
59
60 static const struct wpa_driver_ops bsd_driver_ops;
61
62 static int bsd_sta_deauth(void *priv, const u8 *addr, int reason_code);
63
64 static int
65 set80211var(struct bsd_driver_data *drv, int op, const void *arg, int arg_len)
66 {
67         struct ieee80211req ireq;
68
69         memset(&ireq, 0, sizeof(ireq));
70         strncpy(ireq.i_name, drv->iface, IFNAMSIZ);
71         ireq.i_type = op;
72         ireq.i_len = arg_len;
73         ireq.i_data = (void *) arg;
74
75         if (ioctl(drv->ioctl_sock, SIOCS80211, &ireq) < 0) {
76                 perror("ioctl[SIOCS80211]");
77                 return -1;
78         }
79         return 0;
80 }
81
82 static int
83 get80211var(struct bsd_driver_data *drv, int op, void *arg, int arg_len)
84 {
85         struct ieee80211req ireq;
86
87         memset(&ireq, 0, sizeof(ireq));
88         strncpy(ireq.i_name, drv->iface, IFNAMSIZ);
89         ireq.i_type = op;
90         ireq.i_len = arg_len;
91         ireq.i_data = arg;
92
93         if (ioctl(drv->ioctl_sock, SIOCG80211, &ireq) < 0) {
94                 perror("ioctl[SIOCG80211]");
95                 return -1;
96         }
97         return ireq.i_len;
98 }
99
100 static int
101 set80211param(struct bsd_driver_data *drv, int op, int arg)
102 {
103         struct ieee80211req ireq;
104
105         memset(&ireq, 0, sizeof(ireq));
106         strncpy(ireq.i_name, drv->iface, IFNAMSIZ);
107         ireq.i_type = op;
108         ireq.i_val = arg;
109
110         if (ioctl(drv->ioctl_sock, SIOCS80211, &ireq) < 0) {
111                 perror("ioctl[SIOCS80211]");
112                 return -1;
113         }
114         return 0;
115 }
116
117 static const char *
118 ether_sprintf(const u8 *addr)
119 {
120         static char buf[sizeof(MACSTR)];
121
122         if (addr != NULL)
123                 snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
124         else
125                 snprintf(buf, sizeof(buf), MACSTR, 0,0,0,0,0,0);
126         return buf;
127 }
128
129 static int
130 bsd_set_iface_flags(void *priv, int flags)
131 {
132         struct bsd_driver_data *drv = priv;
133         struct hostapd_data *hapd = drv->hapd;
134         struct ifreq ifr;
135
136         wpa_printf(MSG_DEBUG, "%s: flags=0x%x\n", __func__, flags);
137
138         if (drv->ioctl_sock < 0)
139                 return -1;
140
141         memset(&ifr, 0, sizeof(ifr));
142         snprintf(ifr.ifr_name, IFNAMSIZ, "%s", drv->iface);
143
144         if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, &ifr) != 0) {
145                 perror("ioctl[SIOCGIFFLAGS]");
146                 return -1;
147         }
148
149         if (flags < 0) {
150                 flags = -flags;
151                 if ((ifr.ifr_flags & flags) == 0)
152                         return 0;
153                 ifr.ifr_flags &= ~flags;
154         } else {
155                 if ((ifr.ifr_flags & flags) == flags)
156                         return 0;
157                 ifr.ifr_flags |= flags;
158         }
159
160         if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, &ifr) != 0) {
161                 perror("ioctl[SIOCSIFFLAGS]");
162                 return -1;
163         }
164         return 0;
165 }
166
167 static int
168 bsd_commit(void *priv)
169 {
170         return bsd_set_iface_flags(priv, IFF_UP);
171 }
172
173 static int
174 bsd_set_ieee8021x(const char *ifname, void *priv, int enabled)
175 {
176         struct bsd_driver_data *drv = priv;
177         struct hostapd_data *hapd = drv->hapd;
178         struct hostapd_bss_config *conf = hapd->conf;
179
180         wpa_printf(MSG_DEBUG, "%s: enabled=%d\n", __func__, enabled);
181
182         if (!enabled) {
183                 /* XXX restore state */
184                 return set80211param(priv, IEEE80211_IOC_AUTHMODE,
185                         IEEE80211_AUTH_AUTO);
186         }
187         if (!conf->wpa && !conf->ieee802_1x) {
188                 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER,
189                         HOSTAPD_LEVEL_WARNING, "No 802.1X or WPA enabled!");
190                 return -1;
191         }
192         if (conf->wpa && set80211param(drv, IEEE80211_IOC_WPA, conf->wpa)) {
193                 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER,
194                         HOSTAPD_LEVEL_WARNING, "Error configuring WPA state!");
195                 return -1;
196         }
197         if (set80211param(priv, IEEE80211_IOC_AUTHMODE,
198                 (conf->wpa ?  IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) {
199                 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER,
200                         HOSTAPD_LEVEL_WARNING, "Error enabling WPA/802.1X!");
201                 return -1;
202         }
203         return 0;
204 }
205
206 static int
207 bsd_set_privacy(const char *ifname, void *priv, int enabled)
208 {
209         struct bsd_driver_data *drv = priv;
210         struct hostapd_data *hapd = drv->hapd;
211
212         wpa_printf(MSG_DEBUG, "%s: enabled=%d\n", __func__, enabled);
213
214         return set80211param(priv, IEEE80211_IOC_PRIVACY, enabled);
215 }
216
217 static int
218 bsd_set_sta_authorized(void *priv, const u8 *addr, int authorized)
219 {
220         struct bsd_driver_data *drv = priv;
221         struct hostapd_data *hapd = drv->hapd;
222         struct ieee80211req_mlme mlme;
223
224         wpa_printf(MSG_DEBUG, "%s: addr=%s authorized=%d\n",
225                 __func__, ether_sprintf(addr), authorized);
226
227         if (authorized)
228                 mlme.im_op = IEEE80211_MLME_AUTHORIZE;
229         else
230                 mlme.im_op = IEEE80211_MLME_UNAUTHORIZE;
231         mlme.im_reason = 0;
232         memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
233         return set80211var(priv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme));
234 }
235
236 static int
237 bsd_sta_set_flags(void *priv, const u8 *addr, int total_flags,
238         int flags_or, int flags_and)
239 {
240         /* For now, only support setting Authorized flag */
241         if (flags_or & WLAN_STA_AUTHORIZED)
242                 return bsd_set_sta_authorized(priv, addr, 1);
243         if (!(flags_and & WLAN_STA_AUTHORIZED))
244                 return bsd_set_sta_authorized(priv, addr, 0);
245         return 0;
246 }
247
248 static int
249 bsd_del_key(void *priv, const unsigned char *addr, int key_idx)
250 {
251         struct bsd_driver_data *drv = priv;
252         struct hostapd_data *hapd = drv->hapd;
253         struct ieee80211req_del_key wk;
254
255         wpa_printf(MSG_DEBUG, "%s: addr=%s key_idx=%d\n",
256                 __func__, ether_sprintf(addr), key_idx);
257
258         memset(&wk, 0, sizeof(wk));
259         if (addr != NULL) {
260                 memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN);
261                 wk.idk_keyix = (u_int8_t) IEEE80211_KEYIX_NONE; /* XXX */
262         } else {
263                 wk.idk_keyix = key_idx;
264         }
265
266         return set80211var(priv, IEEE80211_IOC_DELKEY, &wk, sizeof(wk));
267 }
268
269 static int
270 bsd_set_key(const char *ifname, void *priv, const char *alg,
271             const u8 *addr, int key_idx,
272             const u8 *key, size_t key_len, int txkey)
273 {
274         struct bsd_driver_data *drv = priv;
275         struct hostapd_data *hapd = drv->hapd;
276         struct ieee80211req_key wk;
277         u_int8_t cipher;
278
279         if (strcmp(alg, "none") == 0)
280                 return bsd_del_key(priv, addr, key_idx);
281
282         wpa_printf(MSG_DEBUG, "%s: alg=%s addr=%s key_idx=%d\n",
283                 __func__, alg, ether_sprintf(addr), key_idx);
284
285         if (strcmp(alg, "WEP") == 0)
286                 cipher = IEEE80211_CIPHER_WEP;
287         else if (strcmp(alg, "TKIP") == 0)
288                 cipher = IEEE80211_CIPHER_TKIP;
289         else if (strcmp(alg, "CCMP") == 0)
290                 cipher = IEEE80211_CIPHER_AES_CCM;
291         else {
292                 printf("%s: unknown/unsupported algorithm %s\n",
293                         __func__, alg);
294                 return -1;
295         }
296
297         if (key_len > sizeof(wk.ik_keydata)) {
298                 printf("%s: key length %d too big\n", __func__, key_len);
299                 return -3;
300         }
301
302         memset(&wk, 0, sizeof(wk));
303         wk.ik_type = cipher;
304         if (addr == NULL) {
305                 memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
306                 wk.ik_keyix = key_idx;
307                 wk.ik_flags = IEEE80211_KEY_XMIT
308                             | IEEE80211_KEY_GROUP
309                             | IEEE80211_KEY_DEFAULT;
310         } else {
311                 memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
312                 wk.ik_keyix = IEEE80211_KEYIX_NONE;
313                 wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT;
314         }
315         wk.ik_keylen = key_len;
316         memcpy(wk.ik_keydata, key, key_len);
317
318         return set80211var(priv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk));
319 }
320
321
322 static int
323 bsd_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx,
324                u8 *seq)
325 {
326         struct bsd_driver_data *drv = priv;
327         struct hostapd_data *hapd = drv->hapd;
328         struct ieee80211req_key wk;
329
330         wpa_printf(MSG_DEBUG, "%s: addr=%s idx=%d\n",
331             __func__, ether_sprintf(addr), idx);
332
333         memset(&wk, 0, sizeof(wk));
334         if (addr == NULL)
335                 memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
336         else
337                 memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
338         wk.ik_keyix = idx;
339
340         if (get80211var(drv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk)) < 0) {
341                 printf("Failed to get encryption.\n");
342                 return -1;
343         } else {
344                 /* NB: upper layer expects tsc in network order */
345                 wk.ik_keytsc = htole64(wk.ik_keytsc);
346                 memcpy(seq, &wk.ik_keytsc, sizeof(wk.ik_keytsc));
347                 return 0;
348         }
349 }
350
351
352 static int 
353 bsd_flush(void *priv)
354 {
355         u8 allsta[IEEE80211_ADDR_LEN];
356
357         memset(allsta, 0xff, IEEE80211_ADDR_LEN);
358         return bsd_sta_deauth(priv, allsta, IEEE80211_REASON_AUTH_LEAVE);
359 }
360
361
362 static int
363 bsd_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data,
364                          const u8 *addr)
365 {
366         struct bsd_driver_data *drv = priv;
367         struct ieee80211req_sta_stats stats;
368
369         memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN);
370         if (get80211var(drv, IEEE80211_IOC_STA_STATS, &stats, sizeof(stats)) > 0) {
371                 /* XXX? do packets counts include non-data frames? */
372                 data->rx_packets = stats.is_stats.ns_rx_data;
373                 data->rx_bytes = stats.is_stats.ns_rx_bytes;
374                 data->tx_packets = stats.is_stats.ns_tx_data;
375                 data->tx_bytes = stats.is_stats.ns_tx_bytes;
376         }
377         return 0;
378 }
379
380 static int
381 bsd_sta_clear_stats(void *priv, const u8 *addr)
382 {
383         struct bsd_driver_data *drv = priv;
384         struct hostapd_data *hapd = drv->hapd;
385         struct ieee80211req_sta_stats stats;
386         
387         wpa_printf(MSG_DEBUG, "%s: addr=%s\n", __func__, ether_sprintf(addr));
388
389         /* zero station statistics */
390         memset(&stats, 0, sizeof(stats));
391         memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN);
392         return set80211var(drv, IEEE80211_IOC_STA_STATS, &stats, sizeof(stats));
393 }
394
395 static int
396 bsd_set_opt_ie(const char *ifname, void *priv, const u8 *ie, size_t ie_len)
397 {
398         struct bsd_driver_data *drv = priv;
399         struct hostapd_data *hapd = drv->hapd;
400         struct ieee80211req ireq;
401
402         memset(&ireq, 0, sizeof(ireq));
403         strncpy(ireq.i_name, drv->iface, IFNAMSIZ);
404         ireq.i_type = IEEE80211_IOC_APPIE;
405         ireq.i_val = IEEE80211_APPIE_WPA;
406         ireq.i_data = (void *) ie;
407         ireq.i_len = ie_len;
408
409         wpa_printf(MSG_DEBUG, "%s: set WPA+RSN ie (len %d)\n",
410             __func__, ie_len);
411         if (ioctl(drv->ioctl_sock, SIOCS80211, &ireq) < 0) {
412                 printf("Unable to set WPA+RSN ie\n");
413                 return -1;
414         }
415         return 0;
416 }
417
418 static int
419 bsd_sta_deauth(void *priv, const u8 *addr, int reason_code)
420 {
421         struct bsd_driver_data *drv = priv;
422         struct hostapd_data *hapd = drv->hapd;
423         struct ieee80211req_mlme mlme;
424
425         wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d\n",
426                 __func__, ether_sprintf(addr), reason_code);
427
428         mlme.im_op = IEEE80211_MLME_DEAUTH;
429         mlme.im_reason = reason_code;
430         memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
431         return set80211var(priv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme));
432 }
433
434 static int
435 bsd_sta_disassoc(void *priv, const u8 *addr, int reason_code)
436 {
437         struct bsd_driver_data *drv = priv;
438         struct hostapd_data *hapd = drv->hapd;
439         struct ieee80211req_mlme mlme;
440
441         wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d\n",
442                 __func__, ether_sprintf(addr), reason_code);
443
444         mlme.im_reason = reason_code;
445         memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
446         return set80211var(priv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme));
447 }
448
449 static int
450 bsd_del_sta(struct bsd_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN])
451 {
452         struct hostapd_data *hapd = drv->hapd;
453         struct hostapd_bss_config *conf = hapd->conf;
454         struct sta_info *sta;
455
456         hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
457                 HOSTAPD_LEVEL_INFO, "deassociated");
458
459         sta = ap_get_sta(hapd, addr);
460         if (sta != NULL) {
461                 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
462                 if (conf->wpa)
463                         wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
464                 sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
465                 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
466                 ap_free_sta(hapd, sta);
467         }
468         return 0;
469 }
470
471 static int
472 bsd_new_sta(struct bsd_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN])
473 {
474         struct hostapd_data *hapd = drv->hapd;
475         struct hostapd_bss_config *conf = hapd->conf;
476         struct sta_info *sta;
477         struct ieee80211req_wpaie ie;
478         int new_assoc, ielen, res;
479
480         hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
481                 HOSTAPD_LEVEL_INFO, "associated");
482
483         sta = ap_sta_add(hapd, addr);
484         if (sta == NULL)
485                 return -1;
486         /*
487          * Fetch and validate any negotiated WPA/RSN parameters.
488          */
489         if (conf->wpa) {
490                 memset(&ie, 0, sizeof(ie));
491                 memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN);
492                 if (get80211var(drv, IEEE80211_IOC_WPAIE, &ie, sizeof(ie)) < 0) {
493                         printf("Failed to get WPA/RSN information element.\n");
494                         return -1;              /* XXX not right */
495                 }
496                 if (ie.wpa_ie[1] == 0) {
497                         printf("No WPA/RSN information element for station!\n");
498                         return -1;              /* XXX not right */
499                 }
500                 if (sta->wpa_sm == NULL)
501                         sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
502                                                         sta->addr);
503                 if (sta->wpa_sm == NULL) {
504                         printf("Failed to initialize WPA state machine\n");
505                         return -1;
506                 }
507                 ielen = 2 + ie.wpa_ie[1];
508                 res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
509                                           ie.wpa_ie, ielen, NULL, 0);
510                 if (res != WPA_IE_OK) {
511                         printf("WPA/RSN information element rejected? "
512                                 "(res %u)\n", res);
513                         return -1;
514                 }
515         }
516
517         /*
518          * Now that the internal station state is setup
519          * kick the authenticator into action.
520          */
521         new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;
522         sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
523         wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
524         hostapd_new_assoc_sta(hapd, sta, !new_assoc);
525         ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
526
527         return 0;
528 }
529
530 #include <net/route.h>
531 #include <net80211/ieee80211_freebsd.h>
532
533 static void
534 bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx)
535 {
536         struct bsd_driver_data *drv = ctx;
537         struct hostapd_data *hapd = drv->hapd;
538         char buf[2048];
539         struct if_announcemsghdr *ifan;
540         struct rt_msghdr *rtm;
541         struct ieee80211_michael_event *mic;
542         struct ieee80211_join_event *join;
543         struct ieee80211_leave_event *leave;
544 #ifdef CONFIG_DRIVER_RADIUS_ACL
545         struct ieee80211_auth_event *auth;
546 #endif
547         int n;
548
549         n = read(sock, buf, sizeof(buf));
550         if (n < 0) {
551                 if (errno != EINTR && errno != EAGAIN)
552                         perror("read(PF_ROUTE)");
553                 return;
554         }
555
556         rtm = (struct rt_msghdr *) buf;
557         if (rtm->rtm_version != RTM_VERSION) {
558                 wpa_printf(MSG_DEBUG, "Routing message version %d not "
559                         "understood\n", rtm->rtm_version);
560                 return;
561         }
562         ifan = (struct if_announcemsghdr *) rtm;
563         if (ifan->ifan_index != drv->ifindex) {
564                 wpa_printf(MSG_DEBUG, "Discard routing message to if#%d "
565                         "(not for us %d)\n",
566                         ifan->ifan_index, drv->ifindex);
567                 return;
568         }
569         switch (rtm->rtm_type) {
570         case RTM_IEEE80211:
571                 switch (ifan->ifan_what) {
572                 case RTM_IEEE80211_ASSOC:
573                 case RTM_IEEE80211_REASSOC:
574                 case RTM_IEEE80211_DISASSOC:
575                 case RTM_IEEE80211_SCAN:
576                         break;
577                 case RTM_IEEE80211_LEAVE:
578                         leave = (struct ieee80211_leave_event *) &ifan[1];
579                         bsd_del_sta(drv, leave->iev_addr);
580                         break;
581                 case RTM_IEEE80211_JOIN:
582 #ifdef RTM_IEEE80211_REJOIN
583                 case RTM_IEEE80211_REJOIN:
584 #endif
585                         join = (struct ieee80211_join_event *) &ifan[1];
586                         bsd_new_sta(drv, join->iev_addr);
587                         break;
588                 case RTM_IEEE80211_REPLAY:
589                         /* ignore */
590                         break;
591                 case RTM_IEEE80211_MICHAEL:
592                         mic = (struct ieee80211_michael_event *) &ifan[1];
593                         wpa_printf(MSG_DEBUG,
594                                 "Michael MIC failure wireless event: "
595                                 "keyix=%u src_addr=" MACSTR, mic->iev_keyix,
596                                 MAC2STR(mic->iev_src));
597                         ieee80211_michael_mic_failure(hapd, mic->iev_src, 1);
598                         break;
599 #ifdef CONFIG_DRIVER_RADIUS_ACL
600                 case RTM_IEEE80211_AUTH:
601                         auth = (struct ieee80211_auth_event *) &ifan[1];
602                         wpa_printf(MSG_DEBUG, "802.11 AUTH, STA = " MACSTR,
603                             MAC2STR(auth->iev_addr));
604                         n = hostapd_allowed_address(hapd, auth->iev_addr,
605                                 NULL, 0, NULL, NULL, NULL);
606                         switch (n) {
607                         case HOSTAPD_ACL_ACCEPT:
608                         case HOSTAPD_ACL_REJECT:
609                                 hostapd_set_radius_acl_auth(hapd,
610                                     auth->iev_addr, n, 0);
611                                 wpa_printf(MSG_DEBUG,
612                                     "802.11 AUTH, STA = " MACSTR " hostapd says: %s",
613                                     MAC2STR(auth->iev_addr),
614                                     (n == HOSTAPD_ACL_ACCEPT ?
615                                         "ACCEPT" : "REJECT" ));
616                                 break;
617                         case HOSTAPD_ACL_PENDING:
618                                 wpa_printf(MSG_DEBUG,
619                                     "802.11 AUTH, STA = " MACSTR " pending",
620                                     MAC2STR(auth->iev_addr));
621                                 break;
622                         }
623                         break;
624 #endif /* CONFIG_DRIVER_RADIUS_ACL */
625                 }
626                 break;
627         }
628 }
629
630 static int
631 bsd_wireless_event_init(void *priv)
632 {
633         struct bsd_driver_data *drv = priv;
634         int s;
635
636         drv->wext_sock = -1;
637
638         s = socket(PF_ROUTE, SOCK_RAW, 0);
639         if (s < 0) {
640                 perror("socket(PF_ROUTE,SOCK_RAW)");
641                 return -1;
642         }
643         eloop_register_read_sock(s, bsd_wireless_event_receive, drv, NULL);
644         drv->wext_sock = s;
645
646         return 0;
647 }
648
649 static void
650 bsd_wireless_event_deinit(void *priv)
651 {
652         struct bsd_driver_data *drv = priv;
653
654         if (drv != NULL) {
655                 if (drv->wext_sock < 0)
656                         return;
657                 eloop_unregister_read_sock(drv->wext_sock);
658                 close(drv->wext_sock);
659         }
660 }
661
662
663 static int
664 bsd_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len,
665                int encrypt, const u8 *own_addr)
666 {
667         struct bsd_driver_data *drv = priv;
668         struct hostapd_data *hapd = drv->hapd;
669         unsigned char buf[3000];
670         unsigned char *bp = buf;
671         struct l2_ethhdr *eth;
672         size_t len;
673         int status;
674
675         /*
676          * Prepend the Etherent header.  If the caller left us
677          * space at the front we could just insert it but since
678          * we don't know we copy to a local buffer.  Given the frequency
679          * and size of frames this probably doesn't matter.
680          */
681         len = data_len + sizeof(struct l2_ethhdr);
682         if (len > sizeof(buf)) {
683                 bp = malloc(len);
684                 if (bp == NULL) {
685                         printf("EAPOL frame discarded, cannot malloc temp "
686                                 "buffer of size %u!\n", len);
687                         return -1;
688                 }
689         }
690         eth = (struct l2_ethhdr *) bp;
691         memcpy(eth->h_dest, addr, ETH_ALEN);
692         memcpy(eth->h_source, own_addr, ETH_ALEN);
693         eth->h_proto = htons(ETH_P_EAPOL);
694         memcpy(eth+1, data, data_len);
695
696         wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", bp, len);
697
698         status = l2_packet_send(drv->sock_xmit, addr, ETH_P_EAPOL, bp, len);
699
700         if (bp != buf)
701                 free(bp);
702         return status;
703 }
704
705 static void
706 handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)
707 {
708         struct bsd_driver_data *drv = ctx;
709         struct hostapd_data *hapd = drv->hapd;
710         struct sta_info *sta;
711
712         sta = ap_get_sta(hapd, src_addr);
713         if (!sta || !(sta->flags & WLAN_STA_ASSOC)) {
714                 printf("Data frame from not associated STA %s\n",
715                        ether_sprintf(src_addr));
716                 /* XXX cannot happen */
717                 return;
718         }
719         ieee802_1x_receive(hapd, src_addr, buf + sizeof(struct l2_ethhdr),
720                            len - sizeof(struct l2_ethhdr));
721 }
722
723 static int
724 bsd_get_ssid(const char *ifname, void *priv, u8 *buf, int len)
725 {
726         struct bsd_driver_data *drv = priv;
727         struct hostapd_data *hapd = drv->hapd;
728         int ssid_len = get80211var(priv, IEEE80211_IOC_SSID, buf, len);
729
730         wpa_printf(MSG_DEBUG, "%s: ssid=\"%.*s\"\n", __func__, ssid_len, buf);
731
732         return ssid_len;
733 }
734
735 static int
736 bsd_set_ssid(const char *ifname, void *priv, const u8 *buf, int len)
737 {
738         struct bsd_driver_data *drv = priv;
739         struct hostapd_data *hapd = drv->hapd;
740
741         wpa_printf(MSG_DEBUG, "%s: ssid=\"%.*s\"\n", __func__, len, buf);
742
743         return set80211var(priv, IEEE80211_IOC_SSID, buf, len);
744 }
745
746 static int
747 bsd_set_countermeasures(void *priv, int enabled)
748 {
749         struct bsd_driver_data *drv = priv;
750
751         wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
752         return set80211param(drv, IEEE80211_IOC_COUNTERMEASURES, enabled);
753 }
754
755 #ifdef CONFIG_DRIVER_RADIUS_ACL
756 static int 
757 bsd_set_radius_acl_auth(void *priv, const u8 *mac, int accepted, 
758         u32 session_timeout)
759 {
760         struct bsd_driver_data *drv = priv;
761         struct hostapd_data *hapd = drv->hapd;
762         struct ieee80211req_mlme mlme;
763
764         switch (accepted) {
765         case HOSTAPD_ACL_ACCEPT_TIMEOUT:
766                 wpa_printf(MSG_DEBUG, "[%s] STA " MACSTR 
767                         " has been accepted by RADIUS ACL with timeout "
768                         "of %d.\n", hapd->conf->iface, MAC2STR(mac), 
769                         session_timeout);
770                 mlme.im_reason = IEEE80211_STATUS_SUCCESS;
771                 break;
772         case HOSTAPD_ACL_ACCEPT:
773                 wpa_printf(MSG_DEBUG, "[%s] STA " MACSTR 
774                         " has been accepted by RADIUS ACL.\n", 
775                         hapd->conf->iface, MAC2STR(mac));
776                 mlme.im_reason = IEEE80211_STATUS_SUCCESS;
777                 break;
778         case HOSTAPD_ACL_REJECT:
779                 wpa_printf(MSG_DEBUG, "[%s] STA " MACSTR 
780                         " has been rejected by RADIUS ACL.\n", 
781                         hapd->conf->iface, MAC2STR(mac));
782                 mlme.im_reason = IEEE80211_STATUS_UNSPECIFIED;
783                 break;
784         default:
785                 wpa_printf(MSG_ERROR, "[%s] STA " MACSTR 
786                         " has unknown status (%d) by RADIUS ACL.  "
787                         "Nothing to do...\n", hapd->conf->iface, 
788                         MAC2STR(mac), accepted);
789                 return 0;
790         }
791         memset(&mlme, 0, sizeof(mlme));
792         mlme.im_op = IEEE80211_MLME_AUTH;
793         memcpy(mlme.im_macaddr, mac, IEEE80211_ADDR_LEN);
794         return set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme));
795 }
796
797 static int
798 bsd_set_radius_acl_expire(void *priv, const u8 *mac)
799 {
800         struct bsd_driver_data *drv = priv;
801         struct hostapd_data *hapd = drv->hapd;
802
803         /*
804          * The expiry of the MAC address from RADIUS ACL cache doesn't mean 
805          * that we should kick off the client.  Our current approach doesn't 
806          * require adding/removing entries from an allow/deny list; so this
807          * function is likely unecessary
808          */
809         wpa_printf(MSG_DEBUG, "[%s] STA " MACSTR " radius acl cache "
810                 "expired; nothing to do...", hapd->conf->iface, 
811                 MAC2STR(mac));
812         return 0;
813 }
814 #endif /* CONFIG_DRIVER_RADIUS_ACL */
815
816 static void *
817 bsd_init(struct hostapd_data *hapd)
818 {
819         struct bsd_driver_data *drv;
820
821         drv = malloc(sizeof(struct bsd_driver_data));
822         if (drv == NULL) {
823                 printf("Could not allocate memory for bsd driver data\n");
824                 goto bad;
825         }
826
827         memset(drv, 0, sizeof(*drv));
828         drv->hapd = hapd;
829         drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
830         if (drv->ioctl_sock < 0) {
831                 perror("socket[PF_INET,SOCK_DGRAM]");
832                 goto bad;
833         }
834         memcpy(drv->iface, hapd->conf->iface, sizeof(drv->iface));
835         /*
836          * NB: We require the interface name be mappable to an index.
837          *     This implies we do not support having wpa_supplicant
838          *     wait for an interface to appear.  This seems ok; that
839          *     doesn't belong here; it's really the job of devd.
840          *     XXXSCW: devd is FreeBSD-specific.
841          */
842         drv->ifindex = if_nametoindex(drv->iface);
843         if (drv->ifindex == 0) {
844                 printf("%s: interface %s does not exist", __func__, drv->iface);
845                 goto bad;
846         }
847
848         drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL,
849                                         handle_read, drv, 1);
850         if (drv->sock_xmit == NULL)
851                 goto bad;
852         if (l2_packet_get_own_addr(drv->sock_xmit, hapd->own_addr))
853                 goto bad;
854
855         bsd_set_iface_flags(drv, -IFF_UP);      /* mark down during setup */
856
857         return drv;
858 bad:
859         if (drv != NULL) {
860                 if (drv->sock_xmit != NULL)
861                         l2_packet_deinit(drv->sock_xmit);
862                 if (drv->ioctl_sock >= 0)
863                         close(drv->ioctl_sock);
864                 free(drv);
865         }
866         return NULL;
867 }
868
869
870 static void
871 bsd_deinit(void *priv)
872 {
873         struct bsd_driver_data *drv = priv;
874
875         (void) bsd_set_iface_flags(drv, -IFF_UP);
876         if (drv->ioctl_sock >= 0)
877                 close(drv->ioctl_sock);
878         if (drv->sock_xmit != NULL)
879                 l2_packet_deinit(drv->sock_xmit);
880         free(drv);
881 }
882
883 const struct wpa_driver_ops wpa_driver_bsd_ops = {
884         .name                   = "bsd",
885         .init                   = bsd_init,
886         .deinit                 = bsd_deinit,
887         .set_ieee8021x          = bsd_set_ieee8021x,
888         .set_privacy            = bsd_set_privacy,
889         .set_encryption         = bsd_set_key,
890         .get_seqnum             = bsd_get_seqnum,
891         .flush                  = bsd_flush,
892         .set_generic_elem       = bsd_set_opt_ie,
893         .wireless_event_init    = bsd_wireless_event_init,
894         .wireless_event_deinit  = bsd_wireless_event_deinit,
895         .sta_set_flags          = bsd_sta_set_flags,
896         .read_sta_data          = bsd_read_sta_driver_data,
897         .send_eapol             = bsd_send_eapol,
898         .sta_disassoc           = bsd_sta_disassoc,
899         .sta_deauth             = bsd_sta_deauth,
900         .set_ssid               = bsd_set_ssid,
901         .get_ssid               = bsd_get_ssid,
902         .set_countermeasures    = bsd_set_countermeasures,
903         .sta_clear_stats        = bsd_sta_clear_stats,
904         .commit                 = bsd_commit,
905 #ifdef CONFIG_DRIVER_RADIUS_ACL
906         .set_radius_acl_auth    = bsd_set_radius_acl_auth,
907         .set_radius_acl_expire  = bsd_set_radius_acl_expire,
908 #endif
909 };