2 * Host AP - driver interaction with BSD net80211 layer
3 * Copyright (c) 2004, Sam Leffler <sam@errno.com>
4 * Copyright (c) 2004, 2Wire, Inc
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.
10 * Alternatively, this software may be distributed under the terms of BSD
13 * See README and COPYING for more details.
21 #include <sys/ioctl.h>
24 #include <sys/socket.h>
26 #include <netinet/in.h>
28 #include <net80211/ieee80211_ioctl.h>
37 #include "ieee802_1x.h"
38 #include "ieee802_11_auth.h"
41 #include "l2_packet/l2_packet.h"
45 #include "radius/radius.h"
46 #include "ieee802_11.h"
48 #include "hostap_common.h"
50 struct bsd_driver_data {
51 struct hostapd_data *hapd; /* back pointer */
53 char iface[IFNAMSIZ + 1];
54 unsigned int ifindex; /* interface index */
55 struct l2_packet_data *sock_xmit; /* raw packet xmit socket */
56 int ioctl_sock; /* socket for ioctl() use */
57 int wext_sock; /* socket for wireless events */
60 static const struct wpa_driver_ops bsd_driver_ops;
62 static int bsd_sta_deauth(void *priv, const u8 *addr, int reason_code);
65 set80211var(struct bsd_driver_data *drv, int op, const void *arg, int arg_len)
67 struct ieee80211req ireq;
69 memset(&ireq, 0, sizeof(ireq));
70 strncpy(ireq.i_name, drv->iface, IFNAMSIZ);
73 ireq.i_data = (void *) arg;
75 if (ioctl(drv->ioctl_sock, SIOCS80211, &ireq) < 0) {
76 perror("ioctl[SIOCS80211]");
83 get80211var(struct bsd_driver_data *drv, int op, void *arg, int arg_len)
85 struct ieee80211req ireq;
87 memset(&ireq, 0, sizeof(ireq));
88 strncpy(ireq.i_name, drv->iface, IFNAMSIZ);
93 if (ioctl(drv->ioctl_sock, SIOCG80211, &ireq) < 0) {
94 perror("ioctl[SIOCG80211]");
101 set80211param(struct bsd_driver_data *drv, int op, int arg)
103 struct ieee80211req ireq;
105 memset(&ireq, 0, sizeof(ireq));
106 strncpy(ireq.i_name, drv->iface, IFNAMSIZ);
110 if (ioctl(drv->ioctl_sock, SIOCS80211, &ireq) < 0) {
111 perror("ioctl[SIOCS80211]");
118 ether_sprintf(const u8 *addr)
120 static char buf[sizeof(MACSTR)];
123 snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
125 snprintf(buf, sizeof(buf), MACSTR, 0,0,0,0,0,0);
130 bsd_set_iface_flags(void *priv, int flags)
132 struct bsd_driver_data *drv = priv;
133 struct hostapd_data *hapd = drv->hapd;
136 wpa_printf(MSG_DEBUG, "%s: flags=0x%x\n", __func__, flags);
138 if (drv->ioctl_sock < 0)
141 memset(&ifr, 0, sizeof(ifr));
142 snprintf(ifr.ifr_name, IFNAMSIZ, "%s", drv->iface);
144 if (ioctl(drv->ioctl_sock, SIOCGIFFLAGS, &ifr) != 0) {
145 perror("ioctl[SIOCGIFFLAGS]");
151 if ((ifr.ifr_flags & flags) == 0)
153 ifr.ifr_flags &= ~flags;
155 if ((ifr.ifr_flags & flags) == flags)
157 ifr.ifr_flags |= flags;
160 if (ioctl(drv->ioctl_sock, SIOCSIFFLAGS, &ifr) != 0) {
161 perror("ioctl[SIOCSIFFLAGS]");
168 bsd_commit(void *priv)
170 return bsd_set_iface_flags(priv, IFF_UP);
174 bsd_set_ieee8021x(const char *ifname, void *priv, int enabled)
176 struct bsd_driver_data *drv = priv;
177 struct hostapd_data *hapd = drv->hapd;
178 struct hostapd_bss_config *conf = hapd->conf;
180 wpa_printf(MSG_DEBUG, "%s: enabled=%d\n", __func__, enabled);
183 /* XXX restore state */
184 return set80211param(priv, IEEE80211_IOC_AUTHMODE,
185 IEEE80211_AUTH_AUTO);
187 if (!conf->wpa && !conf->ieee802_1x) {
188 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER,
189 HOSTAPD_LEVEL_WARNING, "No 802.1X or WPA enabled!");
192 if (conf->wpa && set80211param(drv, IEEE80211_IOC_WPA, conf->wpa)) {
193 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER,
194 HOSTAPD_LEVEL_WARNING, "Error configuring WPA state!");
197 if (set80211param(priv, IEEE80211_IOC_AUTHMODE,
198 (conf->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) {
199 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_DRIVER,
200 HOSTAPD_LEVEL_WARNING, "Error enabling WPA/802.1X!");
207 bsd_set_privacy(const char *ifname, void *priv, int enabled)
209 struct bsd_driver_data *drv = priv;
210 struct hostapd_data *hapd = drv->hapd;
212 wpa_printf(MSG_DEBUG, "%s: enabled=%d\n", __func__, enabled);
214 return set80211param(priv, IEEE80211_IOC_PRIVACY, enabled);
218 bsd_set_sta_authorized(void *priv, const u8 *addr, int authorized)
220 struct bsd_driver_data *drv = priv;
221 struct hostapd_data *hapd = drv->hapd;
222 struct ieee80211req_mlme mlme;
224 wpa_printf(MSG_DEBUG, "%s: addr=%s authorized=%d\n",
225 __func__, ether_sprintf(addr), authorized);
228 mlme.im_op = IEEE80211_MLME_AUTHORIZE;
230 mlme.im_op = IEEE80211_MLME_UNAUTHORIZE;
232 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
233 return set80211var(priv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme));
237 bsd_sta_set_flags(void *priv, const u8 *addr, int total_flags,
238 int flags_or, int flags_and)
240 /* For now, only support setting Authorized flag */
241 if (flags_or & WLAN_STA_AUTHORIZED)
242 return bsd_set_sta_authorized(priv, addr, 1);
243 if (!(flags_and & WLAN_STA_AUTHORIZED))
244 return bsd_set_sta_authorized(priv, addr, 0);
249 bsd_del_key(void *priv, const unsigned char *addr, int key_idx)
251 struct bsd_driver_data *drv = priv;
252 struct hostapd_data *hapd = drv->hapd;
253 struct ieee80211req_del_key wk;
255 wpa_printf(MSG_DEBUG, "%s: addr=%s key_idx=%d\n",
256 __func__, ether_sprintf(addr), key_idx);
258 memset(&wk, 0, sizeof(wk));
260 memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN);
261 wk.idk_keyix = (u_int8_t) IEEE80211_KEYIX_NONE; /* XXX */
263 wk.idk_keyix = key_idx;
266 return set80211var(priv, IEEE80211_IOC_DELKEY, &wk, sizeof(wk));
270 bsd_set_key(const char *ifname, void *priv, const char *alg,
271 const u8 *addr, int key_idx,
272 const u8 *key, size_t key_len, int txkey)
274 struct bsd_driver_data *drv = priv;
275 struct hostapd_data *hapd = drv->hapd;
276 struct ieee80211req_key wk;
279 if (strcmp(alg, "none") == 0)
280 return bsd_del_key(priv, addr, key_idx);
282 wpa_printf(MSG_DEBUG, "%s: alg=%s addr=%s key_idx=%d\n",
283 __func__, alg, ether_sprintf(addr), key_idx);
285 if (strcmp(alg, "WEP") == 0)
286 cipher = IEEE80211_CIPHER_WEP;
287 else if (strcmp(alg, "TKIP") == 0)
288 cipher = IEEE80211_CIPHER_TKIP;
289 else if (strcmp(alg, "CCMP") == 0)
290 cipher = IEEE80211_CIPHER_AES_CCM;
292 printf("%s: unknown/unsupported algorithm %s\n",
297 if (key_len > sizeof(wk.ik_keydata)) {
298 printf("%s: key length %d too big\n", __func__, key_len);
302 memset(&wk, 0, sizeof(wk));
305 memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
306 wk.ik_keyix = key_idx;
307 wk.ik_flags = IEEE80211_KEY_XMIT
308 | IEEE80211_KEY_GROUP
309 | IEEE80211_KEY_DEFAULT;
311 memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
312 wk.ik_keyix = IEEE80211_KEYIX_NONE;
313 wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT;
315 wk.ik_keylen = key_len;
316 memcpy(wk.ik_keydata, key, key_len);
318 return set80211var(priv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk));
323 bsd_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx,
326 struct bsd_driver_data *drv = priv;
327 struct hostapd_data *hapd = drv->hapd;
328 struct ieee80211req_key wk;
330 wpa_printf(MSG_DEBUG, "%s: addr=%s idx=%d\n",
331 __func__, ether_sprintf(addr), idx);
333 memset(&wk, 0, sizeof(wk));
335 memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
337 memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
340 if (get80211var(drv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk)) < 0) {
341 printf("Failed to get encryption.\n");
344 /* NB: upper layer expects tsc in network order */
345 wk.ik_keytsc = htole64(wk.ik_keytsc);
346 memcpy(seq, &wk.ik_keytsc, sizeof(wk.ik_keytsc));
353 bsd_flush(void *priv)
355 u8 allsta[IEEE80211_ADDR_LEN];
357 memset(allsta, 0xff, IEEE80211_ADDR_LEN);
358 return bsd_sta_deauth(priv, allsta, IEEE80211_REASON_AUTH_LEAVE);
363 bsd_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data,
366 struct bsd_driver_data *drv = priv;
367 struct ieee80211req_sta_stats stats;
369 memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN);
370 if (get80211var(drv, IEEE80211_IOC_STA_STATS, &stats, sizeof(stats)) > 0) {
371 /* XXX? do packets counts include non-data frames? */
372 data->rx_packets = stats.is_stats.ns_rx_data;
373 data->rx_bytes = stats.is_stats.ns_rx_bytes;
374 data->tx_packets = stats.is_stats.ns_tx_data;
375 data->tx_bytes = stats.is_stats.ns_tx_bytes;
381 bsd_sta_clear_stats(void *priv, const u8 *addr)
383 struct bsd_driver_data *drv = priv;
384 struct hostapd_data *hapd = drv->hapd;
385 struct ieee80211req_sta_stats stats;
387 wpa_printf(MSG_DEBUG, "%s: addr=%s\n", __func__, ether_sprintf(addr));
389 /* zero station statistics */
390 memset(&stats, 0, sizeof(stats));
391 memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN);
392 return set80211var(drv, IEEE80211_IOC_STA_STATS, &stats, sizeof(stats));
396 bsd_set_opt_ie(const char *ifname, void *priv, const u8 *ie, size_t ie_len)
398 struct bsd_driver_data *drv = priv;
399 struct hostapd_data *hapd = drv->hapd;
400 struct ieee80211req ireq;
402 memset(&ireq, 0, sizeof(ireq));
403 strncpy(ireq.i_name, drv->iface, IFNAMSIZ);
404 ireq.i_type = IEEE80211_IOC_APPIE;
405 ireq.i_val = IEEE80211_APPIE_WPA;
406 ireq.i_data = (void *) ie;
409 wpa_printf(MSG_DEBUG, "%s: set WPA+RSN ie (len %d)\n",
411 if (ioctl(drv->ioctl_sock, SIOCS80211, &ireq) < 0) {
412 printf("Unable to set WPA+RSN ie\n");
419 bsd_sta_deauth(void *priv, const u8 *addr, int reason_code)
421 struct bsd_driver_data *drv = priv;
422 struct hostapd_data *hapd = drv->hapd;
423 struct ieee80211req_mlme mlme;
425 wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d\n",
426 __func__, ether_sprintf(addr), reason_code);
428 mlme.im_op = IEEE80211_MLME_DEAUTH;
429 mlme.im_reason = reason_code;
430 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
431 return set80211var(priv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme));
435 bsd_sta_disassoc(void *priv, const u8 *addr, int reason_code)
437 struct bsd_driver_data *drv = priv;
438 struct hostapd_data *hapd = drv->hapd;
439 struct ieee80211req_mlme mlme;
441 wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d\n",
442 __func__, ether_sprintf(addr), reason_code);
444 mlme.im_reason = reason_code;
445 memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
446 return set80211var(priv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme));
450 bsd_del_sta(struct bsd_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN])
452 struct hostapd_data *hapd = drv->hapd;
453 struct hostapd_bss_config *conf = hapd->conf;
454 struct sta_info *sta;
456 hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
457 HOSTAPD_LEVEL_INFO, "deassociated");
459 sta = ap_get_sta(hapd, addr);
461 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
463 wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
464 sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
465 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
466 ap_free_sta(hapd, sta);
472 bsd_new_sta(struct bsd_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN])
474 struct hostapd_data *hapd = drv->hapd;
475 struct hostapd_bss_config *conf = hapd->conf;
476 struct sta_info *sta;
477 struct ieee80211req_wpaie ie;
478 int new_assoc, ielen, res;
480 hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
481 HOSTAPD_LEVEL_INFO, "associated");
483 sta = ap_sta_add(hapd, addr);
487 * Fetch and validate any negotiated WPA/RSN parameters.
490 memset(&ie, 0, sizeof(ie));
491 memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN);
492 if (get80211var(drv, IEEE80211_IOC_WPAIE, &ie, sizeof(ie)) < 0) {
493 printf("Failed to get WPA/RSN information element.\n");
494 return -1; /* XXX not right */
496 if (ie.wpa_ie[1] == 0) {
497 printf("No WPA/RSN information element for station!\n");
498 return -1; /* XXX not right */
500 if (sta->wpa_sm == NULL)
501 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
503 if (sta->wpa_sm == NULL) {
504 printf("Failed to initialize WPA state machine\n");
507 ielen = 2 + ie.wpa_ie[1];
508 res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
509 ie.wpa_ie, ielen, NULL, 0);
510 if (res != WPA_IE_OK) {
511 printf("WPA/RSN information element rejected? "
518 * Now that the internal station state is setup
519 * kick the authenticator into action.
521 new_assoc = (sta->flags & WLAN_STA_ASSOC) == 0;
522 sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC;
523 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
524 hostapd_new_assoc_sta(hapd, sta, !new_assoc);
525 ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
530 #include <net/route.h>
531 #include <net80211/ieee80211_freebsd.h>
534 bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx)
536 struct bsd_driver_data *drv = ctx;
537 struct hostapd_data *hapd = drv->hapd;
539 struct if_announcemsghdr *ifan;
540 struct rt_msghdr *rtm;
541 struct ieee80211_michael_event *mic;
542 struct ieee80211_join_event *join;
543 struct ieee80211_leave_event *leave;
544 #ifdef CONFIG_DRIVER_RADIUS_ACL
545 struct ieee80211_auth_event *auth;
549 n = read(sock, buf, sizeof(buf));
551 if (errno != EINTR && errno != EAGAIN)
552 perror("read(PF_ROUTE)");
556 rtm = (struct rt_msghdr *) buf;
557 if (rtm->rtm_version != RTM_VERSION) {
558 wpa_printf(MSG_DEBUG, "Routing message version %d not "
559 "understood\n", rtm->rtm_version);
562 ifan = (struct if_announcemsghdr *) rtm;
563 if (ifan->ifan_index != drv->ifindex) {
564 wpa_printf(MSG_DEBUG, "Discard routing message to if#%d "
566 ifan->ifan_index, drv->ifindex);
569 switch (rtm->rtm_type) {
571 switch (ifan->ifan_what) {
572 case RTM_IEEE80211_ASSOC:
573 case RTM_IEEE80211_REASSOC:
574 case RTM_IEEE80211_DISASSOC:
575 case RTM_IEEE80211_SCAN:
577 case RTM_IEEE80211_LEAVE:
578 leave = (struct ieee80211_leave_event *) &ifan[1];
579 bsd_del_sta(drv, leave->iev_addr);
581 case RTM_IEEE80211_JOIN:
582 #ifdef RTM_IEEE80211_REJOIN
583 case RTM_IEEE80211_REJOIN:
585 join = (struct ieee80211_join_event *) &ifan[1];
586 bsd_new_sta(drv, join->iev_addr);
588 case RTM_IEEE80211_REPLAY:
591 case RTM_IEEE80211_MICHAEL:
592 mic = (struct ieee80211_michael_event *) &ifan[1];
593 wpa_printf(MSG_DEBUG,
594 "Michael MIC failure wireless event: "
595 "keyix=%u src_addr=" MACSTR, mic->iev_keyix,
596 MAC2STR(mic->iev_src));
597 ieee80211_michael_mic_failure(hapd, mic->iev_src, 1);
599 #ifdef CONFIG_DRIVER_RADIUS_ACL
600 case RTM_IEEE80211_AUTH:
601 auth = (struct ieee80211_auth_event *) &ifan[1];
602 wpa_printf(MSG_DEBUG, "802.11 AUTH, STA = " MACSTR,
603 MAC2STR(auth->iev_addr));
604 n = hostapd_allowed_address(hapd, auth->iev_addr,
605 NULL, 0, NULL, NULL, NULL);
607 case HOSTAPD_ACL_ACCEPT:
608 case HOSTAPD_ACL_REJECT:
609 hostapd_set_radius_acl_auth(hapd,
610 auth->iev_addr, n, 0);
611 wpa_printf(MSG_DEBUG,
612 "802.11 AUTH, STA = " MACSTR " hostapd says: %s",
613 MAC2STR(auth->iev_addr),
614 (n == HOSTAPD_ACL_ACCEPT ?
615 "ACCEPT" : "REJECT" ));
617 case HOSTAPD_ACL_PENDING:
618 wpa_printf(MSG_DEBUG,
619 "802.11 AUTH, STA = " MACSTR " pending",
620 MAC2STR(auth->iev_addr));
624 #endif /* CONFIG_DRIVER_RADIUS_ACL */
631 bsd_wireless_event_init(void *priv)
633 struct bsd_driver_data *drv = priv;
638 s = socket(PF_ROUTE, SOCK_RAW, 0);
640 perror("socket(PF_ROUTE,SOCK_RAW)");
643 eloop_register_read_sock(s, bsd_wireless_event_receive, drv, NULL);
650 bsd_wireless_event_deinit(void *priv)
652 struct bsd_driver_data *drv = priv;
655 if (drv->wext_sock < 0)
657 eloop_unregister_read_sock(drv->wext_sock);
658 close(drv->wext_sock);
664 bsd_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len,
665 int encrypt, const u8 *own_addr)
667 struct bsd_driver_data *drv = priv;
668 struct hostapd_data *hapd = drv->hapd;
669 unsigned char buf[3000];
670 unsigned char *bp = buf;
671 struct l2_ethhdr *eth;
676 * Prepend the Etherent header. If the caller left us
677 * space at the front we could just insert it but since
678 * we don't know we copy to a local buffer. Given the frequency
679 * and size of frames this probably doesn't matter.
681 len = data_len + sizeof(struct l2_ethhdr);
682 if (len > sizeof(buf)) {
685 printf("EAPOL frame discarded, cannot malloc temp "
686 "buffer of size %u!\n", len);
690 eth = (struct l2_ethhdr *) bp;
691 memcpy(eth->h_dest, addr, ETH_ALEN);
692 memcpy(eth->h_source, own_addr, ETH_ALEN);
693 eth->h_proto = htons(ETH_P_EAPOL);
694 memcpy(eth+1, data, data_len);
696 wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", bp, len);
698 status = l2_packet_send(drv->sock_xmit, addr, ETH_P_EAPOL, bp, len);
706 handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)
708 struct bsd_driver_data *drv = ctx;
709 struct hostapd_data *hapd = drv->hapd;
710 struct sta_info *sta;
712 sta = ap_get_sta(hapd, src_addr);
713 if (!sta || !(sta->flags & WLAN_STA_ASSOC)) {
714 printf("Data frame from not associated STA %s\n",
715 ether_sprintf(src_addr));
716 /* XXX cannot happen */
719 ieee802_1x_receive(hapd, src_addr, buf + sizeof(struct l2_ethhdr),
720 len - sizeof(struct l2_ethhdr));
724 bsd_get_ssid(const char *ifname, void *priv, u8 *buf, int len)
726 struct bsd_driver_data *drv = priv;
727 struct hostapd_data *hapd = drv->hapd;
728 int ssid_len = get80211var(priv, IEEE80211_IOC_SSID, buf, len);
730 wpa_printf(MSG_DEBUG, "%s: ssid=\"%.*s\"\n", __func__, ssid_len, buf);
736 bsd_set_ssid(const char *ifname, void *priv, const u8 *buf, int len)
738 struct bsd_driver_data *drv = priv;
739 struct hostapd_data *hapd = drv->hapd;
741 wpa_printf(MSG_DEBUG, "%s: ssid=\"%.*s\"\n", __func__, len, buf);
743 return set80211var(priv, IEEE80211_IOC_SSID, buf, len);
747 bsd_set_countermeasures(void *priv, int enabled)
749 struct bsd_driver_data *drv = priv;
751 wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
752 return set80211param(drv, IEEE80211_IOC_COUNTERMEASURES, enabled);
755 #ifdef CONFIG_DRIVER_RADIUS_ACL
757 bsd_set_radius_acl_auth(void *priv, const u8 *mac, int accepted,
760 struct bsd_driver_data *drv = priv;
761 struct hostapd_data *hapd = drv->hapd;
762 struct ieee80211req_mlme mlme;
765 case HOSTAPD_ACL_ACCEPT_TIMEOUT:
766 wpa_printf(MSG_DEBUG, "[%s] STA " MACSTR
767 " has been accepted by RADIUS ACL with timeout "
768 "of %d.\n", hapd->conf->iface, MAC2STR(mac),
770 mlme.im_reason = IEEE80211_STATUS_SUCCESS;
772 case HOSTAPD_ACL_ACCEPT:
773 wpa_printf(MSG_DEBUG, "[%s] STA " MACSTR
774 " has been accepted by RADIUS ACL.\n",
775 hapd->conf->iface, MAC2STR(mac));
776 mlme.im_reason = IEEE80211_STATUS_SUCCESS;
778 case HOSTAPD_ACL_REJECT:
779 wpa_printf(MSG_DEBUG, "[%s] STA " MACSTR
780 " has been rejected by RADIUS ACL.\n",
781 hapd->conf->iface, MAC2STR(mac));
782 mlme.im_reason = IEEE80211_STATUS_UNSPECIFIED;
785 wpa_printf(MSG_ERROR, "[%s] STA " MACSTR
786 " has unknown status (%d) by RADIUS ACL. "
787 "Nothing to do...\n", hapd->conf->iface,
788 MAC2STR(mac), accepted);
791 memset(&mlme, 0, sizeof(mlme));
792 mlme.im_op = IEEE80211_MLME_AUTH;
793 memcpy(mlme.im_macaddr, mac, IEEE80211_ADDR_LEN);
794 return set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme));
798 bsd_set_radius_acl_expire(void *priv, const u8 *mac)
800 struct bsd_driver_data *drv = priv;
801 struct hostapd_data *hapd = drv->hapd;
804 * The expiry of the MAC address from RADIUS ACL cache doesn't mean
805 * that we should kick off the client. Our current approach doesn't
806 * require adding/removing entries from an allow/deny list; so this
807 * function is likely unecessary
809 wpa_printf(MSG_DEBUG, "[%s] STA " MACSTR " radius acl cache "
810 "expired; nothing to do...", hapd->conf->iface,
814 #endif /* CONFIG_DRIVER_RADIUS_ACL */
817 bsd_init(struct hostapd_data *hapd)
819 struct bsd_driver_data *drv;
821 drv = malloc(sizeof(struct bsd_driver_data));
823 printf("Could not allocate memory for bsd driver data\n");
827 memset(drv, 0, sizeof(*drv));
829 drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
830 if (drv->ioctl_sock < 0) {
831 perror("socket[PF_INET,SOCK_DGRAM]");
834 memcpy(drv->iface, hapd->conf->iface, sizeof(drv->iface));
836 * NB: We require the interface name be mappable to an index.
837 * This implies we do not support having wpa_supplicant
838 * wait for an interface to appear. This seems ok; that
839 * doesn't belong here; it's really the job of devd.
840 * XXXSCW: devd is FreeBSD-specific.
842 drv->ifindex = if_nametoindex(drv->iface);
843 if (drv->ifindex == 0) {
844 printf("%s: interface %s does not exist", __func__, drv->iface);
848 drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL,
849 handle_read, drv, 1);
850 if (drv->sock_xmit == NULL)
852 if (l2_packet_get_own_addr(drv->sock_xmit, hapd->own_addr))
855 bsd_set_iface_flags(drv, -IFF_UP); /* mark down during setup */
860 if (drv->sock_xmit != NULL)
861 l2_packet_deinit(drv->sock_xmit);
862 if (drv->ioctl_sock >= 0)
863 close(drv->ioctl_sock);
871 bsd_deinit(void *priv)
873 struct bsd_driver_data *drv = priv;
875 (void) bsd_set_iface_flags(drv, -IFF_UP);
876 if (drv->ioctl_sock >= 0)
877 close(drv->ioctl_sock);
878 if (drv->sock_xmit != NULL)
879 l2_packet_deinit(drv->sock_xmit);
883 const struct wpa_driver_ops wpa_driver_bsd_ops = {
886 .deinit = bsd_deinit,
887 .set_ieee8021x = bsd_set_ieee8021x,
888 .set_privacy = bsd_set_privacy,
889 .set_encryption = bsd_set_key,
890 .get_seqnum = bsd_get_seqnum,
892 .set_generic_elem = bsd_set_opt_ie,
893 .wireless_event_init = bsd_wireless_event_init,
894 .wireless_event_deinit = bsd_wireless_event_deinit,
895 .sta_set_flags = bsd_sta_set_flags,
896 .read_sta_data = bsd_read_sta_driver_data,
897 .send_eapol = bsd_send_eapol,
898 .sta_disassoc = bsd_sta_disassoc,
899 .sta_deauth = bsd_sta_deauth,
900 .set_ssid = bsd_set_ssid,
901 .get_ssid = bsd_get_ssid,
902 .set_countermeasures = bsd_set_countermeasures,
903 .sta_clear_stats = bsd_sta_clear_stats,
904 .commit = bsd_commit,
905 #ifdef CONFIG_DRIVER_RADIUS_ACL
906 .set_radius_acl_auth = bsd_set_radius_acl_auth,
907 .set_radius_acl_expire = bsd_set_radius_acl_expire,