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