- Move pcap_{get_selectable_fd,pcap_inject}() from 802_11/wpa_supplicant/Packet32.c
[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.2.2.1 2006/03/24 01:43:18 sam Exp $
16  * $DragonFly: src/usr.sbin/802_11/hostapd/driver_dragonfly.c,v 1.1 2006/09/02 05:40:35 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, 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", "CKIP", "NONE" };
135         hostapd *hapd = drv->hapd;
136         struct hostapd_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         hostapd *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(void *priv, int enabled)
266 {
267         struct bsd_driver_data *drv = priv;
268         hostapd *hapd = drv->hapd;
269         struct hostapd_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(void *priv, int enabled)
300 {
301         struct bsd_driver_data *drv = priv;
302         hostapd *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, u8 *addr, int authorized)
312 {
313         struct bsd_driver_data *drv = priv;
314         hostapd *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_del_key(void *priv, unsigned char *addr, int key_idx)
332 {
333         struct bsd_driver_data *drv = priv;
334         hostapd *hapd = drv->hapd;
335         struct ieee80211req_del_key wk;
336
337         HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
338                 "%s: addr=%s key_idx=%d\n",
339                 __func__, ether_sprintf(addr), key_idx);
340
341         memset(&wk, 0, sizeof(wk));
342         if (addr != NULL) {
343                 memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN);
344                 wk.idk_keyix = (u_int8_t) IEEE80211_KEYIX_NONE; /* XXX */
345         } else {
346                 wk.idk_keyix = key_idx;
347         }
348
349         return set80211var(priv, IEEE80211_IOC_DELKEY, &wk, sizeof(wk));
350 }
351
352 static int
353 bsd_set_key(void *priv, const char *alg,
354              unsigned char *addr, int key_idx,
355              u8 *key, size_t key_len)
356 {
357         struct bsd_driver_data *drv = priv;
358         hostapd *hapd = drv->hapd;
359         struct ieee80211req_key wk;
360         u_int8_t cipher;
361
362         if (strcmp(alg, "none") == 0)
363                 return bsd_del_key(priv, addr, key_idx);
364
365         HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
366                 "%s: alg=%s addr=%s key_idx=%d\n",
367                 __func__, alg, ether_sprintf(addr), key_idx);
368
369         if (strcmp(alg, "WEP") == 0)
370                 cipher = IEEE80211_CIPHER_WEP;
371         else if (strcmp(alg, "TKIP") == 0)
372                 cipher = IEEE80211_CIPHER_TKIP;
373         else if (strcmp(alg, "CCMP") == 0)
374                 cipher = IEEE80211_CIPHER_AES_CCM;
375         else {
376                 printf("%s: unknown/unsupported algorithm %s\n",
377                         __func__, alg);
378                 return -1;
379         }
380
381         if (key_len > sizeof(wk.ik_keydata)) {
382                 printf("%s: key length %d too big\n", __func__, key_len);
383                 return -3;
384         }
385
386         memset(&wk, 0, sizeof(wk));
387         wk.ik_type = cipher;
388         wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT;
389         if (addr == NULL) {
390                 memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
391                 wk.ik_keyix = key_idx;
392                 wk.ik_flags |= IEEE80211_KEY_DEFAULT | IEEE80211_KEY_GROUP;
393         } else {
394                 memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
395                 wk.ik_keyix = IEEE80211_KEYIX_NONE;
396         }
397         wk.ik_keylen = key_len;
398         memcpy(wk.ik_keydata, key, key_len);
399
400         return set80211var(priv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk));
401 }
402
403
404 static int
405 bsd_get_seqnum(void *priv, u8 *addr, int idx, u8 *seq)
406 {
407         struct bsd_driver_data *drv = priv;
408         hostapd *hapd = drv->hapd;
409         struct ieee80211req_key wk;
410
411         HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
412                 "%s: addr=%s idx=%d\n", __func__, ether_sprintf(addr), idx);
413
414         memset(&wk, 0, sizeof(wk));
415         if (addr == NULL)
416                 memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
417         else
418                 memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
419         wk.ik_keyix = idx;
420
421         if (get80211var(drv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk)) < 0) {
422                 printf("Failed to get encryption.\n");
423                 return -1;
424         } else {
425                 /* NB: upper layer expects tsc in network order */
426                 wk.ik_keytsc = htole64(wk.ik_keytsc);
427                 memcpy(seq, &wk.ik_keytsc, sizeof(wk.ik_keytsc));
428                 return 0;
429         }
430 }
431
432
433 static int 
434 bsd_flush(void *priv)
435 {
436         u8 allsta[IEEE80211_ADDR_LEN];
437
438         memset(allsta, 0xff, IEEE80211_ADDR_LEN);
439         return bsd_sta_deauth(priv, allsta, IEEE80211_REASON_AUTH_LEAVE);
440 }
441
442
443 static int
444 bsd_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data,
445                                         u8 *addr)
446 {
447         struct bsd_driver_data *drv = priv;
448         struct ieee80211req_sta_stats stats;
449
450         memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN);
451         if (get80211var(drv, IEEE80211_IOC_STA_STATS, &stats, sizeof(stats)) > 0) {
452                 /* XXX? do packets counts include non-data frames? */
453                 data->rx_packets = stats.is_stats.ns_rx_data;
454                 data->rx_bytes = stats.is_stats.ns_rx_bytes;
455                 data->tx_packets = stats.is_stats.ns_tx_data;
456                 data->tx_bytes = stats.is_stats.ns_tx_bytes;
457         }
458         return 0;
459 }
460
461 static int
462 bsd_sta_clear_stats(void *priv, u8 *addr)
463 {
464         struct bsd_driver_data *drv = priv;
465         hostapd *hapd = drv->hapd;
466         struct ieee80211req_sta_stats stats;
467         
468         HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "%s: addr=%s\n",
469                       __func__, ether_sprintf(addr));
470
471         /* zero station statistics */
472         memset(&stats, 0, sizeof(stats));
473         memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN);
474         return set80211var(drv, IEEE80211_IOC_STA_STATS, &stats, sizeof(stats));
475 }
476
477 static int
478 bsd_set_opt_ie(void *priv, const u8 *ie, size_t ie_len)
479 {
480         /*
481          * Do nothing; we setup parameters at startup that define the
482          * contents of the beacon information element.
483          */
484         return 0;
485 }
486
487 static int
488 bsd_sta_deauth(void *priv, u8 *addr, int reason_code)
489 {
490         struct bsd_driver_data *drv = priv;
491         hostapd *hapd = drv->hapd;
492         struct ieee80211req_mlme mlme;
493
494         HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
495                 "%s: addr=%s reason_code=%d\n",
496                 __func__, ether_sprintf(addr), reason_code);
497
498         mlme.im_op = IEEE80211_MLME_DEAUTH;
499         mlme.im_reason = reason_code;
500         memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
501         return set80211var(priv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme));
502 }
503
504 static int
505 bsd_sta_disassoc(void *priv, u8 *addr, int reason_code)
506 {
507         struct bsd_driver_data *drv = priv;
508         hostapd *hapd = drv->hapd;
509         struct ieee80211req_mlme mlme;
510
511         HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
512                 "%s: addr=%s reason_code=%d\n",
513                 __func__, ether_sprintf(addr), reason_code);
514
515         mlme.im_reason = reason_code;
516         memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
517         return set80211var(priv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme));
518 }
519
520 static int
521 bsd_del_sta(struct bsd_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN])
522 {
523         struct hostapd_data *hapd = drv->hapd;
524         struct hostapd_config *conf = hapd->conf;
525         struct sta_info *sta;
526
527         hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
528                 HOSTAPD_LEVEL_INFO, "deassociated");
529
530         sta = ap_get_sta(hapd, addr);
531         if (sta != NULL) {
532                 sta->flags &= ~WLAN_STA_ASSOC;
533                 if (conf->wpa)
534                         wpa_sm_event(hapd, sta, WPA_DISASSOC);
535                 sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
536                 ieee802_1x_set_port_enabled(hapd, sta, 0);
537                 ap_free_sta(hapd, sta);
538         }
539         return 0;
540 }
541
542 static int
543 bsd_new_sta(struct bsd_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN])
544 {
545         struct hostapd_data *hapd = drv->hapd;
546         struct hostapd_config *conf = hapd->conf;
547         struct sta_info *sta;
548         struct ieee80211req_wpaie ie;
549         int new_assoc, ielen, res;
550
551         hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
552                 HOSTAPD_LEVEL_INFO, "associated");
553
554         sta = ap_sta_add(hapd, addr);
555         if (sta == NULL)
556                 return -1;
557         /*
558          * Fetch and validate any negotiated WPA/RSN parameters.
559          */
560         if (conf->wpa) {
561                 memset(&ie, 0, sizeof(ie));
562                 memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN);
563                 if (get80211var(drv, IEEE80211_IOC_WPAIE, &ie, sizeof(ie)) < 0) {
564                         printf("Failed to get WPA/RSN information element.\n");
565                         return -1;              /* XXX not right */
566                 }
567                 ielen = ie.wpa_ie[1];
568                 if (ielen == 0) {
569                         printf("No WPA/RSN information element for station!\n");
570                         return -1;              /* XXX not right */
571                 }
572                 ielen += 2;
573                 res = wpa_validate_wpa_ie(hapd, sta, ie.wpa_ie, ielen,
574                                 ie.wpa_ie[0] == WLAN_EID_RSN ?
575                                     HOSTAPD_WPA_VERSION_WPA2 :
576                                     HOSTAPD_WPA_VERSION_WPA);
577                 if (res != WPA_IE_OK) {
578                         printf("WPA/RSN information element rejected? "
579                                 "(res %u)\n", res);
580                         return -1;
581                 }
582                 if (sta->wpa_ie != NULL)
583                         free(sta->wpa_ie);
584                 sta->wpa_ie = malloc(ielen);
585                 if (sta->wpa_ie == NULL) {
586                         printf("No memory for WPA/RSN information element!\n");
587                         return -1;
588                 }
589                 memcpy(sta->wpa_ie, ie.wpa_ie, ielen);
590                 sta->wpa_ie_len = ielen;
591         } else {
592                 if (sta->wpa_ie != NULL)
593                         free(sta->wpa_ie);
594                 sta->wpa_ie = NULL;
595                 sta->wpa_ie_len = 0;
596         }
597
598         /*
599          * Now that the internal station state is setup
600          * kick the authenticator into action.
601          */
602         new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;
603         sta->flags |= WLAN_STA_ASSOC;
604         if (new_assoc) {
605                 if (conf->wpa)
606                         wpa_sm_event(hapd, sta, WPA_ASSOC);
607                 hostapd_new_assoc_sta(hapd, sta, !new_assoc);
608         } else {
609                 if (conf->wpa)
610                         wpa_sm_event(hapd, sta, WPA_REAUTH);
611         }
612         ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
613         return 0;
614 }
615
616 #include <net/route.h>
617 #include <netproto/802_11/ieee80211_dragonfly.h>
618
619 static void
620 bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx)
621 {
622         struct bsd_driver_data *drv = ctx;
623         struct hostapd_data *hapd = drv->hapd;
624         char buf[2048];
625         struct if_announcemsghdr *ifan;
626         struct rt_msghdr *rtm;
627         struct ieee80211_michael_event *mic;
628         struct ieee80211_join_event *join;
629         struct ieee80211_leave_event *leave;
630         int n;
631
632         n = read(sock, buf, sizeof(buf));
633         if (n < 0) {
634                 if (errno != EINTR && errno != EAGAIN)
635                         perror("read(PF_ROUTE)");
636                 return;
637         }
638
639         rtm = (struct rt_msghdr *) buf;
640         if (rtm->rtm_version != RTM_VERSION) {
641                 wpa_printf(MSG_DEBUG, "Routing message version %d not "
642                         "understood\n", rtm->rtm_version);
643                 return;
644         }
645         ifan = (struct if_announcemsghdr *) rtm;
646         switch (rtm->rtm_type) {
647         case RTM_IEEE80211:
648                 switch (ifan->ifan_what) {
649                 case RTM_IEEE80211_ASSOC:
650                 case RTM_IEEE80211_REASSOC:
651                 case RTM_IEEE80211_DISASSOC:
652                 case RTM_IEEE80211_SCAN:
653                         break;
654                 case RTM_IEEE80211_LEAVE:
655                         leave = (struct ieee80211_leave_event *) &ifan[1];
656                         bsd_del_sta(drv, leave->iev_addr);
657                         break;
658                 case RTM_IEEE80211_JOIN:
659 #ifdef RTM_IEEE80211_REJOIN
660                 case RTM_IEEE80211_REJOIN:
661 #endif
662                         join = (struct ieee80211_join_event *) &ifan[1];
663                         bsd_new_sta(drv, join->iev_addr);
664                         break;
665                 case RTM_IEEE80211_REPLAY:
666                         /* ignore */
667                         break;
668                 case RTM_IEEE80211_MICHAEL:
669                         mic = (struct ieee80211_michael_event *) &ifan[1];
670                         wpa_printf(MSG_DEBUG,
671                                 "Michael MIC failure wireless event: "
672                                 "keyix=%u src_addr=" MACSTR, mic->iev_keyix,
673                                 MAC2STR(mic->iev_src));
674                         ieee80211_michael_mic_failure(hapd, mic->iev_src, 1);
675                         break;
676                 }
677                 break;
678         }
679 }
680
681 static int
682 bsd_wireless_event_init(void *priv)
683 {
684         struct bsd_driver_data *drv = priv;
685         int s;
686
687         drv->wext_sock = -1;
688
689         s = socket(PF_ROUTE, SOCK_RAW, 0);
690         if (s < 0) {
691                 perror("socket(PF_ROUTE,SOCK_RAW)");
692                 return -1;
693         }
694         eloop_register_read_sock(s, bsd_wireless_event_receive, drv, NULL);
695         drv->wext_sock = s;
696
697         return 0;
698 }
699
700 static void
701 bsd_wireless_event_deinit(void *priv)
702 {
703         struct bsd_driver_data *drv = priv;
704
705         if (drv != NULL) {
706                 if (drv->wext_sock < 0)
707                         return;
708                 eloop_unregister_read_sock(drv->wext_sock);
709                 close(drv->wext_sock);
710         }
711 }
712
713
714 static int
715 bsd_send_eapol(void *priv, u8 *addr, u8 *data, size_t data_len, int encrypt)
716 {
717         struct bsd_driver_data *drv = priv;
718         hostapd *hapd = drv->hapd;
719         unsigned char buf[3000];
720         unsigned char *bp = buf;
721         struct l2_ethhdr *eth;
722         size_t len;
723         int status;
724
725         /*
726          * Prepend the Etherent header.  If the caller left us
727          * space at the front we could just insert it but since
728          * we don't know we copy to a local buffer.  Given the frequency
729          * and size of frames this probably doesn't matter.
730          */
731         len = data_len + sizeof(struct l2_ethhdr);
732         if (len > sizeof(buf)) {
733                 bp = malloc(len);
734                 if (bp == NULL) {
735                         printf("EAPOL frame discarded, cannot malloc temp "
736                                 "buffer of size %u!\n", len);
737                         return -1;
738                 }
739         }
740         eth = (struct l2_ethhdr *) bp;
741         memcpy(eth->h_dest, addr, ETH_ALEN);
742         memcpy(eth->h_source, drv->hapd->own_addr, ETH_ALEN);
743         eth->h_proto = htons(ETH_P_EAPOL);
744         memcpy(eth+1, data, data_len);
745
746         if (HOSTAPD_DEBUG_COND(HOSTAPD_DEBUG_MSGDUMPS))
747                 hostapd_hexdump("TX EAPOL", bp, len);
748
749         status = l2_packet_send(drv->sock_xmit, addr, ETH_P_EAPOL, bp, len);
750
751         if (bp != buf)
752                 free(bp);
753         return status;
754 }
755
756 static void
757 handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)
758 {
759         struct bsd_driver_data *drv = ctx;
760         hostapd *hapd = drv->hapd;
761         struct sta_info *sta;
762
763         sta = ap_get_sta(hapd, src_addr);
764         if (!sta || !(sta->flags & WLAN_STA_ASSOC)) {
765                 printf("Data frame from not associated STA %s\n",
766                        ether_sprintf(src_addr));
767                 /* XXX cannot happen */
768                 return;
769         }
770         ieee802_1x_receive(hapd, src_addr, buf + sizeof(struct l2_ethhdr),
771                            len - sizeof(struct l2_ethhdr));
772 }
773
774 static int
775 bsd_get_ssid(void *priv, u8 *buf, int len)
776 {
777         struct bsd_driver_data *drv = priv;
778         hostapd *hapd = drv->hapd;
779         int ssid_len = get80211var(priv, IEEE80211_IOC_SSID, buf, len);
780
781         HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "%s: ssid=\"%.*s\"\n",
782                 __func__, ssid_len, buf);
783
784         return ssid_len;
785 }
786
787 static int
788 bsd_set_ssid(void *priv, u8 *buf, int len)
789 {
790         struct bsd_driver_data *drv = priv;
791         hostapd *hapd = drv->hapd;
792
793         HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "%s: ssid=\"%.*s\"\n",
794                 __func__, len, buf);
795
796         return set80211var(priv, IEEE80211_IOC_SSID, buf, len);
797 }
798
799 static int
800 bsd_set_countermeasures(void *priv, int enabled)
801 {
802         struct bsd_driver_data *drv = priv;
803
804         wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
805         return set80211param(drv, IEEE80211_IOC_COUNTERMEASURES, enabled);
806 }
807
808 static int
809 bsd_init(struct hostapd_data *hapd)
810 {
811         struct bsd_driver_data *drv;
812
813         drv = malloc(sizeof(struct bsd_driver_data));
814         if (drv == NULL) {
815                 printf("Could not allocate memory for bsd driver data\n");
816                 goto bad;
817         }
818
819         memset(drv, 0, sizeof(*drv));
820         drv->ops = bsd_driver_ops;
821         drv->hapd = hapd;
822         drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
823         if (drv->ioctl_sock < 0) {
824                 perror("socket[PF_INET,SOCK_DGRAM]");
825                 goto bad;
826         }
827         memcpy(drv->iface, hapd->conf->iface, sizeof(drv->iface));
828
829         drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL,
830                                         handle_read, drv, 1);
831         if (drv->sock_xmit == NULL)
832                 goto bad;
833         if (l2_packet_get_own_addr(drv->sock_xmit, hapd->own_addr))
834                 goto bad;
835
836         bsd_set_iface_flags(drv, 0);    /* mark down during setup */
837
838         hapd->driver = &drv->ops;
839         return 0;
840 bad:
841         if (drv->sock_xmit != NULL)
842                 l2_packet_deinit(drv->sock_xmit);
843         if (drv->ioctl_sock >= 0)
844                 close(drv->ioctl_sock);
845         if (drv != NULL)
846                 free(drv);
847         return -1;
848 }
849
850
851 static void
852 bsd_deinit(void *priv)
853 {
854         struct bsd_driver_data *drv = priv;
855
856         drv->hapd->driver = NULL;
857
858         (void) bsd_set_iface_flags(drv, 0);
859         if (drv->ioctl_sock >= 0)
860                 close(drv->ioctl_sock);
861         if (drv->sock_xmit != NULL)
862                 l2_packet_deinit(drv->sock_xmit);
863         free(drv);
864 }
865
866 static const struct driver_ops bsd_driver_ops = {
867         .name                   = "bsd",
868         .init                   = bsd_init,
869         .deinit                 = bsd_deinit,
870         .set_ieee8021x          = bsd_set_ieee8021x,
871         .set_privacy            = bsd_set_privacy,
872         .set_encryption         = bsd_set_key,
873         .get_seqnum             = bsd_get_seqnum,
874         .flush                  = bsd_flush,
875         .set_generic_elem       = bsd_set_opt_ie,
876         .wireless_event_init    = bsd_wireless_event_init,
877         .wireless_event_deinit  = bsd_wireless_event_deinit,
878         .set_sta_authorized     = bsd_set_sta_authorized,
879         .read_sta_data          = bsd_read_sta_driver_data,
880         .send_eapol             = bsd_send_eapol,
881         .sta_disassoc           = bsd_sta_disassoc,
882         .sta_deauth             = bsd_sta_deauth,
883         .set_ssid               = bsd_set_ssid,
884         .get_ssid               = bsd_get_ssid,
885         .set_countermeasures    = bsd_set_countermeasures,
886         .sta_clear_stats        = bsd_sta_clear_stats,
887 };
888
889 void bsd_driver_register(void)
890 {
891         driver_register(bsd_driver_ops.name, &bsd_driver_ops);
892 }