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