diff options
author | rpaulo <rpaulo@FreeBSD.org> | 2013-07-04 21:12:58 +0000 |
---|---|---|
committer | rpaulo <rpaulo@FreeBSD.org> | 2013-07-04 21:12:58 +0000 |
commit | 083dd1de651813c2c5b040ffe3cba771aa583df1 (patch) | |
tree | fabd7f6454b47c2dac03bf9badf207872ea2410a /usr.sbin/wpa/hostapd | |
parent | 323bbb2da1c96dac40be6115c94507c2eed99186 (diff) | |
parent | 5e9e13ee49049544adc4f40a42b737418896a338 (diff) | |
download | FreeBSD-src-083dd1de651813c2c5b040ffe3cba771aa583df1.zip FreeBSD-src-083dd1de651813c2c5b040ffe3cba771aa583df1.tar.gz |
Merge hostapd / wpa_supplicant 2.0.
Reviewed by: adrian (driver_bsd + usr.sbin/wpa)
Diffstat (limited to 'usr.sbin/wpa/hostapd')
-rw-r--r-- | usr.sbin/wpa/hostapd/Makefile | 82 | ||||
-rw-r--r-- | usr.sbin/wpa/hostapd/driver_freebsd.c | 787 |
2 files changed, 30 insertions, 839 deletions
diff --git a/usr.sbin/wpa/hostapd/Makefile b/usr.sbin/wpa/hostapd/Makefile index 273c127..530cf02 100644 --- a/usr.sbin/wpa/hostapd/Makefile +++ b/usr.sbin/wpa/hostapd/Makefile @@ -6,55 +6,22 @@ ${WPA_DISTDIR}/src/drivers PROG= hostapd -SRCS= accounting.c \ - aes-wrap.c \ - ap_config.c \ - ap_drv_ops.c \ - ap_mlme.c \ - authsrv.c \ - base64.c \ - chap.c \ - common.c \ - config_file.c \ - ctrl_iface.c \ - ctrl_iface_ap.c \ - drivers.c \ - drv_callbacks.c \ - eap_common.c \ - eap_peap_common.c \ - eap_register.c \ - eapol_auth_dump.c \ - eapol_auth_sm.c \ - eap_server.c \ - eap_server_methods.c \ - eloop.c \ - hostapd.c \ - ieee802_11_auth.c \ - ieee802_11_common.c \ - ieee802_1x.c \ - ip_addr.c \ - main.c \ - md5.c \ - ms_funcs.c \ - os_unix.c \ - peerkey_auth.c \ - pmksa_cache_auth.c \ - preauth_auth.c \ - radius.c \ - radius_client.c \ - sha1-pbkdf2.c \ - sha1.c \ - sta_info.c \ - tkip_countermeasures.c \ - utils.c \ - vlan_init.c \ - wpa_auth.c \ - wpa_auth_glue.c \ - wpa_auth_ie.c \ - wpa_common.c \ - wpa_debug.c \ - wpabuf.c -SRCS+= l2_packet_freebsd.c driver_freebsd.c +SRCS= accounting.c aes-wrap.c ap_config.c ap_drv_ops.c ap_mlme.c authsrv.c \ + base64.c beacon.c chap.c common.c config_file.c ctrl_iface.c \ + ctrl_iface_ap.c driver_common.c l2_packet_freebsd.c driver_bsd.c \ + drivers.c drv_callbacks.c eap_common.c eap_peap_common.c \ + eap_register.c eap_server.c eap_server_methods.c eap_user_db.c \ + eapol_auth_dump.c eapol_auth_sm.c eloop.c gas.c gas_serv.c hostapd.c \ + hs20.c http_client.c http_server.c httpread.c ieee802_11_auth.c \ + ieee802_11_common.c ieee802_11_shared.c ieee802_1x.c ip_addr.c \ + main.c md5.c ms_funcs.c os_unix.c peerkey_auth.c pmksa_cache_auth.c \ + preauth_auth.c radius.c radius_client.c radius_das.c sta_info.c \ + tkip_countermeasures.c upnp_xml.c utils.c uuid.c vlan_init.c \ + wpa_auth.c wpa_auth_glue.c wpa_auth_ie.c wpa_common.c wpa_debug.c \ + wpabuf.c wps.c wps_attr_build.c wps_attr_parse.c wps_attr_process.c \ + wps_common.c wps_dev_attr.c wps_enrollee.c wps_hostapd.c \ + wps_registrar.c wps_upnp.c wps_upnp_ap.c wps_upnp_event.c \ + wps_upnp_ssdp.c wps_upnp_web.c MAN= hostapd.8 hostapd.conf.5 @@ -68,7 +35,12 @@ CFLAGS+=-DCONFIG_DRIVER_BSD \ -DHOSTAPD \ -DCONFIG_DRIVER_RADIUS_ACL \ -DCONFIG_RSN_PREAUTH \ - -DCONFIG_PEERKEY + -DCONFIG_PEERKEY \ + -DCONFIG_WPS \ + -DCONFIG_WPS2 \ + -DCONFIG_WPS_UPNP \ + -DCONFIG_INTERWORKING \ + -DCONFIG_HS20 .if ${MK_INET6} != "no" CFLAGS+= -DCONFIG_IPV6 .endif @@ -92,6 +64,7 @@ CFLAGS+=-DDPKCS12_FUNCS \ -DEAP_SERVER_TLS \ -DEAP_SERVER_TTLS \ -DEAP_TLS_FUNCS \ + -DEAP_SERVER_WSC \ -DCONFIG_NO_DUMP_STATE SRCS+= dump_state.c \ eap_server_gtc.c \ @@ -101,9 +74,14 @@ SRCS+= dump_state.c \ eap_server_peap.c \ eap_server_tls.c \ eap_server_tls_common.c \ - eap_server_ttls.c + eap_server_ttls.c \ + eap_server_wsc.c \ + eap_wsc_common.c TLS_FUNCS=y -NEED_SHA256=y + +.if !empty(CFLAGS:M*-DCONFIG_WPS) +NEED_SIM_COMMON=y +.endif .if !empty(CFLAGS:M*-DEAP_SERVER_AKA) SRCS+= eap_server_aka.c diff --git a/usr.sbin/wpa/hostapd/driver_freebsd.c b/usr.sbin/wpa/hostapd/driver_freebsd.c deleted file mode 100644 index 9b9d7d4..0000000 --- a/usr.sbin/wpa/hostapd/driver_freebsd.c +++ /dev/null @@ -1,787 +0,0 @@ -/* - * Host AP - driver interaction with BSD net80211 layer - * Copyright (c) 2004, Sam Leffler <sam@errno.com> - * Copyright (c) 2004, 2Wire, Inc - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. - * - * $FreeBSD$ - */ - -#include "includes.h" -#include <sys/ioctl.h> - -#include "common.h" -#include "driver.h" -#include "eloop.h" -#include "common/ieee802_11_defs.h" -#include "common/wpa_common.h" - -#include <sys/socket.h> -#include <net/if.h> -#include <net/route.h> -#include <netinet/in.h> - -#include <net80211/ieee80211_ioctl.h> -#include <net80211/ieee80211_freebsd.h> - -#include "l2_packet/l2_packet.h" - -struct bsd_driver_data { - struct hostapd_data *hapd; /* back pointer */ - - int sock; /* open socket for 802.11 ioctls */ - struct l2_packet_data *sock_xmit;/* raw packet xmit socket */ - int route; /* routing socket for events */ - char ifname[IFNAMSIZ+1]; /* interface name */ - unsigned int ifindex; /* interface index */ - void *ctx; - struct wpa_driver_capa capa; /* driver capability */ - int is_ap; /* Access point mode */ - int prev_roaming; /* roaming state to restore on deinit */ - int prev_privacy; /* privacy state to restore on deinit */ - int prev_wpa; /* wpa state to restore on deinit */ -}; - -static int -bsd_set80211(void *priv, int op, int val, const void *arg, int arg_len) -{ - struct bsd_driver_data *drv = priv; - struct ieee80211req ireq; - - os_memset(&ireq, 0, sizeof(ireq)); - os_strlcpy(ireq.i_name, drv->ifname, sizeof(ireq.i_name)); - ireq.i_type = op; - ireq.i_val = val; - ireq.i_data = (void *) arg; - ireq.i_len = arg_len; - - if (ioctl(drv->sock, SIOCS80211, &ireq) < 0) { - wpa_printf(MSG_ERROR, "ioctl[SIOCS80211, op=%u, val=%u, " - "arg_len=%u]: %s", op, val, arg_len, - strerror(errno)); - return -1; - } - return 0; -} - -static int -bsd_get80211(void *priv, struct ieee80211req *ireq, int op, void *arg, - int arg_len) -{ - struct bsd_driver_data *drv = priv; - - os_memset(ireq, 0, sizeof(*ireq)); - os_strlcpy(ireq->i_name, drv->ifname, sizeof(ireq->i_name)); - ireq->i_type = op; - ireq->i_len = arg_len; - ireq->i_data = arg; - - if (ioctl(drv->sock, SIOCG80211, ireq) < 0) { - wpa_printf(MSG_ERROR, "ioctl[SIOCS80211, op=%u, " - "arg_len=%u]: %s", op, arg_len, strerror(errno)); - return -1; - } - return 0; -} - -static int -get80211var(struct bsd_driver_data *drv, int op, void *arg, int arg_len) -{ - struct ieee80211req ireq; - - if (bsd_get80211(drv, &ireq, op, arg, arg_len) < 0) - return -1; - return ireq.i_len; -} - -static int -set80211var(struct bsd_driver_data *drv, int op, const void *arg, int arg_len) -{ - return bsd_set80211(drv, op, 0, arg, arg_len); -} - -static int -set80211param(struct bsd_driver_data *drv, int op, int arg) -{ - return bsd_set80211(drv, op, arg, NULL, 0); -} - -static int -bsd_get_ssid(void *priv, u8 *ssid, int len) -{ - struct bsd_driver_data *drv = priv; - - return get80211var(drv, IEEE80211_IOC_SSID, ssid, IEEE80211_NWID_LEN); -} - -static int -bsd_set_ssid(void *priv, const u8 *ssid, int ssid_len) -{ - struct bsd_driver_data *drv = priv; - - return set80211var(drv, IEEE80211_IOC_SSID, ssid, ssid_len); -} - -static int -bsd_del_key(void *priv, const u8 *addr, int key_idx) -{ - struct ieee80211req_del_key wk; - - os_memset(&wk, 0, sizeof(wk)); - if (addr == NULL) { - wpa_printf(MSG_DEBUG, "%s: key_idx=%d", __func__, key_idx); - wk.idk_keyix = key_idx; - } else { - wpa_printf(MSG_DEBUG, "%s: addr=" MACSTR, __func__, - MAC2STR(addr)); - os_memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN); - wk.idk_keyix = (u_int8_t) IEEE80211_KEYIX_NONE; /* XXX */ - } - - return set80211var(priv, IEEE80211_IOC_DELKEY, &wk, sizeof(wk)); -} - -static int -bsd_send_mlme_param(void *priv, const u8 op, const u16 reason, const u8 *addr) -{ - struct ieee80211req_mlme mlme; - - os_memset(&mlme, 0, sizeof(mlme)); - mlme.im_op = op; - mlme.im_reason = reason; - os_memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); - return set80211var(priv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)); -} - -static int -bsd_ctrl_iface(void *priv, int enable) -{ - struct bsd_driver_data *drv = priv; - struct ifreq ifr; - - if (drv->sock < 0) - return -1; - - os_memset(&ifr, 0, sizeof(ifr)); - os_strlcpy(ifr.ifr_name, drv->ifname, sizeof(ifr.ifr_name)); - - if (ioctl(drv->sock, SIOCGIFFLAGS, &ifr) < 0) { - perror("ioctl[SIOCGIFFLAGS]"); - return -1; - } - - if (enable) { - if ((ifr.ifr_flags & IFF_UP) == IFF_UP) - return 0; - ifr.ifr_flags |= IFF_UP; - } else { - if ((ifr.ifr_flags & IFF_UP) == 0) - return 0; - ifr.ifr_flags &= ~IFF_UP; - } - - if (ioctl(drv->sock, SIOCSIFFLAGS, &ifr) < 0) { - perror("ioctl[SIOCSIFFLAGS]"); - return -1; - } - - return 0; -} - -static int -bsd_commit(void *priv) -{ - return bsd_ctrl_iface(priv, 1); -} - -static int -bsd_set_key(const char *ifname, void *priv, enum wpa_alg alg, - const unsigned char *addr, int key_idx, int set_tx, const u8 *seq, - size_t seq_len, const u8 *key, size_t key_len) -{ - struct ieee80211req_key wk; - - wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%p key_idx=%d set_tx=%d " - "seq_len=%zu key_len=%zu", __func__, alg, addr, key_idx, - set_tx, seq_len, key_len); - - if (alg == WPA_ALG_NONE) { - return bsd_del_key(priv, addr, key_idx); - } - - os_memset(&wk, 0, sizeof(wk)); - switch (alg) { - case WPA_ALG_WEP: - wk.ik_type = IEEE80211_CIPHER_WEP; - break; - case WPA_ALG_TKIP: - wk.ik_type = IEEE80211_CIPHER_TKIP; - break; - case WPA_ALG_CCMP: - wk.ik_type = IEEE80211_CIPHER_AES_CCM; - break; - default: - wpa_printf(MSG_ERROR, "%s: unknown alg=%d", __func__, alg); - return -1; - } - - wk.ik_flags = IEEE80211_KEY_RECV; - if (set_tx) - wk.ik_flags |= IEEE80211_KEY_XMIT; - - if (addr == NULL) { - os_memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); - wk.ik_keyix = key_idx; - } else { - os_memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); - /* - * Deduce whether group/global or unicast key by checking - * the address (yech). Note also that we can only mark global - * keys default; doing this for a unicast key is an error. - */ - if (os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", - IEEE80211_ADDR_LEN) == 0) { - wk.ik_flags |= IEEE80211_KEY_GROUP; - wk.ik_keyix = key_idx; - } else { - wk.ik_keyix = key_idx == 0 ? IEEE80211_KEYIX_NONE : - key_idx; - } - } - if (wk.ik_keyix != IEEE80211_KEYIX_NONE && set_tx) - wk.ik_flags |= IEEE80211_KEY_DEFAULT; - wk.ik_keylen = key_len; - os_memcpy(&wk.ik_keyrsc, seq, seq_len); - os_memcpy(wk.ik_keydata, key, key_len); - - return set80211var(priv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk)); -} - -static int -bsd_configure_wpa(void *priv, struct wpa_bss_params *params) -{ - wpa_printf(MSG_DEBUG, "%s: enable WPA= 0x%x", __func__, params->wpa); - if (set80211param(priv, IEEE80211_IOC_WPA, params->wpa)) { - printf("Unable to set WPA to %u\n", params->wpa); - return -1; - } - return 0; -} - -static int -bsd_set_ieee8021x(void *priv, struct wpa_bss_params *params) -{ - wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, params->enabled); - - if (!params->enabled) { - /* XXX restore state */ - return set80211param(priv, IEEE80211_IOC_AUTHMODE, - IEEE80211_AUTH_AUTO); - } - if (!params->wpa && !params->ieee802_1x) { - wpa_printf(MSG_ERROR, "%s: No 802.1X or WPA enabled", - __func__); - return -1; - } - if (params->wpa && bsd_configure_wpa(priv, params) != 0) { - wpa_printf(MSG_ERROR, "%s: Failed to configure WPA state", - __func__); - return -1; - } - if (set80211param(priv, IEEE80211_IOC_AUTHMODE, - (params->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) { - wpa_printf(MSG_ERROR, "%s: Failed to enable WPA/802.1X", - __func__); - return -1; - } - return 0; -} - -static int -bsd_set_sta_authorized(void *priv, const u8 *addr, - int total_flags, int flags_or, int flags_and) -{ - int authorized = -1; - - /* For now, only support setting Authorized flag */ - if (flags_or & WPA_STA_AUTHORIZED) - authorized = 1; - if (!(flags_and & WPA_STA_AUTHORIZED)) - authorized = 0; - - if (authorized < 0) - return 0; - - return bsd_send_mlme_param(priv, authorized ? - IEEE80211_MLME_AUTHORIZE : - IEEE80211_MLME_UNAUTHORIZE, 0, addr); -} - -static void -bsd_new_sta(void *priv, void *ctx, u8 addr[IEEE80211_ADDR_LEN]) -{ - struct ieee80211req_wpaie ie; - int ielen = 0; - u8 *iebuf = NULL; - - /* - * Fetch and validate any negotiated WPA/RSN parameters. - */ - memset(&ie, 0, sizeof(ie)); - memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN); - if (get80211var(priv, IEEE80211_IOC_WPAIE, &ie, sizeof(ie)) < 0) { - printf("Failed to get WPA/RSN information element.\n"); - goto no_ie; - } - iebuf = ie.wpa_ie; - ielen = ie.wpa_ie[1]; - if (ielen == 0) - iebuf = NULL; - else - ielen += 2; - -no_ie: - drv_event_assoc(ctx, addr, iebuf, ielen); -} - -static int -bsd_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len, - int encrypt, const u8 *own_addr) -{ - struct bsd_driver_data *drv = priv; - - wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", data, data_len); - - return l2_packet_send(drv->sock_xmit, addr, ETH_P_EAPOL, data, - data_len); -} - -static int -bsd_set_opt_ie(void *priv, const u8 *ie, size_t ie_len) -{ - wpa_printf(MSG_DEBUG, "%s: set WPA+RSN ie (len %lu)", __func__, - (unsigned long)ie_len); - return bsd_set80211(priv, IEEE80211_IOC_APPIE, IEEE80211_APPIE_WPA, - ie, ie_len); -} - -/* - * Avoid conflicts with hostapd definitions by undefining couple of defines - * from net80211 header files. - */ -#undef RSN_VERSION -#undef WPA_VERSION -#undef WPA_OUI_TYPE - -static int bsd_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, - int reason_code); - -static const char * -ether_sprintf(const u8 *addr) -{ - static char buf[sizeof(MACSTR)]; - - if (addr != NULL) - snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr)); - else - snprintf(buf, sizeof(buf), MACSTR, 0,0,0,0,0,0); - return buf; -} - -static int -bsd_set_privacy(void *priv, int enabled) -{ - wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled); - - return set80211param(priv, IEEE80211_IOC_PRIVACY, enabled); -} - -static int -bsd_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx, - u8 *seq) -{ - struct ieee80211req_key wk; - - wpa_printf(MSG_DEBUG, "%s: addr=%s idx=%d", - __func__, ether_sprintf(addr), idx); - - memset(&wk, 0, sizeof(wk)); - if (addr == NULL) - memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN); - else - memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); - wk.ik_keyix = idx; - - if (get80211var(priv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk)) < 0) { - printf("Failed to get encryption.\n"); - return -1; - } - -#ifdef WORDS_BIGENDIAN - { - /* - * wk.ik_keytsc is in host byte order (big endian), need to - * swap it to match with the byte order used in WPA. - */ - int i; - u8 tmp[WPA_KEY_RSC_LEN]; - memcpy(tmp, &wk.ik_keytsc, sizeof(wk.ik_keytsc)); - for (i = 0; i < WPA_KEY_RSC_LEN; i++) { - seq[i] = tmp[WPA_KEY_RSC_LEN - i - 1]; - } - } -#else /* WORDS_BIGENDIAN */ - memcpy(seq, &wk.ik_keytsc, sizeof(wk.ik_keytsc)); -#endif /* WORDS_BIGENDIAN */ - return 0; -} - - -static int -bsd_flush(void *priv) -{ - u8 allsta[IEEE80211_ADDR_LEN]; - - memset(allsta, 0xff, IEEE80211_ADDR_LEN); - return bsd_sta_deauth(priv, NULL, allsta, IEEE80211_REASON_AUTH_LEAVE); -} - - -static int -bsd_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data, - const u8 *addr) -{ - struct ieee80211req_sta_stats stats; - - memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN); - if (get80211var(priv, IEEE80211_IOC_STA_STATS, &stats, sizeof(stats)) - > 0) { - /* XXX? do packets counts include non-data frames? */ - data->rx_packets = stats.is_stats.ns_rx_data; - data->rx_bytes = stats.is_stats.ns_rx_bytes; - data->tx_packets = stats.is_stats.ns_tx_data; - data->tx_bytes = stats.is_stats.ns_tx_bytes; - } - return 0; -} - -static int -bsd_sta_clear_stats(void *priv, const u8 *addr) -{ - struct ieee80211req_sta_stats stats; - - wpa_printf(MSG_DEBUG, "%s: addr=%s", __func__, ether_sprintf(addr)); - - /* zero station statistics */ - memset(&stats, 0, sizeof(stats)); - memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN); - return set80211var(priv, IEEE80211_IOC_STA_STATS, &stats, - sizeof(stats)); -} - -static int -bsd_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr, int reason_code) -{ - return bsd_send_mlme_param(priv, IEEE80211_MLME_DEAUTH, reason_code, - addr); -} - -static int -bsd_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr, - int reason_code) -{ - return bsd_send_mlme_param(priv, IEEE80211_MLME_DISASSOC, reason_code, - addr); -} - -static void -bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx) -{ - struct bsd_driver_data *drv = ctx; - char buf[2048]; - struct if_announcemsghdr *ifan; - struct rt_msghdr *rtm; - struct ieee80211_michael_event *mic; - struct ieee80211_join_event *join; - struct ieee80211_leave_event *leave; -#ifdef CONFIG_DRIVER_RADIUS_ACL - struct ieee80211_auth_event *auth; -#endif - int n; - union wpa_event_data data; - - n = read(sock, buf, sizeof(buf)); - if (n < 0) { - if (errno != EINTR && errno != EAGAIN) - perror("read(PF_ROUTE)"); - return; - } - - rtm = (struct rt_msghdr *) buf; - if (rtm->rtm_version != RTM_VERSION) { - wpa_printf(MSG_DEBUG, "Routing message version %d not " - "understood\n", rtm->rtm_version); - return; - } - ifan = (struct if_announcemsghdr *) rtm; - if (ifan->ifan_index != drv->ifindex) { - wpa_printf(MSG_DEBUG, "Discard routing message to if#%d " - "(not for us %d)\n", - ifan->ifan_index, drv->ifindex); - return; - } - switch (rtm->rtm_type) { - case RTM_IEEE80211: - switch (ifan->ifan_what) { - case RTM_IEEE80211_ASSOC: - case RTM_IEEE80211_REASSOC: - case RTM_IEEE80211_DISASSOC: - case RTM_IEEE80211_SCAN: - break; - case RTM_IEEE80211_LEAVE: - leave = (struct ieee80211_leave_event *) &ifan[1]; - drv_event_disassoc(drv->hapd, leave->iev_addr); - break; - case RTM_IEEE80211_JOIN: -#ifdef RTM_IEEE80211_REJOIN - case RTM_IEEE80211_REJOIN: -#endif - join = (struct ieee80211_join_event *) &ifan[1]; - bsd_new_sta(drv, drv->hapd, join->iev_addr); - break; - case RTM_IEEE80211_REPLAY: - /* ignore */ - break; - case RTM_IEEE80211_MICHAEL: - mic = (struct ieee80211_michael_event *) &ifan[1]; - wpa_printf(MSG_DEBUG, - "Michael MIC failure wireless event: " - "keyix=%u src_addr=" MACSTR, mic->iev_keyix, - MAC2STR(mic->iev_src)); - os_memset(&data, 0, sizeof(data)); - data.michael_mic_failure.unicast = 1; - data.michael_mic_failure.src = mic->iev_src; - wpa_supplicant_event(drv->hapd, - EVENT_MICHAEL_MIC_FAILURE, &data); - break; -#ifdef CONFIG_DRIVER_RADIUS_ACL_NOT_YET - case RTM_IEEE80211_AUTH: - auth = (struct ieee80211_auth_event *) &ifan[1]; - wpa_printf(MSG_DEBUG, "802.11 AUTH, STA = " MACSTR, - MAC2STR(auth->iev_addr)); - n = hostapd_allowed_address(drv->hapd, auth->iev_addr, - NULL, 0, NULL, NULL, NULL); - switch (n) { - case HOSTAPD_ACL_ACCEPT: - case HOSTAPD_ACL_REJECT: - hostapd_set_radius_acl_auth(drv->hapd, - auth->iev_addr, n, 0); - wpa_printf(MSG_DEBUG, - "802.11 AUTH, STA = " MACSTR " hostapd says: %s", - MAC2STR(auth->iev_addr), - (n == HOSTAPD_ACL_ACCEPT ? - "ACCEPT" : "REJECT" )); - break; - case HOSTAPD_ACL_PENDING: - wpa_printf(MSG_DEBUG, - "802.11 AUTH, STA = " MACSTR " pending", - MAC2STR(auth->iev_addr)); - break; - } - break; -#endif /* CONFIG_DRIVER_RADIUS_ACL */ - } - break; - } -} - -static void -handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len) -{ - struct bsd_driver_data *drv = ctx; - drv_event_eapol_rx(drv->hapd, src_addr, buf, len); -} - -static int -bsd_set_countermeasures(void *priv, int enabled) -{ - wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled); - return set80211param(priv, IEEE80211_IOC_COUNTERMEASURES, enabled); -} - -#ifdef CONFIG_DRIVER_RADIUS_ACL_NOT_YET -static int -bsd_set_radius_acl_auth(void *priv, const u8 *mac, int accepted, - u32 session_timeout) -{ - struct bsd_driver_data *drv = priv; - struct hostapd_data *hapd = drv->hapd; - struct ieee80211req_mlme mlme; - - switch (accepted) { - case HOSTAPD_ACL_ACCEPT_TIMEOUT: - wpa_printf(MSG_DEBUG, "[%s] STA " MACSTR - " has been accepted by RADIUS ACL with timeout " - "of %d.\n", hapd->conf->iface, MAC2STR(mac), - session_timeout); - mlme.im_reason = IEEE80211_STATUS_SUCCESS; - break; - case HOSTAPD_ACL_ACCEPT: - wpa_printf(MSG_DEBUG, "[%s] STA " MACSTR - " has been accepted by RADIUS ACL.\n", - hapd->conf->iface, MAC2STR(mac)); - mlme.im_reason = IEEE80211_STATUS_SUCCESS; - break; - case HOSTAPD_ACL_REJECT: - wpa_printf(MSG_DEBUG, "[%s] STA " MACSTR - " has been rejected by RADIUS ACL.\n", - hapd->conf->iface, MAC2STR(mac)); - mlme.im_reason = IEEE80211_STATUS_UNSPECIFIED; - break; - default: - wpa_printf(MSG_ERROR, "[%s] STA " MACSTR - " has unknown status (%d) by RADIUS ACL. " - "Nothing to do...\n", hapd->conf->iface, - MAC2STR(mac), accepted); - return 0; - } - memset(&mlme, 0, sizeof(mlme)); - mlme.im_op = IEEE80211_MLME_AUTH; - memcpy(mlme.im_macaddr, mac, IEEE80211_ADDR_LEN); - return set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)); -} - -static int -bsd_set_radius_acl_expire(void *priv, const u8 *mac) -{ - struct bsd_driver_data *drv = priv; - struct hostapd_data *hapd = drv->hapd; - - /* - * The expiry of the MAC address from RADIUS ACL cache doesn't mean - * that we should kick off the client. Our current approach doesn't - * require adding/removing entries from an allow/deny list; so this - * function is likely unnecessary - */ - wpa_printf(MSG_DEBUG, "[%s] STA " MACSTR " radius acl cache " - "expired; nothing to do...", hapd->conf->iface, - MAC2STR(mac)); - return 0; -} -#endif /* CONFIG_DRIVER_RADIUS_ACL */ - -static void * -bsd_init(struct hostapd_data *hapd, struct wpa_init_params *params) -{ - struct bsd_driver_data *drv; - - drv = os_zalloc(sizeof(struct bsd_driver_data)); - if (drv == NULL) { - printf("Could not allocate memory for bsd driver data\n"); - goto bad; - } - - drv->hapd = hapd; - drv->sock = socket(PF_INET, SOCK_DGRAM, 0); - if (drv->sock < 0) { - perror("socket[PF_INET,SOCK_DGRAM]"); - goto bad; - } - os_strlcpy(drv->ifname, params->ifname, sizeof(drv->ifname)); - /* - * NB: We require the interface name be mappable to an index. - * This implies we do not support having wpa_supplicant - * wait for an interface to appear. This seems ok; that - * doesn't belong here; it's really the job of devd. - * XXXSCW: devd is FreeBSD-specific. - */ - drv->ifindex = if_nametoindex(drv->ifname); - if (drv->ifindex == 0) { - printf("%s: interface %s does not exist", __func__, - drv->ifname); - goto bad; - } - - drv->sock_xmit = l2_packet_init(drv->ifname, NULL, ETH_P_EAPOL, - handle_read, drv, 0); - if (drv->sock_xmit == NULL) - goto bad; - if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr)) - goto bad; - - /* mark down during setup */ - if (bsd_ctrl_iface(drv, 0) < 0) - goto bad; - - drv->route = socket(PF_ROUTE, SOCK_RAW, 0); - if (drv->route < 0) { - perror("socket(PF_ROUTE,SOCK_RAW)"); - goto bad; - } - eloop_register_read_sock(drv->route, bsd_wireless_event_receive, drv, - NULL); - - return drv; -bad: - if (drv == NULL) - return NULL; - if (drv->sock_xmit != NULL) - l2_packet_deinit(drv->sock_xmit); - if (drv->sock >= 0) - close(drv->sock); - os_free(drv); - return NULL; -} - - -static void -bsd_deinit(void *priv) -{ - struct bsd_driver_data *drv = priv; - - if (drv->route >= 0) { - eloop_unregister_read_sock(drv->route); - close(drv->route); - } - bsd_ctrl_iface(drv, 0); - if (drv->sock >= 0) - close(drv->sock); - if (drv->sock_xmit != NULL) - l2_packet_deinit(drv->sock_xmit); - os_free(drv); -} - -const struct wpa_driver_ops wpa_driver_bsd_ops = { - .name = "bsd", - .desc = "BSD 802.11 support", - .hapd_init = bsd_init, - .hapd_deinit = bsd_deinit, - .set_privacy = bsd_set_privacy, - .get_seqnum = bsd_get_seqnum, - .flush = bsd_flush, - .read_sta_data = bsd_read_sta_driver_data, - .sta_clear_stats = bsd_sta_clear_stats, - .sta_disassoc = bsd_sta_disassoc, - .sta_deauth = bsd_sta_deauth, - .set_key = bsd_set_key, - .set_ieee8021x = bsd_set_ieee8021x, - .hapd_set_ssid = bsd_set_ssid, - .hapd_get_ssid = bsd_get_ssid, - .hapd_send_eapol = bsd_send_eapol, - .sta_set_flags = bsd_set_sta_authorized, - .set_generic_elem = bsd_set_opt_ie, - .set_countermeasures = bsd_set_countermeasures, - .commit = bsd_commit, -#ifdef CONFIG_DRIVER_RADIUS_ACL_NOT_YET - .set_radius_acl_auth = bsd_set_radius_acl_auth, - .set_radius_acl_expire = bsd_set_radius_acl_expire, -#endif -}; |