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 | |
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')
-rw-r--r-- | usr.sbin/wpa/Makefile.crypto | 20 | ||||
-rw-r--r-- | usr.sbin/wpa/Makefile.inc | 4 | ||||
-rw-r--r-- | usr.sbin/wpa/hostapd/Makefile | 82 | ||||
-rw-r--r-- | usr.sbin/wpa/hostapd/driver_freebsd.c | 787 | ||||
-rw-r--r-- | usr.sbin/wpa/hostapd_cli/Makefile | 2 | ||||
-rw-r--r-- | usr.sbin/wpa/wpa_cli/Makefile | 2 | ||||
-rw-r--r-- | usr.sbin/wpa/wpa_passphrase/Makefile | 4 | ||||
-rw-r--r-- | usr.sbin/wpa/wpa_priv/Makefile | 17 | ||||
-rw-r--r-- | usr.sbin/wpa/wpa_supplicant/Makefile | 65 | ||||
-rw-r--r-- | usr.sbin/wpa/wpa_supplicant/driver_freebsd.c | 934 |
10 files changed, 99 insertions, 1818 deletions
diff --git a/usr.sbin/wpa/Makefile.crypto b/usr.sbin/wpa/Makefile.crypto index e1ac445..94367bb 100644 --- a/usr.sbin/wpa/Makefile.crypto +++ b/usr.sbin/wpa/Makefile.crypto @@ -1,20 +1,24 @@ # $FreeBSD$ .if ${MK_OPENSSL} != "no" && !defined(RELEASE_CRUNCH) -SRCS+= crypto_openssl.c +SRCS+= crypto_openssl.c random.c sha1-prf.c sha256-prf.c DPADD+= ${LIBSSL} ${LIBCRYPTO} LDADD+= -lssl -lcrypto +CFLAGS+= -DCONFIG_SHA256 .else CFLAGS+=-DCONFIG_CRYPTO_INTERNAL -SRCS+= crypto_internal.c +SRCS+= crypto_internal.c random.c CONFIG_INTERNAL_AES=y CONFIG_INTERNAL_DES=y CONFIG_INTERNAL_MD4=y CONFIG_INTERNAL_MD5=y CONFIG_INTERNAL_RC4=y CONFIG_INTERNAL_SHA1=y +NEED_SHA256=y CONFIG_INTERNAL_SHA256=y CONFIG_INTERNAL_TLS=y +CONFIG_INTERNAL_DH5=y +CONFIG_INTERNAL_DH=y NEED_AES_ENC=true .endif @@ -105,17 +109,25 @@ SRCS+= rc4.c .endif .if defined(CONFIG_INTERNAL_SHA1) -SRCS+= sha1-internal.c +SRCS+= sha1-internal.c sha1-pbkdf2.c sha1.c sha1-prf.c .endif .if defined(NEED_SHA256) CFLAGS+=-DCONFIG_SHA256 SRCS+= sha256.c .if defined(CONFIG_INTERNAL_SHA256) -SRCS+= sha256-internal.c +SRCS+= sha256-internal.c sha256-prf.c .endif .endif .if defined(NEED_TLS_PRF) SRCS+= sha1-tlsprf.c .endif + +.if defined(CONFIG_INTERNAL_DH5) +SRCS+= dh_group5.c +.endif + +.if defined(CONFIG_INTERNAL_DH) +SRCS+= dh_groups.c +.endif diff --git a/usr.sbin/wpa/Makefile.inc b/usr.sbin/wpa/Makefile.inc index bbd55fc..0b13b97 100644 --- a/usr.sbin/wpa/Makefile.inc +++ b/usr.sbin/wpa/Makefile.inc @@ -19,7 +19,8 @@ HOSTAPD_DISTDIR?= ${WPA_DISTDIR}/hostapd ${WPA_DISTDIR}/src/radius \ ${WPA_DISTDIR}/src/rsn_supp \ ${WPA_DISTDIR}/src/tls \ - ${WPA_DISTDIR}/src/utils + ${WPA_DISTDIR}/src/utils \ + ${WPA_DISTDIR}/src/wps CFLAGS+=-I${.CURDIR} CFLAGS+=-I${HOSTAPD_DISTDIR} @@ -29,6 +30,7 @@ CFLAGS+=-I${WPA_DISTDIR}/src/crypto CFLAGS+=-I${WPA_DISTDIR}/src/drivers CFLAGS+=-I${WPA_DISTDIR}/src/l2_packet CFLAGS+=-I${WPA_DISTDIR}/src/utils +CFLAGS+=-I${WPA_DISTDIR}/src/wps CFLAGS+= -DCONFIG_CTRL_IFACE CFLAGS+= -DCONFIG_CTRL_IFACE_UNIX 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 -}; diff --git a/usr.sbin/wpa/hostapd_cli/Makefile b/usr.sbin/wpa/hostapd_cli/Makefile index 667134c..8677fbf 100644 --- a/usr.sbin/wpa/hostapd_cli/Makefile +++ b/usr.sbin/wpa/hostapd_cli/Makefile @@ -5,7 +5,7 @@ .PATH.c:${HOSTAPD_DISTDIR} PROG= hostapd_cli -SRCS= hostapd_cli.c wpa_ctrl.c os_unix.c +SRCS= common.c edit.c eloop.c hostapd_cli.c os_unix.c wpa_ctrl.c wpa_debug.c CFLAGS+= -DCONFIG_CTRL_IFACE CFLAGS+= -DCONFIG_CTRL_IFACE_UNIX diff --git a/usr.sbin/wpa/wpa_cli/Makefile b/usr.sbin/wpa/wpa_cli/Makefile index 1721437..da25325 100644 --- a/usr.sbin/wpa/wpa_cli/Makefile +++ b/usr.sbin/wpa/wpa_cli/Makefile @@ -5,7 +5,7 @@ .PATH.c:${WPA_SUPPLICANT_DISTDIR} PROG= wpa_cli -SRCS= wpa_cli.c wpa_ctrl.c os_unix.c +SRCS= common.c edit.c eloop.c os_unix.c wpa_cli.c wpa_ctrl.c wpa_debug.c MAN= wpa_cli.8 diff --git a/usr.sbin/wpa/wpa_passphrase/Makefile b/usr.sbin/wpa/wpa_passphrase/Makefile index 385e23c..16321c4 100644 --- a/usr.sbin/wpa/wpa_passphrase/Makefile +++ b/usr.sbin/wpa/wpa_passphrase/Makefile @@ -5,8 +5,8 @@ .PATH.c:${WPA_SUPPLICANT_DISTDIR} PROG= wpa_passphrase -SRCS= wpa_passphrase.c sha1.c sha1-internal.c sha1-pbkdf2.c \ - md5.c md5-internal.c +SRCS= common.c md5-internal.c md5.c os_unix.c sha1-internal.c sha1-pbkdf2.c sha1.c \ + wpa_passphrase.c CFLAGS+= -DINTERNAL_SHA1 CFLAGS+= -DINTERNAL_MD5 diff --git a/usr.sbin/wpa/wpa_priv/Makefile b/usr.sbin/wpa/wpa_priv/Makefile new file mode 100644 index 0000000..4dbc631 --- /dev/null +++ b/usr.sbin/wpa/wpa_priv/Makefile @@ -0,0 +1,17 @@ +# $FreeBSD$ + +.include "${.CURDIR}/../Makefile.inc" + +.PATH.c:${WPA_SUPPLICANT_DISTDIR} \ + ${WPA_DISTDIR}/src/drivers + +PROG= wpa_priv +SRCS= drivers.c os_unix.c eloop.c common.c wpa_debug.c wpabuf.c wpa_priv.c \ + driver_common.c l2_packet_freebsd.c + +DPADD+= ${LIBPCAP} +LDADD+= -lpcap + +.include "${.CURDIR}/../Makefile.crypto" + +.include <bsd.prog.mk> diff --git a/usr.sbin/wpa/wpa_supplicant/Makefile b/usr.sbin/wpa/wpa_supplicant/Makefile index 6c352ab..3424413 100644 --- a/usr.sbin/wpa/wpa_supplicant/Makefile +++ b/usr.sbin/wpa/wpa_supplicant/Makefile @@ -6,41 +6,19 @@ ${WPA_DISTDIR}/src/drivers PROG= wpa_supplicant -SRCS= aes-unwrap.c \ - base64.c \ - blacklist.c \ - bss.c \ - common.c \ - config.c \ - config_file.c \ - ctrl_iface.c \ - ctrl_iface_unix.c \ - driver_ndis.c \ - driver_wired.c \ - drivers.c \ - eap_register.c \ - eloop.c \ - events.c \ - main.c \ - md5.c \ - notify.c \ - os_unix.c \ - peerkey.c \ - pmksa_cache.c \ - preauth.c \ - scan.c \ - sha1-pbkdf2.c \ - sha1.c \ - wpa.c \ - wpa_common.c \ - wpa_debug.c \ - wpa_ie.c \ - wpa_supplicant.c \ - wpabuf.c \ - wpas_glue.c -SRCS+= driver_freebsd.c \ - l2_packet_freebsd.c \ - Packet32.c +SRCS= aes-unwrap.c base64.c blacklist.c bss.c common.c config.c \ + config_file.c ctrl_iface.c ctrl_iface_unix.c driver_bsd.c \ + driver_common.c driver_ndis.c driver_wired.c drivers.c \ + eap_register.c eloop.c events.c gas.c gas_query.c hs20.c \ + hs20_supplicant.c http_client.c http_server.c httpread.c \ + ieee802_11_common.c interworking.c l2_packet_freebsd.c main.c \ + md5.c notify.c offchannel.c os_unix.c peerkey.c pmksa_cache.c \ + preauth.c scan.c upnp_xml.c uuid.c wpa.c wpa_common.c wpa_debug.c \ + wpa_ft.c wpa_ie.c wpa_supplicant.c wpabuf.c wpas_glue.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_registrar.c \ + wps_supplicant.c wps_upnp.c wps_upnp_ap.c wps_upnp_event.c \ + wps_upnp_ssdp.c wps_upnp_web.c Packet32.c MAN= wpa_supplicant.8 wpa_supplicant.conf.5 @@ -58,6 +36,15 @@ CFLAGS+=-DCONFIG_BACKEND_FILE \ -DCONFIG_PEERKEY \ -DCONFIG_SMARTCARD \ -DCONFIG_TERMINATE_ONLASTIF \ + -DCONFIG_WPS \ + -DCONFIG_WPS2 \ + -DCONFIG_WPS_UPNP \ + -DCONFIG_TLS=openssl \ + -DCONFIG_IEEE80211R \ + -DCONFIG_INTERWORKING \ + -DCONFIG_PRIVSEP \ + -DCONFIG_HS20 \ + -DCONFIG_GAS \ -DPKCS12_FUNCS #CFLAGS+= -g DPADD+= ${LIBPCAP} @@ -79,6 +66,9 @@ CFLAGS+=-DEAP_GTC \ -DEAP_PSK \ -DEAP_TLS \ -DEAP_TTLS \ + -DEAP_GTC \ + -DEAP_OTP \ + -DEAP_LEAP \ -DIEEE8021X_EAPOL SRCS+= chap.c \ eap.c \ @@ -103,7 +93,10 @@ TLS_FUNCS=y NEED_AES_EAX=y NEED_AES_ENCBLOCK=y NEED_AES_OMAC1=y -NEED_SHA256=y +.endif + +.if !empty(CFLAGS:M-DCONFIG_WPS) +NEED_AES_CBC=y .endif .if !empty(CFLAGS:M*-DEAP_AKA) diff --git a/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c b/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c deleted file mode 100644 index 24a0b9c..0000000 --- a/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c +++ /dev/null @@ -1,934 +0,0 @@ -/* - * WPA Supplicant - driver interaction with BSD net80211 layer - * Copyright (c) 2004, Sam Leffler <sam@errno.com> - * - * 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 <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <sys/ioctl.h> -#include <errno.h> - -#include "common.h" -#include "driver.h" -#include "eloop.h" -#include "l2_packet.h" -#include "ieee802_11_defs.h" - -#include <sys/socket.h> -#include <net/if.h> -#include <net/if_media.h> -#include <net/ethernet.h> - -#include <net80211/ieee80211_ioctl.h> - -struct wpa_driver_bsd_data { - int sock; /* open socket for 802.11 ioctls */ - int route; /* routing socket for events */ - char ifname[IFNAMSIZ+1]; /* interface name */ - unsigned int ifindex; /* interface index */ - void *ctx; - 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 */ - int prev_scanvalid; /* scan valid to restore on deinit */ - uint8_t lastssid[IEEE80211_NWID_LEN]; - int lastssid_len; - uint32_t drivercaps; /* general driver capabilities */ - uint32_t cryptocaps; /* hardware crypto support */ - enum ieee80211_opmode opmode; /* operation mode */ -}; - -static enum ieee80211_opmode -get80211opmode(struct wpa_driver_bsd_data *drv) -{ - struct ifmediareq ifmr; - - (void) memset(&ifmr, 0, sizeof(ifmr)); - (void) strncpy(ifmr.ifm_name, drv->ifname, sizeof(ifmr.ifm_name)); - - if (ioctl(drv->sock, SIOCGIFMEDIA, (caddr_t)&ifmr) >= 0) { - if (ifmr.ifm_current & IFM_IEEE80211_ADHOC) { - if (ifmr.ifm_current & IFM_FLAG0) - return IEEE80211_M_AHDEMO; - else - return IEEE80211_M_IBSS; - } - if (ifmr.ifm_current & IFM_IEEE80211_HOSTAP) - return IEEE80211_M_HOSTAP; - if (ifmr.ifm_current & IFM_IEEE80211_MONITOR) - return IEEE80211_M_MONITOR; - if (ifmr.ifm_current & IFM_IEEE80211_MBSS) - return IEEE80211_M_MBSS; - } - return IEEE80211_M_STA; -} - -static int -set80211var(struct wpa_driver_bsd_data *drv, int op, const void *arg, int arg_len) -{ - struct ieee80211req ireq; - - memset(&ireq, 0, sizeof(ireq)); - strncpy(ireq.i_name, drv->ifname, IFNAMSIZ); - ireq.i_type = op; - ireq.i_len = arg_len; - ireq.i_data = (void *) arg; - - if (ioctl(drv->sock, SIOCS80211, &ireq) < 0) { - fprintf(stderr, "ioctl[SIOCS80211, op %u, len %u]: %s\n", - op, arg_len, strerror(errno)); - return -1; - } - return 0; -} - -static int -get80211var(struct wpa_driver_bsd_data *drv, int op, void *arg, int arg_len) -{ - struct ieee80211req ireq; - - memset(&ireq, 0, sizeof(ireq)); - strncpy(ireq.i_name, drv->ifname, IFNAMSIZ); - ireq.i_type = op; - ireq.i_len = arg_len; - ireq.i_data = arg; - - if (ioctl(drv->sock, SIOCG80211, &ireq) < 0) { - fprintf(stderr, "ioctl[SIOCG80211, op %u, len %u]: %s\n", - op, arg_len, strerror(errno)); - return -1; - } - return ireq.i_len; -} - -static int -set80211param(struct wpa_driver_bsd_data *drv, int op, int arg) -{ - struct ieee80211req ireq; - - memset(&ireq, 0, sizeof(ireq)); - strncpy(ireq.i_name, drv->ifname, IFNAMSIZ); - ireq.i_type = op; - ireq.i_val = arg; - - if (ioctl(drv->sock, SIOCS80211, &ireq) < 0) { - fprintf(stderr, "ioctl[SIOCS80211, op %u, arg 0x%x]: %s\n", - op, arg, strerror(errno)); - return -1; - } - return 0; -} - -static int -get80211param(struct wpa_driver_bsd_data *drv, int op) -{ - struct ieee80211req ireq; - - memset(&ireq, 0, sizeof(ireq)); - strncpy(ireq.i_name, drv->ifname, IFNAMSIZ); - ireq.i_type = op; - - if (ioctl(drv->sock, SIOCG80211, &ireq) < 0) { - fprintf(stderr, "ioctl[SIOCG80211, op %u]: %s\n", - op, strerror(errno)); - return -1; - } - return ireq.i_val; -} - -static int -getifflags(struct wpa_driver_bsd_data *drv, int *flags) -{ - struct ifreq ifr; - - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, drv->ifname, sizeof (ifr.ifr_name)); - if (ioctl(drv->sock, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) { - perror("SIOCGIFFLAGS"); - return errno; - } - *flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16); - return 0; -} - -static int -setifflags(struct wpa_driver_bsd_data *drv, int flags) -{ - struct ifreq ifr; - - memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, drv->ifname, sizeof (ifr.ifr_name)); - ifr.ifr_flags = flags & 0xffff; - ifr.ifr_flagshigh = flags >> 16; - if (ioctl(drv->sock, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) { - perror("SIOCSIFFLAGS"); - return errno; - } - return 0; -} - -static int -wpa_driver_bsd_get_bssid(void *priv, u8 *bssid) -{ - struct wpa_driver_bsd_data *drv = priv; - - return get80211var(drv, IEEE80211_IOC_BSSID, - bssid, IEEE80211_ADDR_LEN) < 0 ? -1 : 0; -} - -#if 0 -static int -wpa_driver_bsd_set_bssid(void *priv, const char *bssid) -{ - struct wpa_driver_bsd_data *drv = priv; - - return set80211var(drv, IEEE80211_IOC_BSSID, - bssid, IEEE80211_ADDR_LEN); -} -#endif - -static int -wpa_driver_bsd_get_ssid(void *priv, u8 *ssid) -{ - struct wpa_driver_bsd_data *drv = priv; - - return get80211var(drv, IEEE80211_IOC_SSID, - ssid, IEEE80211_NWID_LEN); -} - -static int -wpa_driver_bsd_set_ssid(void *priv, const char *ssid, - size_t ssid_len) -{ - struct wpa_driver_bsd_data *drv = priv; - - return set80211var(drv, IEEE80211_IOC_SSID, ssid, ssid_len); -} - -static int -wpa_driver_bsd_set_wpa_ie(struct wpa_driver_bsd_data *drv, - const u8 *wpa_ie, size_t wpa_ie_len) -{ - struct ieee80211req ireq; - - memset(&ireq, 0, sizeof(ireq)); - strncpy(ireq.i_name, drv->ifname, IFNAMSIZ); - ireq.i_type = IEEE80211_IOC_APPIE; - ireq.i_val = IEEE80211_APPIE_WPA; - ireq.i_len = wpa_ie_len; - ireq.i_data = (void *) wpa_ie; - if (ioctl(drv->sock, SIOCS80211, &ireq) < 0) { - fprintf(stderr, - "ioctl[IEEE80211_IOC_APPIE:IEEE80211_APPIE_WPA]: %s\n", - strerror(errno)); - return -1; - } - return 0; -} - -static int -wpa_driver_bsd_set_wpa_internal(void *priv, int wpa, int privacy) -{ - struct wpa_driver_bsd_data *drv = priv; - int ret = 0; - - wpa_printf(MSG_DEBUG, "%s: wpa=%d privacy=%d", - __FUNCTION__, wpa, privacy); - - if (!wpa && wpa_driver_bsd_set_wpa_ie(drv, NULL, 0) < 0) - ret = -1; - if (set80211param(drv, IEEE80211_IOC_PRIVACY, privacy) < 0) - ret = -1; - if (set80211param(drv, IEEE80211_IOC_WPA, wpa) < 0) - ret = -1; - - return ret; -} - -static int -wpa_driver_bsd_del_key(struct wpa_driver_bsd_data *drv, int key_idx, - const unsigned char *addr) -{ - struct ieee80211req_del_key wk; - - memset(&wk, 0, sizeof(wk)); - if (addr != NULL && - bcmp(addr, "\xff\xff\xff\xff\xff\xff", IEEE80211_ADDR_LEN) != 0) { - struct ether_addr ea; - - memcpy(&ea, addr, IEEE80211_ADDR_LEN); - wpa_printf(MSG_DEBUG, "%s: addr=%s keyidx=%d", - __func__, ether_ntoa(&ea), key_idx); - memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN); - wk.idk_keyix = (uint8_t) IEEE80211_KEYIX_NONE; - } else { - wpa_printf(MSG_DEBUG, "%s: keyidx=%d", __func__, key_idx); - wk.idk_keyix = key_idx; - } - return set80211var(drv, IEEE80211_IOC_DELKEY, &wk, sizeof(wk)); -} - -static int -wpa_driver_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 wpa_driver_bsd_data *drv = priv; - struct ieee80211req_key wk; - struct ether_addr ea; - char *alg_name; - u_int8_t cipher; - - if (alg == WPA_ALG_NONE) - return wpa_driver_bsd_del_key(drv, key_idx, addr); - - switch (alg) { - case WPA_ALG_WEP: - alg_name = "WEP"; - cipher = IEEE80211_CIPHER_WEP; - break; - case WPA_ALG_TKIP: - alg_name = "TKIP"; - cipher = IEEE80211_CIPHER_TKIP; - break; - case WPA_ALG_CCMP: - alg_name = "CCMP"; - cipher = IEEE80211_CIPHER_AES_CCM; - break; - default: - wpa_printf(MSG_DEBUG, "%s: unknown/unsupported algorithm %d", - __func__, alg); - return -1; - } - - memcpy(&ea, addr, IEEE80211_ADDR_LEN); - wpa_printf(MSG_DEBUG, - "%s: alg=%s addr=%s key_idx=%d set_tx=%d seq_len=%zu key_len=%zu", - __func__, alg_name, ether_ntoa(&ea), key_idx, set_tx, - seq_len, key_len); - - if (seq_len > sizeof(u_int64_t)) { - wpa_printf(MSG_DEBUG, "%s: seq_len %zu too big", - __func__, seq_len); - return -2; - } - if (key_len > sizeof(wk.ik_keydata)) { - wpa_printf(MSG_DEBUG, "%s: key length %zu too big", - __func__, key_len); - return -3; - } - - memset(&wk, 0, sizeof(wk)); - wk.ik_type = cipher; - wk.ik_flags = IEEE80211_KEY_RECV; - if (set_tx) - wk.ik_flags |= IEEE80211_KEY_XMIT; - 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 (bcmp(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; - /* - * Ignore replay failures in IBSS and AHDEMO mode. - */ - if (drv->opmode == IEEE80211_M_IBSS || - drv->opmode == IEEE80211_M_AHDEMO) - wk.ik_flags |= IEEE80211_KEY_NOREPLAY; - wk.ik_keylen = key_len; - memcpy(&wk.ik_keyrsc, seq, seq_len); - wk.ik_keyrsc = le64toh(wk.ik_keyrsc); - memcpy(wk.ik_keydata, key, key_len); - - return set80211var(drv, IEEE80211_IOC_WPAKEY, &wk, sizeof(wk)); -} - -static int -wpa_driver_bsd_set_countermeasures(void *priv, int enabled) -{ - struct wpa_driver_bsd_data *drv = priv; - - wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled); - return set80211param(drv, IEEE80211_IOC_COUNTERMEASURES, enabled); -} - - -static int -wpa_driver_bsd_set_drop_unencrypted(void *priv, int enabled) -{ - struct wpa_driver_bsd_data *drv = priv; - - wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled); - return set80211param(drv, IEEE80211_IOC_DROPUNENCRYPTED, enabled); -} - -static int -wpa_driver_bsd_set_auth_alg(void *priv, int auth_alg) -{ - struct wpa_driver_bsd_data *drv = priv; - int authmode; - - if ((auth_alg & WPA_AUTH_ALG_OPEN) && - (auth_alg & WPA_AUTH_ALG_SHARED)) - authmode = IEEE80211_AUTH_AUTO; - else if (auth_alg & WPA_AUTH_ALG_SHARED) - authmode = IEEE80211_AUTH_SHARED; - else - authmode = IEEE80211_AUTH_OPEN; - - wpa_printf(MSG_DEBUG, "%s alg 0x%x authmode %u", - __func__, auth_alg, authmode); - - return set80211param(drv, IEEE80211_IOC_AUTHMODE, authmode); -} - -static int -wpa_driver_bsd_deauthenticate(void *priv, const u8 *addr, int reason_code) -{ - struct wpa_driver_bsd_data *drv = priv; - struct ieee80211req_mlme mlme; - - drv->lastssid_len = 0; - - wpa_printf(MSG_DEBUG, "%s", __func__); - memset(&mlme, 0, sizeof(mlme)); - mlme.im_op = IEEE80211_MLME_DEAUTH; - mlme.im_reason = reason_code; - memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); - return set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)); -} - -static int -wpa_driver_bsd_disassociate(void *priv, const u8 *addr, int reason_code) -{ - struct wpa_driver_bsd_data *drv = priv; - struct ieee80211req_mlme mlme; - - drv->lastssid_len = 0; - - wpa_printf(MSG_DEBUG, "%s", __func__); - memset(&mlme, 0, sizeof(mlme)); - mlme.im_op = IEEE80211_MLME_DISASSOC; - mlme.im_reason = reason_code; - memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN); - return set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)); -} - -static int -wpa_driver_bsd_associate(void *priv, struct wpa_driver_associate_params *params) -{ - struct wpa_driver_bsd_data *drv = priv; - struct ieee80211req_mlme mlme; - int flags, privacy; - - wpa_printf(MSG_DEBUG, - "%s: ssid '%.*s' wpa ie len %u pairwise %u group %u key mgmt %u" - , __func__ - , params->ssid_len, params->ssid - , params->wpa_ie_len - , params->pairwise_suite - , params->group_suite - , params->key_mgmt_suite - ); - - /* NB: interface must be marked UP to associate */ - if (getifflags(drv, &flags) != 0) { - wpa_printf(MSG_DEBUG, "%s did not mark interface UP", __func__); - return -1; - } - if ((flags & IFF_UP) == 0 && setifflags(drv, flags | IFF_UP) != 0) { - wpa_printf(MSG_DEBUG, "%s unable to mark interface UP", - __func__); - return -1; - } - - if (wpa_driver_bsd_set_drop_unencrypted(drv, params->drop_unencrypted) - < 0) - return -1; - if (wpa_driver_bsd_set_auth_alg(drv, params->auth_alg) < 0) - return -1; - /* XXX error handling is wrong but unclear what to do... */ - if (wpa_driver_bsd_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0) - return -1; - - privacy = !(params->pairwise_suite == CIPHER_NONE && - params->group_suite == CIPHER_NONE && - params->key_mgmt_suite == KEY_MGMT_NONE && - params->wpa_ie_len == 0); - wpa_printf(MSG_DEBUG, "%s: set PRIVACY %u", __func__, privacy); - - if (set80211param(drv, IEEE80211_IOC_PRIVACY, privacy) < 0) - return -1; - - if (params->wpa_ie_len && - set80211param(drv, IEEE80211_IOC_WPA, - params->wpa_ie[0] == WLAN_EID_RSN ? 2 : 1) < 0) - return -1; - - memset(&mlme, 0, sizeof(mlme)); - mlme.im_op = IEEE80211_MLME_ASSOC; - if (params->ssid != NULL) - memcpy(mlme.im_ssid, params->ssid, params->ssid_len); - mlme.im_ssid_len = params->ssid_len; - if (params->bssid != NULL) - memcpy(mlme.im_macaddr, params->bssid, IEEE80211_ADDR_LEN); - if (set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)) < 0) - return -1; - memcpy(drv->lastssid, params->ssid, params->ssid_len); - drv->lastssid_len = params->ssid_len; - return 0; -} - -static int -wpa_driver_bsd_scan(void *priv, struct wpa_driver_scan_params *params) -{ - struct wpa_driver_bsd_data *drv = priv; - struct ieee80211_scan_req sr; - int i; - int flags; - - /* XXX not true but easiest to perpetuate the myth */ - /* NB: interface must be marked UP to do a scan */ - if (getifflags(drv, &flags) != 0) { - wpa_printf(MSG_DEBUG, "%s did not mark interface UP", __func__); - return -1; - } - if ((flags & IFF_UP) == 0 && setifflags(drv, flags | IFF_UP) != 0) { - wpa_printf(MSG_DEBUG, "%s unable to mark interface UP", - __func__); - return -1; - } - - memset(&sr, 0, sizeof(sr)); - sr.sr_flags = IEEE80211_IOC_SCAN_ACTIVE - | IEEE80211_IOC_SCAN_ONCE - | IEEE80211_IOC_SCAN_NOJOIN - ; - sr.sr_duration = IEEE80211_IOC_SCAN_FOREVER; - if (params->num_ssids > 0) { - sr.sr_nssid = params->num_ssids; -#if 0 - /* Boundary check is done by upper layer */ - if (sr.sr_nssid > IEEE80211_IOC_SCAN_MAX_SSID) - sr.sr_nssid = IEEE80211_IOC_SCAN_MAX_SSID; -#endif - /* NB: check scan cache first */ - sr.sr_flags |= IEEE80211_IOC_SCAN_CHECK; -} - for (i = 0; i < sr.sr_nssid; i++) { - sr.sr_ssid[i].len = params->ssids[i].ssid_len; - os_memcpy(sr.sr_ssid[i].ssid, params->ssids[i].ssid, - sr.sr_ssid[i].len); - } - /* NB: net80211 delivers a scan complete event so no need to poll */ - return set80211var(drv, IEEE80211_IOC_SCAN_REQ, &sr, sizeof(sr)); -} - -#include <net/route.h> -#include <net80211/ieee80211_freebsd.h> - -static void -wpa_driver_bsd_event_receive(int sock, void *ctx, void *sock_ctx) -{ - struct wpa_driver_bsd_data *drv = sock_ctx; - char buf[2048]; - struct if_announcemsghdr *ifan; - struct if_msghdr *ifm; - struct rt_msghdr *rtm; - union wpa_event_data event; - struct ieee80211_michael_event *mic; - int n; - - 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; - } - memset(&event, 0, sizeof(event)); - switch (rtm->rtm_type) { - case RTM_IFANNOUNCE: - ifan = (struct if_announcemsghdr *) rtm; - if (ifan->ifan_index != drv->ifindex) - break; - strlcpy(event.interface_status.ifname, drv->ifname, - sizeof(event.interface_status.ifname)); - switch (ifan->ifan_what) { - case IFAN_DEPARTURE: - event.interface_status.ievent = EVENT_INTERFACE_REMOVED; - default: - return; - } - wpa_printf(MSG_DEBUG, "RTM_IFANNOUNCE: Interface '%s' %s", - event.interface_status.ifname, - ifan->ifan_what == IFAN_DEPARTURE ? - "removed" : "added"); - wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event); - break; - case RTM_IEEE80211: - ifan = (struct if_announcemsghdr *) rtm; - if (ifan->ifan_index != drv->ifindex) - break; - switch (ifan->ifan_what) { - case RTM_IEEE80211_ASSOC: - case RTM_IEEE80211_REASSOC: - wpa_supplicant_event(ctx, EVENT_ASSOC, NULL); - break; - case RTM_IEEE80211_DISASSOC: - wpa_supplicant_event(ctx, EVENT_DISASSOC, NULL); - break; - case RTM_IEEE80211_SCAN: - wpa_supplicant_event(ctx, EVENT_SCAN_RESULTS, NULL); - 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)); - - memset(&event, 0, sizeof(event)); - event.michael_mic_failure.unicast = - !IEEE80211_IS_MULTICAST(mic->iev_dst); - wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, - &event); - break; - } - break; - case RTM_IFINFO: - ifm = (struct if_msghdr *) rtm; - if (ifm->ifm_index != drv->ifindex) - break; - if ((rtm->rtm_flags & RTF_UP) == 0) { - strlcpy(event.interface_status.ifname, drv->ifname, - sizeof(event.interface_status.ifname)); - event.interface_status.ievent = EVENT_INTERFACE_REMOVED; - wpa_printf(MSG_DEBUG, "RTM_IFINFO: Interface '%s' DOWN", - event.interface_status.ifname); - wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event); - } - break; - } -} - -static int -getmaxrate(const uint8_t rates[15], uint8_t nrates) -{ - int i, maxrate = -1; - - for (i = 0; i < nrates; i++) { - int rate = rates[i] & IEEE80211_RATE_VAL; - if (rate > maxrate) - rate = maxrate; - } - return maxrate; -} - -/* unalligned little endian access */ -#define LE_READ_4(p) \ - ((u_int32_t) \ - ((((const u_int8_t *)(p))[0] ) | \ - (((const u_int8_t *)(p))[1] << 8) | \ - (((const u_int8_t *)(p))[2] << 16) | \ - (((const u_int8_t *)(p))[3] << 24))) - -static int __inline -iswpaoui(const u_int8_t *frm) -{ - return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI); -} - - -static void -wpa_driver_bsd_add_scan_entry(struct wpa_scan_results *res, - struct ieee80211req_scan_result *sr) -{ - struct wpa_scan_res *result, **tmp; - size_t extra_len; - u8 *pos; - - extra_len = 2 + sr->isr_ssid_len; - extra_len += 2 + sr->isr_nrates; - extra_len += 3; /* ERP IE */ - extra_len += sr->isr_ie_len; - - result = os_zalloc(sizeof(*result) + extra_len); - if (result == NULL) - return; - os_memcpy(result->bssid, sr->isr_bssid, ETH_ALEN); - result->freq = sr->isr_freq; - result->beacon_int = sr->isr_intval; - result->caps = sr->isr_capinfo; - result->qual = sr->isr_rssi; - result->noise = sr->isr_noise; - /* - * the rssi value reported by the kernel is in 0.5dB steps relative to - * the reported noise floor. see ieee80211_node.h for details. - */ - result->level = sr->isr_rssi / 2 + sr->isr_noise; - - pos = (u8 *)(result + 1); - - *pos++ = WLAN_EID_SSID; - *pos++ = sr->isr_ssid_len; - os_memcpy(pos, sr + 1, sr->isr_ssid_len); - pos += sr->isr_ssid_len; - - /* - * Deal all rates as supported rate. - * Because net80211 doesn't report extended supported rate or not. - */ - *pos++ = WLAN_EID_SUPP_RATES; - *pos++ = sr->isr_nrates; - os_memcpy(pos, sr->isr_rates, sr->isr_nrates); - pos += sr->isr_nrates; - - *pos++ = WLAN_EID_ERP_INFO; - *pos++ = 1; - *pos++ = sr->isr_erp; - - os_memcpy(pos, (u8 *)(sr + 1) + sr->isr_ssid_len, sr->isr_ie_len); - pos += sr->isr_ie_len; - - result->ie_len = pos - (u8 *)(result + 1); - - tmp = os_realloc(res->res, - (res->num + 1) * sizeof(struct wpa_scan_res *)); - if (tmp == NULL) { - os_free(result); - return; - } - tmp[res->num++] = result; - res->res = tmp; -} - -static struct wpa_scan_results * -wpa_driver_bsd_get_scan_results2(void *priv) -{ - struct ieee80211req_scan_result *sr; - struct wpa_scan_results *res; - int len, rest; - uint8_t buf[24*1024], *pos; - - len = get80211var(priv, IEEE80211_IOC_SCAN_RESULTS, buf, 24*1024); - if (len < 0) - return NULL; - - res = os_zalloc(sizeof(*res)); - if (res == NULL) - return NULL; - - pos = buf; - rest = len; - while (rest >= sizeof(struct ieee80211req_scan_result)) { - sr = (struct ieee80211req_scan_result *)pos; - wpa_driver_bsd_add_scan_entry(res, sr); - pos += sr->isr_len; - rest -= sr->isr_len; - } - - wpa_printf(MSG_DEBUG, "Received %d bytes of scan results (%lu BSSes)", - len, (unsigned long)res->num); - - return (res); -} - - -#define GETPARAM(drv, param, v) \ - (((v) = get80211param(drv, param)) != -1) -#define IEEE80211_C_BGSCAN 0x20000000 - -/* - * Set the scan cache valid threshold to 1.5 x bg scan interval - * to force all scan requests to consult the cache unless they - * explicitly bypass it. - */ -static int -setscanvalid(struct wpa_driver_bsd_data *drv) -{ - int bgscan, scanvalid; - - if (!GETPARAM(drv, IEEE80211_IOC_SCANVALID, drv->prev_scanvalid) || - !GETPARAM(drv, IEEE80211_IOC_BGSCAN_INTERVAL, bgscan)) - return -1; - scanvalid = 3*bgscan/2; - return (drv->prev_scanvalid < scanvalid) ? - set80211param(drv, IEEE80211_IOC_SCANVALID, scanvalid) : 0; -} - -static void * -wpa_driver_bsd_init(void *ctx, const char *ifname) -{ - struct wpa_driver_bsd_data *drv; - struct ieee80211_devcaps_req devcaps; - int flags; - - drv = malloc(sizeof(*drv)); - if (drv == NULL) - return NULL; - memset(drv, 0, sizeof(*drv)); - /* - * 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. - */ - drv->ifindex = if_nametoindex(ifname); - if (drv->ifindex == 0) { - wpa_printf(MSG_DEBUG, "%s: interface %s does not exist", - __func__, ifname); - goto fail1; - } - drv->sock = socket(PF_INET, SOCK_DGRAM, 0); - if (drv->sock < 0) - goto fail1; - drv->ctx = ctx; - strncpy(drv->ifname, ifname, sizeof(drv->ifname)); - - /* - * Mark the interface as down to ensure wpa_supplicant has exclusive - * access to the net80211 state machine, do this before opening the - * route socket to avoid a false event that the interface disappeared. - */ - if (getifflags(drv, &flags) == 0) - (void) setifflags(drv, flags &~ IFF_UP); - - drv->route = socket(PF_ROUTE, SOCK_RAW, 0); - if (drv->route < 0) - goto fail; - eloop_register_read_sock(drv->route, - wpa_driver_bsd_event_receive, ctx, drv); - - if (get80211var(drv, IEEE80211_IOC_DEVCAPS, &devcaps, sizeof(devcaps)) < 0) { - wpa_printf(MSG_DEBUG, - "%s: failed to get device capabilities: %s", - __func__, strerror(errno)); - goto fail; - } - drv->drivercaps = devcaps.dc_drivercaps; - drv->cryptocaps = devcaps.dc_cryptocaps; - - if (!GETPARAM(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming)) { - wpa_printf(MSG_DEBUG, "%s: failed to get roaming state: %s", - __func__, strerror(errno)); - goto fail; - } - if (!GETPARAM(drv, IEEE80211_IOC_PRIVACY, drv->prev_privacy)) { - wpa_printf(MSG_DEBUG, "%s: failed to get privacy state: %s", - __func__, strerror(errno)); - goto fail; - } - if (!GETPARAM(drv, IEEE80211_IOC_WPA, drv->prev_wpa)) { - wpa_printf(MSG_DEBUG, "%s: failed to get wpa state: %s", - __func__, strerror(errno)); - goto fail; - } - if (set80211param(drv, IEEE80211_IOC_ROAMING, IEEE80211_ROAMING_MANUAL) < 0) { - wpa_printf(MSG_DEBUG, "%s: failed to set wpa_supplicant-based " - "roaming: %s", __func__, strerror(errno)); - goto fail; - } - if (drv->drivercaps & IEEE80211_C_BGSCAN) { - /* - * Driver does background scanning; force the scan valid - * setting to 1.5 x bg scan interval so the scan cache is - * always consulted before we force a foreground scan. - */ - if (setscanvalid(drv) < 0) { - wpa_printf(MSG_DEBUG, - "%s: warning, failed to set scanvalid, scanning " - "may be suboptimal: %s", __func__, strerror(errno)); - } - } - if (set80211param(drv, IEEE80211_IOC_WPA, 1+2) < 0) { - wpa_printf(MSG_DEBUG, "%s: failed to enable WPA support %s", - __func__, strerror(errno)); - goto fail; - } - drv->opmode = get80211opmode(drv); - - return drv; -fail: - close(drv->sock); -fail1: - free(drv); - return NULL; -} -#undef GETPARAM - -static void -wpa_driver_bsd_deinit(void *priv) -{ - struct wpa_driver_bsd_data *drv = priv; - int flags; - - /* NB: mark interface down */ - if (getifflags(drv, &flags) == 0) - (void) setifflags(drv, flags &~ IFF_UP); - - wpa_driver_bsd_set_wpa_internal(drv, drv->prev_wpa, drv->prev_privacy); - if (set80211param(drv, IEEE80211_IOC_ROAMING, drv->prev_roaming) < 0) { - /* NB: don't whinge if device ejected or equivalent */ - if (errno != ENXIO) - wpa_printf(MSG_DEBUG, "%s: failed to restore roaming " - "state", __func__); - } - if (drv->drivercaps & IEEE80211_C_BGSCAN) { - /* XXX check return value */ - (void) set80211param(drv, IEEE80211_IOC_SCANVALID, - drv->prev_scanvalid); - } - - (void) close(drv->route); /* ioctl socket */ - (void) close(drv->sock); /* event socket */ - free(drv); -} - - -struct wpa_driver_ops wpa_driver_bsd_ops = { - .name = "bsd", - .desc = "BSD 802.11 support (Atheros, etc.)", - .init = wpa_driver_bsd_init, - .deinit = wpa_driver_bsd_deinit, - .get_bssid = wpa_driver_bsd_get_bssid, - .get_ssid = wpa_driver_bsd_get_ssid, - .set_key = wpa_driver_bsd_set_key, - .set_countermeasures = wpa_driver_bsd_set_countermeasures, - .scan2 = wpa_driver_bsd_scan, - .get_scan_results2 = wpa_driver_bsd_get_scan_results2, - .deauthenticate = wpa_driver_bsd_deauthenticate, - .disassociate = wpa_driver_bsd_disassociate, - .associate = wpa_driver_bsd_associate, -}; |