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