summaryrefslogtreecommitdiffstats
path: root/usr.sbin/wpa
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/wpa')
-rw-r--r--usr.sbin/wpa/Makefile7
-rw-r--r--usr.sbin/wpa/Makefile.inc27
-rw-r--r--usr.sbin/wpa/hostapd/Makefile128
-rw-r--r--usr.sbin/wpa/hostapd/driver_freebsd.c787
-rw-r--r--usr.sbin/wpa/hostapd/hostapd.8134
-rw-r--r--usr.sbin/wpa/hostapd/hostapd.conf.5210
-rw-r--r--usr.sbin/wpa/hostapd_cli/Makefile15
-rw-r--r--usr.sbin/wpa/hostapd_cli/hostapd_cli.8112
-rw-r--r--usr.sbin/wpa/ndis_events/Makefile8
-rw-r--r--usr.sbin/wpa/ndis_events/ndis_events.8135
-rw-r--r--usr.sbin/wpa/ndis_events/ndis_events.c354
-rw-r--r--usr.sbin/wpa/wpa_cli/Makefile21
-rw-r--r--usr.sbin/wpa/wpa_cli/wpa_cli.8222
-rw-r--r--usr.sbin/wpa/wpa_passphrase/Makefile16
-rw-r--r--usr.sbin/wpa/wpa_passphrase/wpa_passphrase.866
-rw-r--r--usr.sbin/wpa/wpa_supplicant/Makefile154
-rw-r--r--usr.sbin/wpa/wpa_supplicant/Packet32.c415
-rw-r--r--usr.sbin/wpa/wpa_supplicant/Packet32.h67
-rw-r--r--usr.sbin/wpa/wpa_supplicant/driver_freebsd.c929
-rw-r--r--usr.sbin/wpa/wpa_supplicant/ntddndis.h31
-rw-r--r--usr.sbin/wpa/wpa_supplicant/wpa_supplicant.8155
-rw-r--r--usr.sbin/wpa/wpa_supplicant/wpa_supplicant.conf.5578
22 files changed, 4571 insertions, 0 deletions
diff --git a/usr.sbin/wpa/Makefile b/usr.sbin/wpa/Makefile
new file mode 100644
index 0000000..5d746e9
--- /dev/null
+++ b/usr.sbin/wpa/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+SUBDIR= wpa_supplicant wpa_cli wpa_passphrase
+SUBDIR+= hostapd hostapd_cli
+SUBDIR+= ndis_events
+
+.include <bsd.subdir.mk>
diff --git a/usr.sbin/wpa/Makefile.inc b/usr.sbin/wpa/Makefile.inc
new file mode 100644
index 0000000..2f9b9ce
--- /dev/null
+++ b/usr.sbin/wpa/Makefile.inc
@@ -0,0 +1,27 @@
+# $FreeBSD$
+
+BINDIR?= /usr/sbin
+
+WPA_DISTDIR?= ${.CURDIR}/../../../contrib/wpa/
+WPA_SUPPLICANT_DISTDIR?=${WPA_DISTDIR}/wpa_supplicant
+HOSTAPD_DISTDIR?= ${WPA_DISTDIR}/hostapd
+
+.PATH.c:${.CURDIR}/.. \
+ ${WPA_DISTDIR}/src/common \
+ ${WPA_DISTDIR}/src/crypto \
+ ${WPA_DISTDIR}/src/eap_common \
+ ${WPA_DISTDIR}/src/eapol_supp \
+ ${WPA_DISTDIR}/src/l2_packet \
+ ${WPA_DISTDIR}/src/utils
+
+CFLAGS+=-I${.CURDIR}
+CFLAGS+=-I${WPA_DISTDIR}/src
+CFLAGS+=-I${WPA_DISTDIR}/src/common
+CFLAGS+=-I${WPA_DISTDIR}/src/crypto
+CFLAGS+=-I${WPA_DISTDIR}/src/l2_packet
+CFLAGS+=-I${WPA_DISTDIR}/src/utils
+
+CFLAGS+= -DCONFIG_CTRL_IFACE
+CFLAGS+= -DCONFIG_CTRL_IFACE_UNIX
+
+.include <bsd.own.mk>
diff --git a/usr.sbin/wpa/hostapd/Makefile b/usr.sbin/wpa/hostapd/Makefile
new file mode 100644
index 0000000..55a1e06
--- /dev/null
+++ b/usr.sbin/wpa/hostapd/Makefile
@@ -0,0 +1,128 @@
+# $FreeBSD$
+
+.include "${.CURDIR}/../Makefile.inc"
+
+.PATH.c:${HOSTAPD_DISTDIR} \
+ ${WPA_DISTDIR}/src/ap \
+ ${WPA_DISTDIR}/src/eap_server \
+ ${WPA_DISTDIR}/src/eap_common \
+ ${WPA_DISTDIR}/src/eapol_auth \
+ ${WPA_DISTDIR}/src/drivers \
+ ${WPA_DISTDIR}/src/radius \
+ ${WPA_DISTDIR}
+
+PROG= hostapd
+SRCS= accounting.c aes-wrap.c ap_config.c \
+ ap_drv_ops.c ap_mlme.c authsrv.c \
+ chap.c common.c config_file.c ctrl_iface.c crypto_openssl.c \
+ ctrl_iface_ap.c drivers.c drv_callbacks.c dump_state.c \
+ eap_common.c eap_peap_common.c eap_register.c eap_server.c \
+ eap_server_gtc.c eap_server_identity.c eap_server_md5.c \
+ eap_server_methods.c eap_server_mschapv2.c eap_server_peap.c \
+ eap_server_tls.c eap_server_tls_common.c eap_server_ttls.c \
+ eapol_auth_dump.c eapol_auth_sm.c eloop.c hostapd.c ieee802_11_auth.c \
+ ieee802_11_common.c ieee802_11_ht.c ieee802_1x.c ip_addr.c \
+ md5.c main.c ms_funcs.c peerkey_auth.c pmksa_cache_auth.c \
+ preauth_auth.c radius.c radius_client.c sta_info.c \
+ sha1-pbkdf2.c sha1-tlsprf.c sha1-tprf.c sha1.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 os_unix.c
+
+MAN= hostapd.8 hostapd.conf.5
+
+.if ${MK_EXAMPLES} != "no"
+FILESDIR= ${SHAREDIR}/examples/hostapd
+.PATH: ${HOSTAPD_DISTDIR}
+FILES= hostapd.conf hostapd.eap_user hostapd.wpa_psk
+.endif
+
+CFLAGS+= -I${HOSTAPD_DISTDIR} -I${WPA_DISTDIR}/src/drivers
+
+CFLAGS+= -DCONFIG_DRIVER_BSD -DHOSTAPD
+CFLAGS+= -DCONFIG_DRIVER_RADIUS_ACL
+.if ${MK_INET6} != "no"
+CFLAGS+= -DCONFIG_IPV6
+.endif
+#CFLAGS+= -g
+DPADD+= ${LIBPCAP} ${LIBSSL}
+LDADD+= -lpcap -lssl
+
+# User customizations for wpa_supplicant/hostapd build environment
+CFLAGS+=${HOSTAPD_CFLAGS}
+#DPADD+=${HOSTAPD_DPADD}
+LDADD+=${HOSTAPD_LDADD}
+#LDFLAGS+=${HOSTAPD_LDFLAGS}
+
+.if !empty(CFLAGS:M*-DEAP_SERVER)
+#SRCS+= eap.c eap_methods.c eap_identity.c
+
+.if ${MK_OPENSSL} != "no" && !defined(RELEASE_CRUNCH)
+
+CFLAGS+=-DEAP_TLS -DEAP_PEAP -DEAP_MSCHAPv2 -DEAP_PSK \
+ -DEAP_TLS_FUNCS -DEAP_TLS_OPENSSL
+SRCS+= crypto_openssl.c
+SRCS+= eap_tls.c eap_peap.c eap_peap_common.c eap_mschapv2.c \
+ eap_psk.c eap_psk_common.c \
+ eap_tls_common.c tls_openssl.c ms_funcs.c chap.c
+
+CFLAGS+=-DEAP_TTLS -DEAP_MD5
+SRCS+= eap_ttls.c eap_md5.c
+
+.if !empty(CFLAGS:M*-DEAP_GTC)
+SRCS+= eap_gtc.c
+.endif
+
+.if !empty(CFLAGS:M*-DEAP_AKA)
+NEED_SIM_COMMON= true
+SRCS+= eap_aka.c
+.endif
+
+.if !empty(CFLAGS:M*-DEAP_SIM)
+NEED_SIM_COMMON= true
+SRCS+= eap_sim.c
+.endif
+
+.if defined(NEED_SIM_COMMON)
+SRCS+= eap_sim_common.c eap_sim_db.c
+.endif
+
+.if !empty(CFLAGS:M*-DEAP_GPSK)
+CFLAGS+=-DEAP_GPSK_SHA256
+SRCS+= eap_gpsk.c eap_gpsk_common.c
+NEED_SHA256= true
+.endif
+
+.if !empty(CFLAGS:M*-DEAP_PAX)
+SRCS+= eap_pax.c eap_pax_common.c
+.endif
+
+.if !empty(CFLAGS:M*-DEAP_SAKE)
+SRCS+= eap_sake.c eap_sake_common.c
+.endif
+
+DPADD+= ${LIBSSL} ${LIBCRYPTO}
+LDADD+= -lssl -lcrypto
+.else
+NEED_TLS_NONE= true
+.endif
+
+.else
+NEED_TLS_NONE= true
+.endif
+
+.if defined(NEED_SHA256)
+CFLAGS+=-DINTERNAL_SHA256
+SRCS+= sha256.c
+.endif
+
+.if defined(NEED_TLS_NONE)
+CFLAGS+= -DEAP_TLS_NONE
+CFLAGS+= -DINTERNAL_AES
+CFLAGS+= -DINTERNAL_SHA1
+CFLAGS+= -DINTERNAL_MD5
+SRCS+= tls_none.c
+.endif
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/wpa/hostapd/driver_freebsd.c b/usr.sbin/wpa/hostapd/driver_freebsd.c
new file mode 100644
index 0000000..5fb6f85
--- /dev/null
+++ b/usr.sbin/wpa/hostapd/driver_freebsd.c
@@ -0,0 +1,787 @@
+/*
+ * 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 unecessary
+ */
+ 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/hostapd.8 b/usr.sbin/wpa/hostapd/hostapd.8
new file mode 100644
index 0000000..7fb14d3
--- /dev/null
+++ b/usr.sbin/wpa/hostapd/hostapd.8
@@ -0,0 +1,134 @@
+.\" Copyright (c) 2005 Sam Leffler <sam@errno.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd October 26, 2007
+.Dt HOSTAPD 8
+.Os
+.Sh NAME
+.Nm hostapd
+.Nd "authenticator for IEEE 802.11 networks"
+.Sh SYNOPSIS
+.Nm
+.Op Fl BdhKtv
+.Op Fl P Ar pidfile
+.Ar config-file ...
+.Sh DESCRIPTION
+The
+.Nm
+utility
+is an authenticator for IEEE 802.11 networks.
+It provides full support for WPA/IEEE 802.11i and
+can also act as an IEEE 802.1X Authenticator with a suitable
+backend Authentication Server (typically
+.Tn FreeRADIUS ) .
+The
+.Nm
+utility
+implements the authentication protocols that piggyback on top
+of the normal IEEE 802.11 protocol mechanisms.
+To use
+.Nm
+as an authenticator, the underlying device must support some
+basic functionality such as the ability to set security information
+in the 802.11 management frames.
+Beware that not all devices have this support.
+.Pp
+The
+.Nm
+utility
+is designed to be a
+.Dq daemon
+program that runs in the
+background and acts as the backend component controlling
+the wireless connection.
+It supports separate frontend programs such as the
+text-based frontend,
+.Xr hostapd_cli 8 .
+.Pp
+The following arguments must be specified on the command line:
+.Bl -tag -width indent
+.It Ar config-file
+Use the settings in the specified configuration file; the name of
+the specified wireless interface is contained in this file.
+See
+.Xr hostapd.conf 5
+for a description of the configuration file syntax.
+.Pp
+Changes to the configuration file can be reloaded by sending a
+.Dv SIGHUP
+to the
+.Nm
+processor or with the
+.Xr hostapd_cli 8
+utility, using
+.Dq Li "hostapd_cli reconfigure" .
+.El
+.Sh OPTIONS
+The options are as follows:
+.Bl -tag -width indent
+.It Fl d
+Enable debugging messages.
+If this option is supplied twice, more verbose messages are displayed.
+.It Fl h
+Show help text.
+.It Fl t
+Include timestamps in debugging output.
+.It Fl v
+Display version information on the terminal and exit.
+.It Fl B
+Detach from the controlling terminal and run as a daemon process
+in the background.
+.It Fl K
+Include key information in debugging output.
+.It Fl P Ar pidfile
+Store PID in
+.Ar pidfile .
+.El
+.Sh SEE ALSO
+.Xr ath 4 ,
+.Xr ipw 4 ,
+.Xr iwi 4 ,
+.Xr ral 4 ,
+.Xr ural 4 ,
+.Xr wi 4 ,
+.Xr hostapd.conf 5 ,
+.Xr hostapd_cli 8 ,
+.Xr ifconfig 8
+.Sh HISTORY
+The
+.Nm
+utility first appeared in
+.Fx 6.0 .
+.Sh AUTHORS
+The
+.Nm
+utility was written by
+.An Jouni Malinen Aq j@w1.fi .
+This manual page is derived from the
+.Pa README
+file included in the
+.Nm
+distribution.
diff --git a/usr.sbin/wpa/hostapd/hostapd.conf.5 b/usr.sbin/wpa/hostapd/hostapd.conf.5
new file mode 100644
index 0000000..a460801
--- /dev/null
+++ b/usr.sbin/wpa/hostapd/hostapd.conf.5
@@ -0,0 +1,210 @@
+.\" Copyright (c) 2005 Sam Leffler <sam@errno.com>
+.\" Copyright (c) 2006 Rui Paulo
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd September 2, 2006
+.Dt HOSTAPD.CONF 5
+.Os
+.Sh NAME
+.Nm hostapd.conf
+.Nd configuration file for
+.Xr hostapd 8
+utility
+.Sh DESCRIPTION
+The
+.Xr hostapd 8
+utility
+is an authenticator for IEEE 802.11 networks.
+It provides full support for WPA/IEEE 802.11i and
+can also act as an IEEE 802.1X Authenticator with a suitable
+backend Authentication Server (typically
+.Tn FreeRADIUS ) .
+.Pp
+The configuration file consists of global parameters and domain
+specific configuration:
+.Bl -bullet -offset indent -compact
+.It
+IEEE 802.1X-2004
+.\" XXX not yet
+.\" .It
+.\" Integrated EAP server
+.\" .It
+.\" IEEE 802.11f - Inter-Access Point Protocol (IAPP)
+.It
+RADIUS client
+.It
+RADIUS authentication server
+.It
+WPA/IEEE 802.11i
+.El
+.Sh GLOBAL PARAMETERS
+The following parameters are recognized:
+.Bl -tag -width indent
+.It Va interface
+Interface name.
+Should be set in
+.Dq hostap
+mode.
+.It Va debug
+Debugging mode: 0 = no, 1 = minimal, 2 = verbose, 3 = msg dumps, 4 =
+excessive.
+.It Va dump_file
+Dump file for state information (on
+.Dv SIGUSR1 ) .
+.It Va ctrl_interface
+The pathname of the directory in which
+.Xr hostapd 8
+creates
+.Ux
+domain socket files for communication
+with frontend programs such as
+.Xr hostapd_cli 8 .
+.It Va ctrl_interface_group
+A group name or group ID to use in setting protection on the
+control interface file.
+This can be set to allow non-root users to access the
+control interface files.
+If no group is specified, the group ID of the control interface
+is not modified and will, typically, be the
+group ID of the directory in which the socket is created.
+.El
+.Sh IEEE 802.1X-2004 PARAMETERS
+The following parameters are recognized:
+.Bl -tag -width indent
+.It Va ieee8021x
+Require IEEE 802.1X authorization.
+.It Va eap_message
+Optional displayable message sent with EAP Request-Identity.
+.It Va wep_key_len_broadcast
+Key lengths for broadcast keys.
+.It Va wep_key_len_unicast
+Key lengths for unicast keys.
+.It Va wep_rekey_period
+Rekeying period in seconds.
+.It Va eapol_key_index_workaround
+EAPOL-Key index workaround (set bit7) for WinXP Supplicant.
+.It Va eap_reauth_period
+EAP reauthentication period in seconds.
+To disable reauthentication,
+use
+.Dq 0 .
+.\" XXX not yet
+.\" .It Va use_pae_group_addr
+.El
+.\" XXX not yet
+.\" .Sh IEEE 802.11f - IAPP PARAMETERS
+.\" The following parameters are recognized:
+.\" .Bl -tag -width indent
+.\" .It Va iapp_interface
+.\" Interface to be used for IAPP broadcast packets
+.\" .El
+.Sh RADIUS CLIENT PARAMETERS
+The following parameters are recognized:
+.Bl -tag -width indent
+.It Va own_ip_addr
+The own IP address of the access point (used as NAS-IP-Address).
+.It Va nas_identifier
+Optional NAS-Identifier string for RADIUS messages.
+.It Va auth_server_addr , auth_server_port , auth_server_shared_secret
+RADIUS authentication server parameters.
+Can be defined twice for secondary servers to be used if primary one
+does not reply to RADIUS packets.
+.It Va acct_server_addr , acct_server_port , acct_server_shared_secret
+RADIUS accounting server parameters.
+Can be defined twice for secondary servers to be used if primary one
+does not reply to RADIUS packets.
+.It Va radius_retry_primary_interval
+Retry interval for trying to return to the primary RADIUS server (in
+seconds).
+.It Va radius_acct_interim_interval
+Interim accounting update interval.
+If this is set (larger than 0) and acct_server is configured,
+.Xr hostapd 8
+will send interim accounting updates every N seconds.
+.El
+.Sh RADIUS AUTHENTICATION SERVER PARAMETERS
+The following parameters are recognized:
+.Bl -tag -width indent
+.It Va radius_server_clients
+File name of the RADIUS clients configuration for the RADIUS server.
+If this is commented out, RADIUS server is disabled.
+.It Va radius_server_auth_port
+The UDP port number for the RADIUS authentication server.
+.It Va radius_server_ipv6
+Use IPv6 with RADIUS server.
+.El
+.Sh WPA/IEEE 802.11i PARAMETERS
+The following parameters are recognized:
+.Bl -tag -width indent
+.It Va wpa
+Enable WPA.
+Setting this variable configures the AP to require WPA (either
+WPA-PSK or WPA-RADIUS/EAP based on other configuration).
+.It Va wpa_psk , wpa_passphrase
+WPA pre-shared keys for WPA-PSK.
+This can be either entered as a 256-bit secret in hex format (64 hex
+digits), wpa_psk, or as an ASCII passphrase (8..63 characters) that
+will be converted to PSK.
+This conversion uses SSID so the PSK changes when ASCII passphrase is
+used and the SSID is changed.
+.It Va wpa_psk_file
+Optionally, WPA PSKs can be read from a separate text file (containing a
+list of (PSK,MAC address) pairs.
+.It Va wpa_key_mgmt
+Set of accepted key management algorithms (WPA-PSK, WPA-EAP, or both).
+.It Va wpa_pairwise
+Set of accepted cipher suites (encryption algorithms) for pairwise keys
+(unicast packets).
+See the example file for more information.
+.It Va wpa_group_rekey
+Time interval for rekeying GTK (broadcast/multicast encryption keys) in
+seconds.
+.It Va wpa_strict_rekey
+Rekey GTK when any STA that possesses the current GTK is leaving the
+BSS.
+.It Va wpa_gmk_rekey
+Time interval for rekeying GMK (master key used internally to generate GTKs),
+in seconds.
+.El
+.Sh SEE ALSO
+.Xr hostapd 8 ,
+.Xr hostapd_cli 8
+.Sh HISTORY
+The
+.Nm
+manual page and
+.Xr hostapd 8
+functionality first appeared in
+.Fx 6.0 .
+.Sh AUTHORS
+This manual page is derived from the
+.Pa README
+and
+.Pa hostapd.conf
+files in the
+.Nm hostapd
+distribution provided by
+.An Jouni Malinen Aq j@w1.fi .
diff --git a/usr.sbin/wpa/hostapd_cli/Makefile b/usr.sbin/wpa/hostapd_cli/Makefile
new file mode 100644
index 0000000..667134c
--- /dev/null
+++ b/usr.sbin/wpa/hostapd_cli/Makefile
@@ -0,0 +1,15 @@
+# $FreeBSD$
+
+.include "${.CURDIR}/../Makefile.inc"
+
+.PATH.c:${HOSTAPD_DISTDIR}
+
+PROG= hostapd_cli
+SRCS= hostapd_cli.c wpa_ctrl.c os_unix.c
+
+CFLAGS+= -DCONFIG_CTRL_IFACE
+CFLAGS+= -DCONFIG_CTRL_IFACE_UNIX
+
+MAN= hostapd_cli.8
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/wpa/hostapd_cli/hostapd_cli.8 b/usr.sbin/wpa/hostapd_cli/hostapd_cli.8
new file mode 100644
index 0000000..eb7f60f
--- /dev/null
+++ b/usr.sbin/wpa/hostapd_cli/hostapd_cli.8
@@ -0,0 +1,112 @@
+.\" Copyright (c) 2005 Sam Leffler <sam@errno.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd June 16, 2005
+.Dt HOSTAPD_CLI 8
+.Os
+.Sh NAME
+.Nm hostapd_cli
+.Nd text-based frontend program for interacting with
+.Xr hostapd 8
+.Sh SYNOPSIS
+.Nm
+.Op Ar commands
+.Sh DESCRIPTION
+The
+.Nm
+utility
+is a text-based frontend program for interacting with
+.Xr hostapd 8 .
+It is used to query the current status.
+.Pp
+The
+.Nm
+utility
+can show the
+current authentication status,
+dot11 and dot1x MIBs, etc.
+.Pp
+The
+.Nm
+utility
+supports two modes: interactive and command line.
+Both modes share the same command set.
+.Pp
+Interactive mode is started when
+.Nm
+is executed without any parameters on the command line.
+Commands are then entered from the controlling terminal in
+response to the
+.Nm
+prompt.
+In command line mode, the same commands are
+entered as command line arguments.
+.Sh COMMANDS
+The following commands may be supplied on the command line
+or at a prompt when operating interactively.
+.Bl -tag -width indent
+.It Ic mib
+Report MIB variables (dot1x, dot11) for the current interface.
+.It Ic sta Ar addr
+Report the MIB variables for the associated station with MAC address
+.Ar addr .
+.It Ic all_sta
+Report the MIB variables for all associated stations.
+.It Ic help
+Show usage help.
+.It Ic interface Op Ar ifname
+Show available interfaces and/or set the current interface
+when multiple are available.
+.It Ic level Ar debug_level
+Change the debugging level in
+.Xr hostapd 8 .
+Larger numbers generate more messages.
+.It Ic license
+Display the full
+license for
+.Nm .
+.It Ic quit
+Exit
+.Nm .
+.El
+.Sh SEE ALSO
+.Xr hostapd.conf 5 ,
+.Xr hostapd 8
+.Sh HISTORY
+The
+.Nm
+utility first appeared in
+.Fx 6.0 .
+.Sh AUTHORS
+The
+.Nm
+utility was written by
+.An Jouni Malinen Aq j@w1.fi .
+This manual page is derived from the
+.Pa README
+file included in the
+.Nm hostapd
+distribution.
diff --git a/usr.sbin/wpa/ndis_events/Makefile b/usr.sbin/wpa/ndis_events/Makefile
new file mode 100644
index 0000000..07caf5a
--- /dev/null
+++ b/usr.sbin/wpa/ndis_events/Makefile
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+PROG= ndis_events
+SRCS+= ndis_events.c
+
+MAN= ndis_events.8
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/wpa/ndis_events/ndis_events.8 b/usr.sbin/wpa/ndis_events/ndis_events.8
new file mode 100644
index 0000000..eacb017
--- /dev/null
+++ b/usr.sbin/wpa/ndis_events/ndis_events.8
@@ -0,0 +1,135 @@
+.\" Copyright (c) 2005
+.\" Bill Paul <wpaul@windriver.com> All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by Bill Paul.
+.\" 4. Neither the name of the author nor the names of any co-contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd August 30, 2007
+.Dt NDIS_EVENTS 8
+.Os
+.Sh NAME
+.Nm ndis_events
+.Nd relay events from
+.Xr ndis 4
+drivers to
+.Xr wpa_supplicant 8
+.Sh SYNOPSIS
+.Nm
+.Op Fl a
+.Op Fl d
+.Op Fl v
+.Sh DESCRIPTION
+The
+.Nm
+utility listens for events generated by an
+.Xr ndis 4
+wireless network driver and relays them to
+.Xr wpa_supplicant 8
+for possible processing.
+The three event types that can occur
+are media connect and disconnect events, such as when a wireless
+interface joins or leaves a network, and media-specific events.
+In particular,
+.Xr ndis 4
+drivers that support WPA2 will generate media-specific events
+containing PMKID candidate information which
+.Xr wpa_supplicant 8
+needs in order to properly associate with WPA2-capable access points.
+.Pp
+The
+.Nm
+daemon works by listening for interface information events via
+a routing socket.
+When it detects an event that was generated by an
+.Xr ndis 4
+interface, it transmits it via UDP packet on the loopback interface,
+where
+.Xr wpa_supplicant 8
+is presumeably listening.
+The standard
+.Xr wpa_supplicant 8
+distribution includes its own version of this utility for use with
+.Tn Windows\[rg] .
+The
+.Fx
+version performs the same functions as the
+.Tn Windows\[rg]
+one, except that it uses an
+.Xr ioctl 4
+and routing socket interface instead of WMI.
+.Pp
+Note that a single instance of
+.Nm
+is sufficient to scan for events for any number of
+.Xr ndis 4
+interfaces in a system.
+.Sh OPTIONS
+The
+.Nm
+daemon supports the following options:
+.Bl -tag -width indent
+.It Fl a
+Process all events.
+By default,
+.Nm
+will only process and forward media-specific events, which contain
+PMKID candidate information, and not bother forwarding connect and
+disconnect events, since
+.Xr wpa_supplicant 8
+normally can determine the current link state on its own.
+In some
+cases, the additional connect and disconnect events only confuse it
+and make the association and authentication process take longer.
+.It Fl d
+Run in debug mode.
+This causes
+.Nm
+to run in the foreground and generate any output to the standard
+error instead of using the
+.Xr syslog 3
+facility.
+.It Fl v
+Run in verbose mode.
+This causes
+.Nm
+to emit notifications when it receives events.
+.El
+.Sh SEE ALSO
+.Xr ndis 4 ,
+.Xr wpa_supplicant 8
+.Sh HISTORY
+The
+.Nm
+utility first appeared in
+.Fx 6.0 .
+.Sh AUTHORS
+The
+.Nm
+utility was written by
+.An Bill Paul Aq wpaul@windriver.com .
diff --git a/usr.sbin/wpa/ndis_events/ndis_events.c b/usr.sbin/wpa/ndis_events/ndis_events.c
new file mode 100644
index 0000000..e3cd9b5
--- /dev/null
+++ b/usr.sbin/wpa/ndis_events/ndis_events.c
@@ -0,0 +1,354 @@
+/*-
+ * Copyright (c) 2005
+ * Bill Paul <wpaul@windriver.com>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * This program simulates the behavior of the ndis_events utility
+ * supplied with wpa_supplicant for Windows. The original utility
+ * is designed to translate Windows WMI events. We don't have WMI,
+ * but we need to supply certain event info to wpa_supplicant in
+ * order to make WPA2 work correctly, so we fake up the interface.
+ */
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/errno.h>
+#include <sys/sysctl.h>
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_var.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <net/route.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <err.h>
+#include <syslog.h>
+#include <stdarg.h>
+
+static int verbose = 0;
+static int debug = 0;
+static int all_events = 0;
+
+#define PROGNAME "ndis_events"
+
+#define WPA_SUPPLICANT_PORT 9876
+#define NDIS_INDICATION_LEN 2048
+
+#define EVENT_CONNECT 0
+#define EVENT_DISCONNECT 1
+#define EVENT_MEDIA_SPECIFIC 2
+
+#define NDIS_STATUS_MEDIA_CONNECT 0x4001000B
+#define NDIS_STATUS_MEDIA_DISCONNECT 0x4001000C
+#define NDIS_STATUS_MEDIA_SPECIFIC_INDICATION 0x40010012
+
+struct ndis_evt {
+ uint32_t ne_sts;
+ uint32_t ne_len;
+#ifdef notdef
+ char ne_buf[1];
+#endif
+};
+
+static int find_ifname(int, char *);
+static int announce_event(char *, int, struct sockaddr_in *);
+static void usage(void);
+
+static void
+dbgmsg(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ if (debug)
+ vwarnx(fmt, ap);
+ else
+ vsyslog(LOG_ERR, fmt, ap);
+ va_end(ap);
+
+ return;
+}
+
+static int
+find_ifname(idx, name)
+ int idx;
+ char *name;
+{
+ int mib[6];
+ size_t needed;
+ struct if_msghdr *ifm;
+ struct sockaddr_dl *sdl;
+ char *buf, *lim, *next;
+
+ needed = 0;
+ mib[0] = CTL_NET;
+ mib[1] = PF_ROUTE;
+ mib[2] = 0; /* protocol */
+ mib[3] = 0; /* wildcard address family */
+ mib[4] = NET_RT_IFLIST;
+ mib[5] = 0; /* no flags */
+
+ if (sysctl (mib, 6, NULL, &needed, NULL, 0) < 0)
+ return(EIO);
+
+ buf = malloc (needed);
+ if (buf == NULL)
+ return(ENOMEM);
+
+ if (sysctl (mib, 6, buf, &needed, NULL, 0) < 0) {
+ free(buf);
+ return(EIO);
+ }
+
+ lim = buf + needed;
+
+ next = buf;
+ while (next < lim) {
+ ifm = (struct if_msghdr *)next;
+ if (ifm->ifm_type == RTM_IFINFO) {
+ sdl = (struct sockaddr_dl *)(ifm + 1);
+ if (ifm->ifm_index == idx) {
+ strncpy(name, sdl->sdl_data, sdl->sdl_nlen);
+ name[sdl->sdl_nlen] = '\0';
+ free (buf);
+ return (0);
+ }
+ }
+ next += ifm->ifm_msglen;
+ }
+
+ free (buf);
+
+ return(ENOENT);
+}
+
+static int
+announce_event(ifname, sock, dst)
+ char *ifname;
+ int sock;
+ struct sockaddr_in *dst;
+{
+ int s;
+ char indication[NDIS_INDICATION_LEN];
+ struct ifreq ifr;
+ struct ndis_evt *e;
+ char buf[512], *pos, *end;
+ int len, type, _type;
+
+ s = socket(PF_INET, SOCK_DGRAM, 0);
+
+ if (s < 0) {
+ dbgmsg("socket creation failed");
+ return(EINVAL);
+ }
+
+ bzero((char *)&ifr, sizeof(ifr));
+ e = (struct ndis_evt *)indication;
+ e->ne_len = NDIS_INDICATION_LEN - sizeof(struct ndis_evt);
+
+ strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
+ ifr.ifr_data = indication;
+
+ if (ioctl(s, SIOCGPRIVATE_0, &ifr) < 0) {
+ close(s);
+ if (verbose) {
+ if (errno == ENOENT)
+ dbgmsg("drained all events from %s",
+ ifname, errno);
+ else
+ dbgmsg("failed to read event info from %s: %d",
+ ifname, errno);
+ }
+ return(ENOENT);
+ }
+
+ if (e->ne_sts == NDIS_STATUS_MEDIA_CONNECT) {
+ type = EVENT_CONNECT;
+ if (verbose)
+ dbgmsg("Received a connect event for %s", ifname);
+ if (!all_events) {
+ close(s);
+ return(0);
+ }
+ }
+ if (e->ne_sts == NDIS_STATUS_MEDIA_DISCONNECT) {
+ type = EVENT_DISCONNECT;
+ if (verbose)
+ dbgmsg("Received a disconnect event for %s", ifname);
+ if (!all_events) {
+ close(s);
+ return(0);
+ }
+ }
+ if (e->ne_sts == NDIS_STATUS_MEDIA_SPECIFIC_INDICATION) {
+ type = EVENT_MEDIA_SPECIFIC;
+ if (verbose)
+ dbgmsg("Received a media-specific event for %s",
+ ifname);
+ }
+
+ end = buf + sizeof(buf);
+ _type = (int) type;
+ memcpy(buf, &_type, sizeof(_type));
+ pos = buf + sizeof(_type);
+
+ len = snprintf(pos + 1, end - pos - 1, "%s", ifname);
+ if (len < 0) {
+ close(s);
+ return(ENOSPC);
+ }
+ if (len > 255)
+ len = 255;
+ *pos = (unsigned char) len;
+ pos += 1 + len;
+ if (e->ne_len) {
+ if (e->ne_len > 255 || 1 + e->ne_len > end - pos) {
+ dbgmsg("Not enough room for send_event data (%d)\n",
+ e->ne_len);
+ close(s);
+ return(ENOSPC);
+ }
+ *pos++ = (unsigned char) e->ne_len;
+ memcpy(pos, (indication) + sizeof(struct ndis_evt), e->ne_len);
+ pos += e->ne_len;
+ }
+
+ len = sendto(sock, buf, pos - buf, 0, (struct sockaddr *) dst,
+ sizeof(struct sockaddr_in));
+
+ close(s);
+ return(0);
+}
+
+static void
+usage()
+{
+ fprintf(stderr, "Usage: ndis_events [-a] [-d] [-v]\n");
+ exit(1);
+}
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int s, r, n;
+ struct sockaddr_in sin;
+ char msg[NDIS_INDICATION_LEN];
+ struct rt_msghdr *rtm;
+ struct if_msghdr *ifm;
+ char ifname[IFNAMSIZ];
+ int ch;
+
+ while ((ch = getopt(argc, argv, "dva")) != -1) {
+ switch(ch) {
+ case 'd':
+ debug++;
+ break;
+ case 'v':
+ verbose++;
+ break;
+ case 'a':
+ all_events++;
+ break;
+ default:
+ usage();
+ break;
+ }
+ }
+
+ if (!debug && daemon(0, 0))
+ err(1, "failed to daemonize ourselves");
+
+ if (!debug)
+ openlog(PROGNAME, LOG_PID | LOG_CONS, LOG_DAEMON);
+
+ bzero((char *)&sin, sizeof(sin));
+
+ /* Create a datagram socket. */
+
+ s = socket(PF_INET, SOCK_DGRAM, 0);
+ if (s < 0) {
+ dbgmsg("socket creation failed");
+ exit(1);
+ }
+
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = inet_addr("127.0.0.1");
+ sin.sin_port = htons(WPA_SUPPLICANT_PORT);
+
+ /* Create a routing socket. */
+
+ r = socket (PF_ROUTE, SOCK_RAW, 0);
+ if (r < 0) {
+ dbgmsg("routing socket creation failed");
+ exit(1);
+ }
+
+ /* Now sit and spin, waiting for events. */
+
+ if (verbose)
+ dbgmsg("Listening for events");
+
+ while (1) {
+ n = read(r, msg, NDIS_INDICATION_LEN);
+ rtm = (struct rt_msghdr *)msg;
+ if (rtm->rtm_type != RTM_IFINFO)
+ continue;
+ ifm = (struct if_msghdr *)msg;
+ if (find_ifname(ifm->ifm_index, ifname))
+ continue;
+ if (strstr(ifname, "ndis")) {
+ while(announce_event(ifname, s, &sin) == 0)
+ ;
+ } else {
+ if (verbose)
+ dbgmsg("Skipping ifinfo message from %s",
+ ifname);
+ }
+ }
+
+ /* NOTREACHED */
+ exit(0);
+}
diff --git a/usr.sbin/wpa/wpa_cli/Makefile b/usr.sbin/wpa/wpa_cli/Makefile
new file mode 100644
index 0000000..1721437
--- /dev/null
+++ b/usr.sbin/wpa/wpa_cli/Makefile
@@ -0,0 +1,21 @@
+# $FreeBSD$
+
+.include "${.CURDIR}/../Makefile.inc"
+
+.PATH.c:${WPA_SUPPLICANT_DISTDIR}
+
+PROG= wpa_cli
+SRCS= wpa_cli.c wpa_ctrl.c os_unix.c
+
+MAN= wpa_cli.8
+
+CFLAGS+= -DCONFIG_CTRL_IFACE
+CFLAGS+= -DCONFIG_CTRL_IFACE_UNIX
+# enable use of d_type to identify unix domain sockets
+CFLAGS+= -D_DIRENT_HAVE_D_TYPE
+
+CFLAGS+= -DCONFIG_READLINE -I${DESTDIR}/${INCLUDEDIR}/edit
+LDADD+= -ledit -ltermcap
+DPADD+= ${LIBEDIT} ${LIBTERMCAP}
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/wpa/wpa_cli/wpa_cli.8 b/usr.sbin/wpa/wpa_cli/wpa_cli.8
new file mode 100644
index 0000000..fdb24fc
--- /dev/null
+++ b/usr.sbin/wpa/wpa_cli/wpa_cli.8
@@ -0,0 +1,222 @@
+.\" Copyright (c) 2005 Sam Leffler <sam@errno.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd June 16, 2005
+.Dt WPA_CLI 8
+.Os
+.Sh NAME
+.Nm wpa_cli
+.Nd "text-based frontend program for interacting with wpa_supplicant"
+.Sh SYNOPSIS
+.Nm
+.Op Ar commands
+.Sh DESCRIPTION
+The
+.Nm
+utility
+is a text-based frontend program for interacting with
+.Xr wpa_supplicant 8 .
+It is used to query current status,
+change configuration,
+trigger events,
+and
+request interactive user input.
+.Pp
+The
+.Nm
+utility
+can show the
+current authentication status,
+selected security
+mode, dot11 and dot1x MIBs, etc.
+In addition,
+.Nm
+can configure EAPOL state machine
+parameters and trigger events such as reassociation
+and IEEE 802.1X logoff/logon.
+.Pp
+The
+.Nm
+utility
+provides an interface to supply authentication information
+such as username and password when it is not provided in the
+.Xr wpa_supplicant.conf 5
+configuration file.
+This can be used, for example, to implement
+one-time passwords or generic token card
+authentication where the authentication is based on a
+challenge-response that uses an external device for generating the
+response.
+.Pp
+The
+.Nm
+utility
+supports two modes: interactive and command line.
+Both modes share the same command set and the main difference
+is in interactive mode providing access to unsolicited messages
+(event messages, username/password requests).
+.Pp
+Interactive mode is started when
+.Nm
+is executed without any parameters on the command line.
+Commands are then entered from the controlling terminal in
+response to the
+.Nm
+prompt.
+In command line mode, the same commands are
+entered as command line arguments.
+.Pp
+The control interface of
+.Xr wpa_supplicant 8
+can be configured to allow
+non-root user access by using the
+.Va ctrl_interface_group
+parameter
+in the
+.Xr wpa_supplicant.conf 5
+configuration file.
+This makes it possible to run
+.Nm
+with a normal user account.
+.Sh AUTHENTICATION PARAMETERS
+When
+.Xr wpa_supplicant 8
+needs authentication parameters, such as username and password,
+that are not present in the configuration file, it sends a
+request message to all attached frontend programs, e.g.,
+.Nm
+in interactive mode.
+The
+.Nm
+utility
+shows these requests with a
+.Dq Li CTRL-REQ- Ns Ao Ar type Ac Ns Li - Ns Ao Ar id Ac Ns : Ns Aq Ar text
+prefix, where
+.Aq Ar type
+is
+.Li IDENTITY , PASSWORD ,
+or
+.Li OTP
+(One-Time Password),
+.Aq Ar id
+is a unique identifier for the current network,
+.Aq Ar text
+is a description of the request.
+In the case of an
+.Li OTP
+(One-Time Password) request,
+it includes the challenge from the authentication server.
+.Pp
+A user must supply
+.Xr wpa_supplicant 8
+the needed parameters in response to these requests.
+.Pp
+For example,
+.Bd -literal -offset indent
+CTRL-REQ-PASSWORD-1:Password needed for SSID foobar
+> password 1 mysecretpassword
+
+Example request for generic token card challenge-response:
+
+CTRL-REQ-OTP-2:Challenge 1235663 needed for SSID foobar
+> otp 2 9876
+.Ed
+.Sh COMMANDS
+The following commands may be supplied on the command line
+or at a prompt when operating interactively.
+.Bl -tag -width indent
+.It Ic status
+Report the current WPA/EAPOL/EAP status for the current interface.
+.It Ic mib
+Report MIB variables (dot1x, dot11) for the current interface.
+.It Ic help
+Show usage help.
+.It Ic interface Op Ar ifname
+Show available interfaces and/or set the current interface
+when multiple are available.
+.It Ic level Ar debug_level
+Change the debugging level in
+.Xr wpa_supplicant 8 .
+Larger numbers generate more messages.
+.It Ic license
+Display the full
+license for
+.Nm .
+.It Ic logoff
+Send the IEEE 802.1X EAPOL state machine into the
+.Dq logoff
+state.
+.It Ic logon
+Send the IEEE 802.1X EAPOL state machine into the
+.Dq logon
+state.
+.It Ic set Op Ar settings
+Set variables.
+When no arguments are supplied, the known variables and their settings
+are displayed.
+.It Ic pmksa
+Show the contents of the PMKSA cache.
+.It Ic reassociate
+Force a reassociation to the current access point.
+.It Ic reconfigure
+Force
+.Xr wpa_supplicant 8
+to re-read its configuration file.
+.It Ic preauthenticate Ar BSSID
+Force preauthentication of the specified
+.Ar BSSID .
+.It Ic identity Ar network_id identity
+Configure an identity for an SSID.
+.It Ic password Ar network_id password
+Configure a password for an SSID.
+.It Ic otp Ar network_id password
+Configure a one-time password for an SSID.
+.It Ic terminate
+Force
+.Xr wpa_supplicant 8
+to terminate.
+.It Ic quit
+Exit
+.Nm .
+.El
+.Sh SEE ALSO
+.Xr wpa_supplicant.conf 5 ,
+.Xr wpa_supplicant 8
+.Sh HISTORY
+The
+.Nm
+utility first appeared in
+.Fx 6.0 .
+.Sh AUTHORS
+The
+.Nm
+utility was written by
+.An Jouni Malinen Aq j@w1.fi .
+This manual page is derived from the
+.Pa README
+file included in the
+.Nm wpa_supplicant
+distribution.
diff --git a/usr.sbin/wpa/wpa_passphrase/Makefile b/usr.sbin/wpa/wpa_passphrase/Makefile
new file mode 100644
index 0000000..385e23c
--- /dev/null
+++ b/usr.sbin/wpa/wpa_passphrase/Makefile
@@ -0,0 +1,16 @@
+# $FreeBSD$
+
+.include "${.CURDIR}/../Makefile.inc"
+
+.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
+
+CFLAGS+= -DINTERNAL_SHA1
+CFLAGS+= -DINTERNAL_MD5
+
+MAN= wpa_passphrase.8
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/wpa/wpa_passphrase/wpa_passphrase.8 b/usr.sbin/wpa/wpa_passphrase/wpa_passphrase.8
new file mode 100644
index 0000000..c66d658
--- /dev/null
+++ b/usr.sbin/wpa/wpa_passphrase/wpa_passphrase.8
@@ -0,0 +1,66 @@
+.\" Copyright (c) 2006 Henrik Brix Andersen <henrik@brixandersen.dk>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd July 17, 2007
+.Dt WPA_PASSPHRASE 8
+.Os
+.Sh NAME
+.Nm wpa_passphrase
+.Nd "utility for generating a 256-bit pre-shared WPA key from an ASCII passphrase"
+.Sh SYNOPSIS
+.Nm
+.Aq Ar ssid
+.Op Ar passphrase
+.Sh DESCRIPTION
+The
+.Nm
+utility is a small program for generating a 256-bit pre-shared WPA key
+from an ASCII passphrase and a given SSID. The output is formatted for
+inclusion in
+.Xr wpa_supplicant.conf 5 .
+.Pp
+If
+.Nm
+is called with only an SSID as argument it will prompt for a
+passphrase on standard input.
+.Sh SEE ALSO
+.Xr wpa_supplicant.conf 5 ,
+.Xr wpa_supplicant 8
+.Sh HISTORY
+The
+.Nm
+utility first appeared in
+.Fx 6.3 .
+.Sh AUTHORS
+The
+.Nm
+utility was written by
+.An Jouni Malinen
+.Aq j@w1.fi .
+.Pp
+This manual page was written by
+.An Henrik Brix Andersen
+.Aq henrik@brixandersen.dk .
diff --git a/usr.sbin/wpa/wpa_supplicant/Makefile b/usr.sbin/wpa/wpa_supplicant/Makefile
new file mode 100644
index 0000000..52c23eb
--- /dev/null
+++ b/usr.sbin/wpa/wpa_supplicant/Makefile
@@ -0,0 +1,154 @@
+# $FreeBSD$
+
+.include "${.CURDIR}/../Makefile.inc"
+
+.PATH.c:${WPA_SUPPLICANT_DISTDIR} \
+ ${WPA_DISTDIR}/src/drivers \
+ ${WPA_DISTDIR}/src/eap_peer \
+ ${WPA_DISTDIR}/src/rsn_supp
+ ${WPA_DISTDIR}/src/crypto
+
+PROG= wpa_supplicant
+SRCS= aes-cbc.c aes-ctr.c aes-eax.c aes-encblock.c \
+ aes-internal.c aes-omac1.c aes-unwrap.c \
+ aes-wrap.c bss.c blacklist.c common.c config.c ctrl_iface.c \
+ ctrl_iface_unix.c drivers.c eloop.c events.c l2_packet_freebsd.c main.c\
+ md5.c notify.c preauth.c pmksa_cache.c scan.c \
+ sha1-pbkdf2.c sha1-tlsprf.c sha1-tprf.c sha1.c \
+ wpa.c wpa_common.c wpa_debug.c wpa_ie.c wpa_supplicant.c \
+ wpabuf.c wpas_glue.c \
+ driver_ndis.c Packet32.c \
+ driver_wired.c \
+ driver_freebsd.c os_unix.c
+
+MAN= wpa_supplicant.8 wpa_supplicant.conf.5
+
+.if ${MK_EXAMPLES} != "no"
+FILESDIR= ${SHAREDIR}/examples/etc
+.PATH: ${WPA_SUPPLICANT_DISTDIR}
+FILES= wpa_supplicant.conf
+.endif
+
+CFLAGS+=-I${WPA_SUPPLICANT_DISTDIR}
+CFLAGS+=-I${WPA_DISTDIR}/src/drivers
+CFLAGS+=-I${WPA_DISTDIR}/src/rsn_supp
+
+CFLAGS+= -DCONFIG_DRIVER_BSD
+CFLAGS+= -DCONFIG_DRIVER_NDIS
+CFLAGS+= -DCONFIG_DRIVER_WIRED
+CFLAGS+= -DCONFIG_TERMINATE_ONLASTIF
+CFLAGS+= -DCONFIG_DEBUG_SYSLOG
+#CFLAGS+= -g
+DPADD+= ${LIBPCAP}
+LDADD+= -lpcap
+
+# NB: we only support wpa_supplicant.conf file
+SRCS+= config_file.c base64.c
+CFLAGS+=-DCONFIG_BACKEND_FILE
+
+# User customizations to the wpa_supplicant build environment
+CFLAGS+=${WPA_SUPPLICANT_CFLAGS}
+#DPADD+=${WPA_SUPPLICANT_DPADD}
+LDADD+=${WPA_SUPPLICANT_LDADD}
+#LDFLAGS+=${WPA_SUPPLICANT_LDFLAGS}
+
+.if ${MK_WPA_SUPPLICANT_EAPOL} != "no"
+SRCS+= eapol_supp_sm.c eap.c eap_common.c eap_methods.c eap_register.c
+CFLAGS+= -DIEEE8021X_EAPOL
+
+.if ${MK_OPENSSL} != "no" && !defined(RELEASE_CRUNCH)
+CFLAGS+=-DEAP_TLS -DEAP_PEAP -DEAP_MSCHAPv2 -DEAP_LEAP -DEAP_PSK \
+ -DEAP_TLV -DEAP_TLS_FUNCS -DEAP_TLS_OPENSSL
+SRCS+= chap.c crypto_openssl.c \
+ eap_leap.c \
+ eap_mschapv2.c \
+ eap_peap.c eap_peap_common.c \
+ eap_psk.c eap_psk_common.c \
+ eap_tls.c eap_tls_common.c \
+ mschapv2.c ms_funcs.c tls_openssl.c
+
+CFLAGS+=-DEAP_TTLS -DEAP_MD5
+SRCS+= eap_ttls.c eap_md5.c
+
+.if !empty(CFLAGS:M*-DEAP_GTC)
+SRCS+= eap_gtc.c
+.endif
+
+.if !empty(CFLAGS:M*-DEAP_OTP)
+SRCS+= eap_otp.c
+.endif
+
+.if !empty(CFLAGS:M*-DEAP_AKA)
+NEED_SIM_COMMON= true
+SRCS+= eap_aka.c
+.endif
+
+.if !empty(CFLAGS:M*-DEAP_SIM)
+NEED_SIM_COMMON= true
+SRCS+= eap_sim.c
+.endif
+
+.if defined(NEED_SIM_COMMON)
+SRCS+= eap_sim_common.c
+
+# PC/SC interface for smartcards (USIM, GSM SIM)
+# GSM/UMTS authentication algorithm (for EAP-SIM/EAP-AKA)
+# NB: requires devel/pcsc-lite
+#
+# WPA_SUPPLICANT_CFLAGS=-DEAP_AKA -DPCSC_FUNCS -I/usr/local/include/PCSC
+# WPA_SUPPLICANT_LDADD=-L/usr/local/lib
+#
+.if !empty(CFLAGS:M*-DPCSC_FUNCS)
+SRCS+= pcsc_funcs.c
+DPADD+=${LIBPTHREAD}
+LDADD+=-lpcsclite -lpthread
+.endif
+.endif
+
+.if !empty(CFLAGS:M*-DEAP_GPSK)
+CFLAGS+=-DEAP_GPSK_SHA256
+SRCS+= eap_gpsk.c eap_gpsk_common.c
+NEED_SHA256= true
+.endif
+
+.if !empty(CFLAGS:M*-DEAP_PAX)
+SRCS+= eap_pax.c eap_pax_common.c
+.endif
+
+.if !empty(CFLAGS:M*-DEAP_SAKE)
+SRCS+= eap_sake.c eap_sake_common.c
+.endif
+
+# NB: requires patch to openssl
+#CFLAGS+= -DEAP_FAST
+#SRCS+= eap_fast.c
+
+NEED_LIBSSL= true
+.else
+CFLAGS+= -DEAP_TLS_NONE
+SRCS+= tls_none.c
+.endif
+
+.endif
+
+#
+# Configure crypto/cipher support.
+#
+# EAPOL support requires openssl in which case we use their
+# cipher code. Otherwise we use our internal versions.
+#
+.if !defined(NEED_LIBSSL)
+CFLAGS+= -DINTERNAL_AES
+CFLAGS+= -DINTERNAL_SHA1
+CFLAGS+= -DINTERNAL_MD5
+.else
+DPADD+= ${LIBSSL} ${LIBCRYPTO}
+LDADD+= -lssl -lcrypto
+.endif
+
+.if defined(NEED_SHA256)
+CFLAGS+=-DINTERNAL_SHA256
+SRCS+= sha256.c
+.endif
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/wpa/wpa_supplicant/Packet32.c b/usr.sbin/wpa/wpa_supplicant/Packet32.c
new file mode 100644
index 0000000..07da359
--- /dev/null
+++ b/usr.sbin/wpa/wpa_supplicant/Packet32.c
@@ -0,0 +1,415 @@
+/*-
+ * Copyright (c) 2005
+ * Bill Paul <wpaul@windriver.com>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * This file implements a small portion of the Winpcap API for the
+ * Windows NDIS interface in wpa_supplicant. It provides just enough
+ * routines to fool wpa_supplicant into thinking it's really running
+ * in a Windows environment.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/errno.h>
+#include <sys/sysctl.h>
+#include <sys/fcntl.h>
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_var.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <net/route.h>
+
+#include <net80211/ieee80211_ioctl.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <pcap.h>
+
+#include "Packet32.h"
+
+#define OID_802_11_ADD_KEY 0x0d01011D
+
+typedef ULONGLONG NDIS_802_11_KEY_RSC;
+typedef UCHAR NDIS_802_11_MAC_ADDRESS[6];
+
+typedef struct NDIS_802_11_KEY {
+ ULONG Length;
+ ULONG KeyIndex;
+ ULONG KeyLength;
+ NDIS_802_11_MAC_ADDRESS BSSID;
+ NDIS_802_11_KEY_RSC KeyRSC;
+ UCHAR KeyMaterial[1];
+} NDIS_802_11_KEY;
+
+typedef struct NDIS_802_11_KEY_COMPAT {
+ ULONG Length;
+ ULONG KeyIndex;
+ ULONG KeyLength;
+ NDIS_802_11_MAC_ADDRESS BSSID;
+ UCHAR Pad[6]; /* Make struct layout match Windows. */
+ NDIS_802_11_KEY_RSC KeyRSC;
+#ifdef notdef
+ UCHAR KeyMaterial[1];
+#endif
+} NDIS_802_11_KEY_COMPAT;
+
+#define TRUE 1
+#define FALSE 0
+
+struct adapter {
+ int socket;
+ char name[IFNAMSIZ];
+ int prev_roaming;
+};
+
+PCHAR
+PacketGetVersion(void)
+{
+ return("FreeBSD WinPcap compatibility shim v1.0");
+}
+
+void *
+PacketOpenAdapter(CHAR *iface)
+{
+ struct adapter *a;
+ int s;
+ int ifflags;
+ struct ifreq ifr;
+ struct ieee80211req ireq;
+
+ s = socket(PF_INET, SOCK_DGRAM, 0);
+
+ if (s == -1)
+ return(NULL);
+
+ a = malloc(sizeof(struct adapter));
+ if (a == NULL)
+ return(NULL);
+
+ a->socket = s;
+ if (strncmp(iface, "\\Device\\NPF_", 12) == 0)
+ iface += 12;
+ else if (strncmp(iface, "\\DEVICE\\", 8) == 0)
+ iface += 8;
+ snprintf(a->name, IFNAMSIZ, "%s", iface);
+
+ /* Turn off net80211 roaming */
+ bzero((char *)&ireq, sizeof(ireq));
+ strncpy(ireq.i_name, iface, sizeof (ifr.ifr_name));
+ ireq.i_type = IEEE80211_IOC_ROAMING;
+ if (ioctl(a->socket, SIOCG80211, &ireq) == 0) {
+ a->prev_roaming = ireq.i_val;
+ ireq.i_val = IEEE80211_ROAMING_MANUAL;
+ if (ioctl(a->socket, SIOCS80211, &ireq) < 0)
+ fprintf(stderr,
+ "Could not set IEEE80211_ROAMING_MANUAL\n");
+ }
+
+ bzero((char *)&ifr, sizeof(ifr));
+ strncpy(ifr.ifr_name, iface, sizeof (ifr.ifr_name));
+ if (ioctl(a->socket, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
+ free(a);
+ close(s);
+ return(NULL);
+ }
+ ifr.ifr_flags |= IFF_UP;
+ if (ioctl(a->socket, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) {
+ free(a);
+ close(s);
+ return(NULL);
+ }
+
+ return(a);
+}
+
+int
+PacketRequest(void *iface, BOOLEAN set, PACKET_OID_DATA *oid)
+{
+ struct adapter *a;
+ uint32_t retval;
+ struct ifreq ifr;
+ NDIS_802_11_KEY *old;
+ NDIS_802_11_KEY_COMPAT *new;
+ PACKET_OID_DATA *o = NULL;
+
+ if (iface == NULL)
+ return(-1);
+
+ a = iface;
+ bzero((char *)&ifr, sizeof(ifr));
+
+ /*
+ * This hack is necessary to work around a difference
+ * betwee the GNU C and Microsoft C compilers. The NDIS_802_11_KEY
+ * structure has a uint64_t in it, right after an array of
+ * chars. The Microsoft compiler inserts padding right before
+ * the 64-bit value to align it on a 64-bit boundary, but
+ * GCC only aligns it on a 32-bit boundary. Trying to pass
+ * the GCC-formatted structure to an NDIS binary driver
+ * fails because some of the fields appear to be at the
+ * wrong offsets.
+ *
+ * To get around this, if we detect someone is trying to do
+ * a set operation on OID_802_11_ADD_KEY, we shuffle the data
+ * into a properly padded structure and pass that into the
+ * driver instead. This allows the driver_ndis.c code supplied
+ * with wpa_supplicant to work unmodified.
+ */
+
+ if (set == TRUE && oid->Oid == OID_802_11_ADD_KEY) {
+ old = (NDIS_802_11_KEY *)&oid->Data;
+ o = malloc(sizeof(PACKET_OID_DATA) +
+ sizeof(NDIS_802_11_KEY_COMPAT) + old->KeyLength);
+ if (o == NULL)
+ return(0);
+ bzero((char *)o, sizeof(PACKET_OID_DATA) +
+ sizeof(NDIS_802_11_KEY_COMPAT) + old->KeyLength);
+ o->Oid = oid->Oid;
+ o->Length = sizeof(NDIS_802_11_KEY_COMPAT) + old->KeyLength;
+ new = (NDIS_802_11_KEY_COMPAT *)&o->Data;
+ new->KeyRSC = old->KeyRSC;
+ new->Length = o->Length;
+ new->KeyIndex = old->KeyIndex;
+ new->KeyLength = old->KeyLength;
+ bcopy(old->BSSID, new->BSSID, sizeof(NDIS_802_11_MAC_ADDRESS));
+ bcopy(old->KeyMaterial, (char *)new +
+ sizeof(NDIS_802_11_KEY_COMPAT), new->KeyLength);
+ ifr.ifr_data = (caddr_t)o;
+ } else
+ ifr.ifr_data = (caddr_t)oid;
+
+ strlcpy(ifr.ifr_name, a->name, sizeof(ifr.ifr_name));
+
+ if (set == TRUE)
+ retval = ioctl(a->socket, SIOCSDRVSPEC, &ifr);
+ else
+ retval = ioctl(a->socket, SIOCGDRVSPEC, &ifr);
+
+ if (o != NULL)
+ free(o);
+
+ if (retval)
+ return(0);
+
+ return(1);
+}
+
+int
+PacketGetAdapterNames(CHAR *namelist, ULONG *len)
+{
+ int mib[6];
+ size_t needed;
+ struct if_msghdr *ifm;
+ struct sockaddr_dl *sdl;
+ char *buf, *lim, *next;
+ char *plist;
+ int spc;
+ int i, ifcnt = 0;
+
+ plist = namelist;
+ spc = 0;
+
+ bzero(plist, *len);
+
+ needed = 0;
+ mib[0] = CTL_NET;
+ mib[1] = PF_ROUTE;
+ mib[2] = 0; /* protocol */
+ mib[3] = 0; /* wildcard address family */
+ mib[4] = NET_RT_IFLIST;
+ mib[5] = 0; /* no flags */
+
+ if (sysctl (mib, 6, NULL, &needed, NULL, 0) < 0)
+ return(FALSE);
+
+ buf = malloc (needed);
+ if (buf == NULL)
+ return(FALSE);
+
+ if (sysctl (mib, 6, buf, &needed, NULL, 0) < 0) {
+ free(buf);
+ return(FALSE);
+ }
+
+ lim = buf + needed;
+
+ /* Generate interface name list. */
+
+ next = buf;
+ while (next < lim) {
+ ifm = (struct if_msghdr *)next;
+ if (ifm->ifm_type == RTM_IFINFO) {
+ sdl = (struct sockaddr_dl *)(ifm + 1);
+ if (strnstr(sdl->sdl_data, "wlan", sdl->sdl_nlen)) {
+ if ((spc + sdl->sdl_nlen) > *len) {
+ free(buf);
+ return(FALSE);
+ }
+ strncpy(plist, sdl->sdl_data, sdl->sdl_nlen);
+ plist += (sdl->sdl_nlen + 1);
+ spc += (sdl->sdl_nlen + 1);
+ ifcnt++;
+ }
+ }
+ next += ifm->ifm_msglen;
+ }
+
+
+ /* Insert an extra "" as a spacer */
+
+ plist++;
+ spc++;
+
+ /*
+ * Now generate the interface description list. There
+ * must be a unique description for each interface, and
+ * they have to match what the ndis_events program will
+ * feed in later. To keep this simple, we just repeat
+ * the interface list over again.
+ */
+
+ next = buf;
+ while (next < lim) {
+ ifm = (struct if_msghdr *)next;
+ if (ifm->ifm_type == RTM_IFINFO) {
+ sdl = (struct sockaddr_dl *)(ifm + 1);
+ if (strnstr(sdl->sdl_data, "wlan", sdl->sdl_nlen)) {
+ if ((spc + sdl->sdl_nlen) > *len) {
+ free(buf);
+ return(FALSE);
+ }
+ strncpy(plist, sdl->sdl_data, sdl->sdl_nlen);
+ plist += (sdl->sdl_nlen + 1);
+ spc += (sdl->sdl_nlen + 1);
+ ifcnt++;
+ }
+ }
+ next += ifm->ifm_msglen;
+ }
+
+ free (buf);
+
+ *len = spc + 1;
+
+ return(TRUE);
+}
+
+void
+PacketCloseAdapter(void *iface)
+{
+ struct adapter *a;
+ struct ifreq ifr;
+ struct ieee80211req ireq;
+
+ if (iface == NULL)
+ return;
+
+ a = iface;
+
+ /* Reset net80211 roaming */
+ bzero((char *)&ireq, sizeof(ireq));
+ strncpy(ireq.i_name, a->name, sizeof (ifr.ifr_name));
+ ireq.i_type = IEEE80211_IOC_ROAMING;
+ ireq.i_val = a->prev_roaming;
+ ioctl(a->socket, SIOCS80211, &ireq);
+
+ bzero((char *)&ifr, sizeof(ifr));
+ strncpy(ifr.ifr_name, a->name, sizeof (ifr.ifr_name));
+ ioctl(a->socket, SIOCGIFFLAGS, (caddr_t)&ifr);
+ ifr.ifr_flags &= ~IFF_UP;
+ ioctl(a->socket, SIOCSIFFLAGS, (caddr_t)&ifr);
+ close(a->socket);
+ free(a);
+
+ return;
+}
+
+#if __FreeBSD_version < 600000
+
+/*
+ * The version of libpcap in FreeBSD 5.2.1 doesn't have these routines.
+ * Call me insane if you will, but I still run 5.2.1 on my laptop, and
+ * I'd like to use WPA there.
+ */
+
+int
+pcap_get_selectable_fd(pcap_t *p)
+{
+ return(pcap_fileno(p));
+}
+
+/*
+ * The old version of libpcap opens its BPF descriptor in read-only
+ * mode. We need to temporarily create a new one we can write to.
+ */
+
+int
+pcap_inject(pcap_t *p, const void *buf, size_t len)
+{
+ int fd;
+ int res, n = 0;
+ char device[sizeof "/dev/bpf0000000000"];
+ struct ifreq ifr;
+
+ /*
+ * Go through all the minors and find one that isn't in use.
+ */
+ do {
+ (void)snprintf(device, sizeof(device), "/dev/bpf%d", n++);
+ fd = open(device, O_RDWR);
+ } while (fd < 0 && errno == EBUSY);
+
+ if (fd == -1)
+ return(-1);
+
+ bzero((char *)&ifr, sizeof(ifr));
+ ioctl(pcap_fileno(p), BIOCGETIF, (caddr_t)&ifr);
+ ioctl(fd, BIOCSETIF, (caddr_t)&ifr);
+
+ res = write(fd, buf, len);
+
+ close(fd);
+
+ return(res);
+}
+#endif
diff --git a/usr.sbin/wpa/wpa_supplicant/Packet32.h b/usr.sbin/wpa/wpa_supplicant/Packet32.h
new file mode 100644
index 0000000..e0598e7
--- /dev/null
+++ b/usr.sbin/wpa/wpa_supplicant/Packet32.h
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 2005
+ * Bill Paul <wpaul@windriver.com>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Bill Paul.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _PACKET32_H_
+#define _PACKET32_H_
+
+#include <sys/types.h>
+#include <ntddndis.h>
+
+struct PACKET_OID_DATA {
+ uint32_t Oid;
+ uint32_t Length;
+ uint8_t Data[1];
+};
+
+
+typedef struct PACKET_OID_DATA PACKET_OID_DATA;
+
+extern PCHAR PacketGetVersion(void);
+extern void *PacketOpenAdapter(CHAR *);
+extern int PacketRequest(void *, BOOLEAN, PACKET_OID_DATA *);
+extern int PacketGetAdapterNames(CHAR *, ULONG *);
+extern void PacketCloseAdapter(void *);
+
+/*
+ * This is for backwards compatibility on FreeBSD 5.
+ */
+
+#ifndef SIOCGDRVSPEC
+#define SIOCSDRVSPEC _IOW('i', 123, struct ifreq) /* set driver-specific
+ parameters */
+#define SIOCGDRVSPEC _IOWR('i', 123, struct ifreq) /* get driver-specific
+ parameters */
+#endif
+
+#endif /* _PACKET32_H_ */
diff --git a/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c b/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c
new file mode 100644
index 0000000..0ac3c50
--- /dev/null
+++ b/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c
@@ -0,0 +1,929 @@
+/*
+ * 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;
+
+ 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,
+};
diff --git a/usr.sbin/wpa/wpa_supplicant/ntddndis.h b/usr.sbin/wpa/wpa_supplicant/ntddndis.h
new file mode 100644
index 0000000..42e403d
--- /dev/null
+++ b/usr.sbin/wpa/wpa_supplicant/ntddndis.h
@@ -0,0 +1,31 @@
+#ifndef _NTDDNDIS_H_
+#define _NTDDNDIS_H_
+
+/*
+ * $FreeBSD$
+ */
+
+/*
+ * Fake up some of the Windows type definitions so that the NDIS
+ * interface module in wpa_supplicant will build.
+ */
+
+#define ULONG uint32_t
+#define USHORT uint16_t
+#define UCHAR uint8_t
+#define LONG int32_t
+#define SHORT int16_t
+#define CHAR int8_t
+#define ULONGLONG uint64_t
+#define LONGLONG int64_t
+#define BOOLEAN uint8_t
+typedef void * LPADAPTER;
+typedef char * PTSTR;
+typedef char * PCHAR;
+
+#define TRUE 1
+#define FALSE 0
+
+#define OID_802_3_CURRENT_ADDRESS 0x01010102
+
+#endif /* _NTDDNDIS_H_ */
diff --git a/usr.sbin/wpa/wpa_supplicant/wpa_supplicant.8 b/usr.sbin/wpa/wpa_supplicant/wpa_supplicant.8
new file mode 100644
index 0000000..4858410
--- /dev/null
+++ b/usr.sbin/wpa/wpa_supplicant/wpa_supplicant.8
@@ -0,0 +1,155 @@
+.\" Copyright (c) 2005 Sam Leffler <sam@errno.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 24, 2008
+.Dt WPA_SUPPLICANT 8
+.Os
+.Sh NAME
+.Nm wpa_supplicant
+.Nd "WPA/802.11i Supplicant for wireless network devices"
+.Sh SYNOPSIS
+.Nm
+.Op Fl BdehLqsvw
+.Fl i Ar ifname
+.Fl c Ar config-file
+.Sh DESCRIPTION
+The
+.Nm
+utility
+is an implementation of the WPA Supplicant component,
+i.e., the part that runs in the client stations.
+It implements WPA key negotiation with a WPA Authenticator
+and EAP authentication with an Authentication Server.
+In addition,
+.Nm
+controls the roaming and IEEE 802.11
+authentication/association support of the
+.Xr wlan 4
+module and can be used to configure static WEP keys
+based on identified networks.
+.Pp
+The
+.Nm
+utility
+is designed to be a
+.Dq daemon
+program that runs in the
+background and acts as the backend component controlling
+the wireless connection.
+It supports separate frontend programs such as the
+text-based
+.Xr wpa_cli 8
+program.
+.Pp
+The following arguments must be specified on the command line:
+.Bl -tag -width indent
+.It Fl i Ar ifname
+Use the specified wireless interface.
+.It Fl c Ar config-file
+Use the settings in the specified configuration file when managing
+the wireless interface.
+See
+.Xr wpa_supplicant.conf 5
+for a description of the configuration file syntax and contents.
+.Pp
+Changes to the configuration file can be reloaded by sending a
+.Dv SIGHUP
+to the
+.Nm
+process or with the
+.Xr wpa_cli 8
+utility, using
+.Dq Li "wpa_cli reconfigure" .
+.El
+.Sh OPTIONS
+The following options are available:
+.Bl -tag -width indent
+.It Fl d
+Enable debugging messages.
+If this option is supplied twice, more verbose messages are displayed.
+.It Fl e
+Use an external IEEE 802.1X Supplicant program and disable the
+internal Supplicant.
+This option is not normally used.
+.It Fl h
+Show help text.
+.It Fl q
+Decrease debugging verbosity (i.e., counteract the use of the
+.Fl d
+flag).
+.It Fl s
+Send log messages through
+.Xr syslog 3
+instead of to the terminal.
+.It Fl v
+Display version information on the terminal and exit.
+.It Fl w
+If the specified interface is not present, wait for it to be
+added; e.g.\& a cardbus device to be inserted.
+This option is not normally used; instead,
+.Xr devd 8
+should be configured to launch
+.Nm
+when a device is created.
+.It Fl B
+Detach from the controlling terminal and run as a daemon process
+in the background.
+.It Fl K
+Include key information in debugging output.
+.It Fl L
+Display the license for this program on the terminal and exit.
+.El
+.Sh SEE ALSO
+.Xr an 4 ,
+.Xr ath 4 ,
+.Xr ipw 4 ,
+.Xr iwi 4 ,
+.Xr ral 4 ,
+.Xr rum 4 ,
+.Xr ural 4 ,
+.Xr wi 4 ,
+.Xr wlan 4 ,
+.Xr wpi 4 ,
+.Xr zyd 4 ,
+.Xr wpa_supplicant.conf 5 ,
+.Xr devd 8 ,
+.Xr ifconfig 8 ,
+.Xr wpa_cli 8
+.Sh HISTORY
+The
+.Nm
+utility first appeared in
+.Fx 6.0 .
+.Sh AUTHORS
+The
+.Nm
+utility was written by
+.An Jouni Malinen Aq j@w1.fi .
+This manual page is derived from the
+.Pa README
+file included in the
+.Nm
+distribution.
diff --git a/usr.sbin/wpa/wpa_supplicant/wpa_supplicant.conf.5 b/usr.sbin/wpa/wpa_supplicant/wpa_supplicant.conf.5
new file mode 100644
index 0000000..d37847e
--- /dev/null
+++ b/usr.sbin/wpa/wpa_supplicant/wpa_supplicant.conf.5
@@ -0,0 +1,578 @@
+.\" Copyright (c) 2005 Sam Leffler <sam@errno.com>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 10, 2010
+.Dt WPA_SUPPLICANT.CONF 5
+.Os
+.Sh NAME
+.Nm wpa_supplicant.conf
+.Nd configuration file for
+.Xr wpa_supplicant 8
+.Sh DESCRIPTION
+The
+.Xr wpa_supplicant 8
+utility is an implementation of the WPA Supplicant component,
+i.e., the part that runs in the client stations.
+It implements WPA key negotiation with a WPA Authenticator
+and EAP authentication with Authentication Server using
+configuration information stored in a text file.
+.Pp
+The configuration file consists of optional global parameter
+settings and one or more network blocks, e.g.\&
+one for each used SSID.
+The
+.Xr wpa_supplicant 8
+utility
+will automatically select the best network based on the order of
+the network blocks in the configuration file, network security level
+(WPA/WPA2 is preferred), and signal strength.
+Comments are indicated with the
+.Ql #
+character; all text to the
+end of the line will be ignored.
+.Sh GLOBAL PARAMETERS
+Default parameters used by
+.Xr wpa_supplicant 8
+may be overridden by specifying
+.Pp
+.Dl parameter=value
+.Pp
+in the configuration file (note no spaces are allowed).
+Values with embedded spaces must be enclosed in quote marks.
+.Pp
+The following parameters are recognized:
+.Bl -tag -width indent
+.It Va ctrl_interface
+The pathname of the directory in which
+.Xr wpa_supplicant 8
+creates
+.Ux
+domain socket files for communication
+with frontend programs such as
+.Xr wpa_cli 8 .
+.It Va ctrl_interface_group
+A group name or group ID to use in setting protection on the
+control interface file.
+This can be set to allow non-root users to access the
+control interface files.
+If no group is specified, the group ID of the control interface
+is not modified and will, typically, be the
+group ID of the directory in which the socket is created.
+.It Va eapol_version
+The IEEE 802.1x/EAPOL protocol version to use; either 1 (default) or 2.
+The
+.Xr wpa_supplicant 8
+utility
+is implemented according to IEEE 802-1X-REV-d8 which defines
+EAPOL version to be 2.
+However, some access points do not work when presented with
+this version so by default
+.Xr wpa_supplicant 8
+will announce that it is using EAPOL version 1.
+If version 2 must be announced for correct operation with an
+access point, this value may be set to 2.
+.It Va ap_scan
+Access point scanning and selection control; one of 0, 1 (default), or 2.
+Only setting 1 should be used with the
+.Xr wlan 4
+module; the other settings are for use on other operating systems.
+.It Va fast_reauth
+EAP fast re-authentication; either 1 (default) or 0.
+Control fast re-authentication support in EAP methods that support it.
+.El
+.Sh NETWORK BLOCKS
+Each potential network/access point should have a
+.Dq "network block"
+that describes how to identify it and how to set up security.
+When multiple network blocks are listed in a configuration file,
+the highest priority one is selected for use or, if multiple networks
+with the same priority are identified, the first one listed in the
+configuration file is used.
+.Pp
+A network block description is of the form:
+.Bd -literal -offset indent
+network={
+ parameter=value
+ ...
+}
+.Ed
+.Pp
+(note the leading
+.Qq Li "network={"
+may have no spaces).
+The block specification contains one or more parameters
+from the following list:
+.Bl -tag -width indent
+.It Va ssid No (required)
+Network name (as announced by the access point).
+An
+.Tn ASCII
+or hex string enclosed in quotation marks.
+.It Va scan_ssid
+SSID scan technique; 0 (default) or 1.
+Technique 0 scans for the SSID using a broadcast Probe Request
+frame while 1 uses a directed Probe Request frame.
+Access points that cloak themselves by not broadcasting their SSID
+require technique 1, but beware that this scheme can cause scanning
+to take longer to complete.
+.It Va bssid
+Network BSSID (typically the MAC address of the access point).
+.It Va priority
+The priority of a network when selecting among multiple networks;
+a higher value means a network is more desirable.
+By default networks have priority 0.
+When multiple networks with the same priority are considered
+for selection, other information such as security policy and
+signal strength are used to select one.
+.It Va mode
+IEEE 802.11 operation mode; either 0 (infrastructure, default) or 1 (IBSS).
+Note that IBSS (adhoc) mode can only be used with
+.Va key_mgmt
+set to
+.Li NONE
+(plaintext and static WEP), or
+.Va key_mgmt
+set to
+.Li WPA-NONE
+(fixed group key TKIP/CCMP).
+In addition,
+.Va ap_scan
+has to be set to 2 for IBSS.
+.Li WPA-NONE
+requires
+.Va proto
+set to WPA,
+.Va key_mgmt
+set to WPA-NONE,
+.Va pairwise
+set to NONE,
+.Va group
+set to either
+CCMP or TKIP (but not both), and
+.Va psk
+must also be set.
+.It Va proto
+List of acceptable protocols; one or more of:
+.Li WPA
+(IEEE 802.11i/D3.0)
+and
+.Li RSN
+(IEEE 802.11i).
+.Li WPA2
+is another name for
+.Li RSN .
+If not set this defaults to
+.Qq Li "WPA RSN" .
+.It Va key_mgmt
+List of acceptable key management protocols; one or more of:
+.Li WPA-PSK
+(WPA pre-shared key),
+.Li WPA-EAP
+(WPA using EAP authentication),
+.Li IEEE8021X
+(IEEE 802.1x using EAP authentication and,
+optionally, dynamically generated WEP keys),
+.Li NONE
+(plaintext or static WEP keys).
+If not set this defaults to
+.Qq Li "WPA-PSK WPA-EAP" .
+.It Va auth_alg
+List of allowed IEEE 802.11 authentication algorithms; one or more of:
+.Li OPEN
+(Open System authentication, required for WPA/WPA2),
+.Li SHARED
+(Shared Key authentication),
+.Li LEAP
+(LEAP/Network EAP).
+If not set automatic selection is used (Open System with LEAP
+enabled if LEAP is allowed as one of the EAP methods).
+.It Va pairwise
+List of acceptable pairwise (unicast) ciphers for WPA; one or more of:
+.Li CCMP
+(AES in Counter mode with CBC-MAC, RFC 3610, IEEE 802.11i/D7.0),
+.Li TKIP
+(Temporal Key Integrity Protocol, IEEE 802.11i/D7.0),
+.Li NONE
+(deprecated).
+If not set this defaults to
+.Qq Li "CCMP TKIP" .
+.It Va group
+List of acceptable group (multicast) ciphers for WPA; one or more of:
+.Li CCMP
+(AES in Counter mode with CBC-MAC, RFC 3610, IEEE 802.11i/D7.0),
+.Li TKIP
+(Temporal Key Integrity Protocol, IEEE 802.11i/D7.0),
+.Li WEP104
+(WEP with 104-bit key),
+.Li WEP40
+(WEP with 40-bit key).
+If not set this defaults to
+.Qq Li "CCMP TKIP WEP104 WEP40" .
+.It Va psk
+WPA preshared key used in WPA-PSK mode.
+The key is specified as 64 hex digits or as
+an 8-63 character
+.Tn ASCII
+passphrase.
+.Tn ASCII
+passphrases are dynamically converted to a 256-bit key at runtime
+using the network SSID, or they can be statically converted at
+configuration time using
+the
+.Xr wpa_passphrase 8
+utility.
+.It Va eapol_flags
+Dynamic WEP key usage for non-WPA mode, specified as a bit field.
+Bit 0 (1) forces dynamically generated unicast WEP keys to be used.
+Bit 1 (2) forces dynamically generated broadcast WEP keys to be used.
+By default this is set to 3 (use both).
+.It Va eap
+List of acceptable EAP methods; one or more of:
+.Li MD5
+(EAP-MD5, cannot be used with WPA,
+used only as a Phase 2 method with EAP-PEAP or EAP-TTLS),
+.Li MSCHAPV2
+(EAP-MSCHAPV2, cannot be used with WPA;
+used only as a Phase 2 method with EAP-PEAP or EAP-TTLS),
+.Li OTP
+(EAP-OTP, cannot be used with WPA;
+used only as a Phase 2 metod with EAP-PEAP or EAP-TTLS),
+.Li GTC
+(EAP-GTC, cannot be used with WPA;
+used only as a Phase 2 metod with EAP-PEAP or EAP-TTLS),
+.Li TLS
+(EAP-TLS, client and server certificate),
+.Li PEAP
+(EAP-PEAP, with tunneled EAP authentication),
+.Li TTLS
+(EAP-TTLS, with tunneled EAP or PAP/CHAP/MSCHAP/MSCHAPV2 authentication).
+If not set this defaults to all available methods compiled in to
+.Xr wpa_supplicant 8 .
+Note that by default
+.Xr wpa_supplicant 8
+is compiled with EAP support; see
+.Xr make.conf 5
+for the
+.Va NO_WPA_SUPPLICANT_EAPOL
+configuration variable that can be used to disable EAP support.
+.It Va identity
+Identity string for EAP.
+.It Va anonymous_identity
+Anonymous identity string for EAP (to be used as the unencrypted identity
+with EAP types that support different tunneled identities; e.g.\& EAP-TTLS).
+.It Va mixed_cell
+Configure whether networks that allow both plaintext and encryption
+are allowed when selecting a BSS from the scan results.
+By default this is set to 0 (disabled).
+.It Va password
+Password string for EAP.
+.It Va ca_cert
+Pathname to CA certificate file.
+This file can have one or more trusted CA certificates.
+If
+.Va ca_cert
+is not included, server certificates will not be verified (not recommended).
+.It Va client_cert
+Pathname to client certificate file (PEM/DER).
+.It Va private_key
+Pathname to a client private key file (PEM/DER/PFX).
+When a PKCS#12/PFX file is used, then
+.Va client_cert
+should not be specified as both the private key and certificate will be
+read from PKCS#12 file.
+.It Va private_key_passwd
+Password for any private key file.
+.It Va dh_file
+Pathname to a file holding DH/DSA parameters (in PEM format).
+This file holds parameters for an ephemeral DH key exchange.
+In most cases, the default RSA authentication does not use this configuration.
+However, it is possible to set up RSA to use an ephemeral DH key exchange.
+In addition, ciphers with
+DSA keys always use ephemeral DH keys.
+This can be used to achieve forward secrecy.
+If the
+.Va dh_file
+is in DSA parameters format, it will be automatically converted
+into DH params.
+.It Va subject_match
+Substring to be matched against the subject of the
+authentication server certificate.
+If this string is set, the server
+certificate is only accepted if it contains this string in the subject.
+The subject string is in following format:
+.Pp
+.Dl "/C=US/ST=CA/L=San Francisco/CN=Test AS/emailAddress=as@example.com"
+.It Va phase1
+Phase1 (outer authentication, i.e., TLS tunnel) parameters
+(string with field-value pairs, e.g.,
+.Qq Li peapver=0
+or
+.Qq Li "peapver=1 peaplabel=1" ) .
+.Bl -inset
+.It Li peapver
+can be used to force which PEAP version (0 or 1) is used.
+.It Li peaplabel=1
+can be used to force new label,
+.Dq "client PEAP encryption" ,
+to be used during key derivation when PEAPv1 or newer.
+Most existing PEAPv1 implementations seem to be using the old label,
+.Dq Li "client EAP encryption" ,
+and
+.Xr wpa_supplicant 8
+is now using that as the
+default value.
+Some servers, e.g.,
+.Tn Radiator ,
+may require
+.Li peaplabel=1
+configuration to interoperate with PEAPv1; see
+.Pa eap_testing.txt
+for more details.
+.It Li peap_outer_success=0
+can be used to terminate PEAP authentication on
+tunneled EAP-Success.
+This is required with some RADIUS servers that
+implement
+.Pa draft-josefsson-pppext-eap-tls-eap-05.txt
+(e.g.,
+.Tn Lucent NavisRadius v4.4.0
+with PEAP in
+.Dq "IETF Draft 5"
+mode).
+.It Li include_tls_length=1
+can be used to force
+.Xr wpa_supplicant 8
+to include
+TLS Message Length field in all TLS messages even if they are not
+fragmented.
+.It Li sim_min_num_chal=3
+can be used to configure EAP-SIM to require three
+challenges (by default, it accepts 2 or 3)
+.It Li fast_provisioning=1
+option enables in-line provisioning of EAP-FAST
+credentials (PAC).
+.El
+.It Va phase2
+phase2: Phase2 (inner authentication with TLS tunnel) parameters
+(string with field-value pairs, e.g.,
+.Qq Li "auth=MSCHAPV2"
+for EAP-PEAP or
+.Qq Li "autheap=MSCHAPV2 autheap=MD5"
+for EAP-TTLS).
+.It Va ca_cert2
+Like
+.Va ca_cert
+but for EAP inner Phase 2.
+.It Va client_cert2
+Like
+.Va client_cert
+but for EAP inner Phase 2.
+.It Va private_key2
+Like
+.Va private_key
+but for EAP inner Phase 2.
+.It Va private_key2_passwd
+Like
+.Va private_key_passwd
+but for EAP inner Phase 2.
+.It Va dh_file2
+Like
+.Va dh_file
+but for EAP inner Phase 2.
+.It Va subject_match2
+Like
+.Va subject_match
+but for EAP inner Phase 2.
+.It Va eappsk
+16-byte pre-shared key in hex format for use with EAP-PSK.
+.It Va nai
+User NAI for use with EAP-PSK.
+.It Va server_nai
+Authentication Server NAI for use with EAP-PSK.
+.It Va pac_file
+Pathname to the file to use for PAC entries with EAP-FAST.
+The
+.Xr wpa_supplicant 8
+utility
+must be able to create this file and write updates to it when
+PAC is being provisioned or refreshed.
+.It Va eap_workaround
+Enable/disable EAP workarounds for various interoperability issues
+with misbehaving authentication servers.
+By default these workarounds are enabled.
+Strict EAP conformance can be configured by setting this to 0.
+.It Va wep_tx_keyidx
+which key to use for transmission of packets.
+.It Va wep_keyN key
+An
+.Tn ASCII
+string enclosed in quotation marks to encode the WEP key.
+Without quotes this is a hex string of the actual key.
+WEP is considered insecure and should be avoided.
+The exact translation from an ASCII key to a hex key varies.
+Use hex keys where possible.
+.El
+.Sh CERTIFICATES
+Some EAP authentication methods require use of certificates.
+EAP-TLS uses both server- and client-side certificates,
+whereas EAP-PEAP and EAP-TTLS only require a server-side certificate.
+When a client certificate is used, a matching private key file must
+also be included in configuration.
+If the private key uses a passphrase, this
+has to be configured in the
+.Nm
+file as
+.Va private_key_passwd .
+.Pp
+The
+.Xr wpa_supplicant 8
+utility
+supports X.509 certificates in PEM and DER formats.
+User certificate and private key can be included in the same file.
+.Pp
+If the user certificate and private key is received in PKCS#12/PFX
+format, they need to be converted to a suitable PEM/DER format for
+use by
+.Xr wpa_supplicant 8 .
+This can be done using the
+.Xr openssl 1
+program, e.g.\& with the following commands:
+.Bd -literal
+# convert client certificate and private key to PEM format
+openssl pkcs12 -in example.pfx -out user.pem -clcerts
+# convert CA certificate (if included in PFX file) to PEM format
+openssl pkcs12 -in example.pfx -out ca.pem -cacerts -nokeys
+.Ed
+.Sh FILES
+.Bl -tag -width ".Pa /usr/share/examples/etc/wpa_supplicant.conf" -compact
+.It Pa /etc/wpa_supplicant.conf
+.It Pa /usr/share/examples/etc/wpa_supplicant.conf
+.El
+.Sh EXAMPLES
+WPA-Personal (PSK) as a home network and WPA-Enterprise with EAP-TLS
+as a work network:
+.Bd -literal
+# allow frontend (e.g., wpa_cli) to be used by all users in 'wheel' group
+ctrl_interface=/var/run/wpa_supplicant
+ctrl_interface_group=wheel
+#
+# home network; allow all valid ciphers
+network={
+ ssid="home"
+ scan_ssid=1
+ key_mgmt=WPA-PSK
+ psk="very secret passphrase"
+}
+#
+# work network; use EAP-TLS with WPA; allow only CCMP and TKIP ciphers
+network={
+ ssid="work"
+ scan_ssid=1
+ key_mgmt=WPA-EAP
+ pairwise=CCMP TKIP
+ group=CCMP TKIP
+ eap=TLS
+ identity="user@example.com"
+ ca_cert="/etc/cert/ca.pem"
+ client_cert="/etc/cert/user.pem"
+ private_key="/etc/cert/user.prv"
+ private_key_passwd="password"
+}
+.Ed
+.Pp
+WPA-RADIUS/EAP-PEAP/MSCHAPv2 with RADIUS servers that use old peaplabel
+(e.g., Funk Odyssey and SBR, Meetinghouse Aegis, Interlink RAD-Series):
+.Bd -literal
+ctrl_interface=/var/run/wpa_supplicant
+ctrl_interface_group=wheel
+network={
+ ssid="example"
+ scan_ssid=1
+ key_mgmt=WPA-EAP
+ eap=PEAP
+ identity="user@example.com"
+ password="foobar"
+ ca_cert="/etc/cert/ca.pem"
+ phase1="peaplabel=0"
+ phase2="auth=MSCHAPV2"
+}
+.Ed
+.Pp
+EAP-TTLS/EAP-MD5-Challenge configuration with anonymous identity for the
+unencrypted use.
+Real identity is sent only within an encrypted TLS tunnel.
+.Bd -literal
+ctrl_interface=/var/run/wpa_supplicant
+ctrl_interface_group=wheel
+network={
+ ssid="example"
+ scan_ssid=1
+ key_mgmt=WPA-EAP
+ eap=TTLS
+ identity="user@example.com"
+ anonymous_identity="anonymous@example.com"
+ password="foobar"
+ ca_cert="/etc/cert/ca.pem"
+ phase2="auth=MD5"
+}
+.Ed
+.Pp
+Traditional WEP configuration with 104 bit key specified in hexadecimal.
+Note the WEP key is not quoted.
+.Bd -literal
+ctrl_interface=/var/run/wpa_supplicant
+ctrl_interface_group=wheel
+network={
+ ssid="example"
+ scan_ssid=1
+ key_mgmt=NONE
+ wep_tx_keyidx=0
+ # hex keys denoted without quotes
+ wep_key0=42FEEDDEAFBABEDEAFBEEFAA55
+ # ASCII keys denoted with quotes.
+ wep_key1="FreeBSDr0cks!"
+}
+.Ed
+.Sh SEE ALSO
+.Xr wpa_cli 8 ,
+.Xr wpa_passphrase 8 ,
+.Xr wpa_supplicant 8
+.Sh HISTORY
+The
+.Nm
+manual page and
+.Xr wpa_supplicant 8
+functionality first appeared in
+.Fx 6.0 .
+.Sh AUTHORS
+This manual page is derived from the
+.Pa README
+and
+.Pa wpa_supplicant.conf
+files in the
+.Nm wpa_supplicant
+distribution provided by
+.An Jouni Malinen Aq j@w1.fi .
OpenPOWER on IntegriCloud