First try at porting wpa_supplicant.
authorRui Paulo <rpaulo@FreeBSD.org>
Thu, 25 Feb 2010 18:30:20 +0000 (18:30 +0000)
committerRui Paulo <rpaulo@FreeBSD.org>
Thu, 25 Feb 2010 18:30:20 +0000 (18:30 +0000)
usr.sbin/802_11/wpa_supplicant/Makefile
usr.sbin/802_11/wpa_supplicant/Packet32.c
usr.sbin/802_11/wpa_supplicant/Packet32.h
usr.sbin/802_11/wpa_supplicant/driver_dragonfly.c
usr.sbin/802_11/wpa_supplicant/driver_wired.c [new file with mode: 0644]
usr.sbin/802_11/wpa_supplicant/driver_wired.c.patch [deleted file]
usr.sbin/802_11/wpa_supplicant/events.c.patch [deleted file]
usr.sbin/802_11/wpa_supplicant/ntddndis.h
usr.sbin/802_11/wpa_supplicant/wpa_supplicant.8
usr.sbin/802_11/wpa_supplicant/wpa_supplicant.conf.5

index 30534f3..8d0a296 100644 (file)
@@ -1,12 +1,12 @@
-# $FreeBSD: src/usr.sbin/wpa/wpa_supplicant/Makefile,v 1.9 2007/07/11 16:04:08 sam Exp $
-# $DragonFly: src/usr.sbin/802_11/wpa_supplicant/Makefile,v 1.2 2007/08/07 11:25:36 sephe Exp $
+# $FreeBSD: head/usr.sbin/wpa/wpa_supplicant/Makefile 189263 2009-03-02 02:28:22Z sam $
+# $DragonFly$
 
 .include "${.CURDIR}/../Makefile.inc"
 
-.PATH.c:       ${WPA_DISTDIR}/wpa_supplicant \
-               ${WPA_DISTDIR}/src/drivers \
-               ${WPA_DISTDIR}/src/eap_peer \
-               ${WPA_DISTDIR}/src/rsn_supp
+.PATH.c:${WPA_DISTDIR}/wpa_supplicant \
+       ${WPA_DISTDIR}/src/drivers \
+       ${WPA_DISTDIR}/src/eap_peer \
+       ${WPA_DISTDIR}/src/rsn_supp
 
 PROG=  wpa_supplicant
 SRCS=  aes.c aes_wrap.c blacklist.c common.c config.c ctrl_iface.c \
@@ -20,13 +20,21 @@ SRCS=       aes.c aes_wrap.c blacklist.c common.c config.c ctrl_iface.c \
 
 MAN=   wpa_supplicant.8 wpa_supplicant.conf.5
 
-CFLAGS+= -I${.CURDIR} -I${WPA_DISTDIR}
-CFLAGS+= -I${WPA_DISTDIR}/src/drivers
-CFLAGS+= -I${WPA_DISTDIR}/src/rsn_supp
+#.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
@@ -35,17 +43,18 @@ LDADD+=     -lpcap
 SRCS+= config_file.c base64.c
 CFLAGS+=-DCONFIG_BACKEND_FILE
 
-.if !defined(NO_WPA_SUPPLICANT_EAPOL)
-.PATH: ${.CURDIR}/.. ${WPA_DISTDIR}/src/eapol_supp
-.PATH: ${.CURDIR}/.. ${WPA_DISTDIR}/src/eap_peer
+# User customizations to the wpa_supplicant build environment
+CFLAGS+=${WPA_SUPPLICANT_CFLAGS}
+#DPADD+=${WPA_SUPPLICANT_DPADD}
+LDADD+=${WPA_SUPPLICANT_LDADD}
+#LDFLAGS+=${WPA_SUPPLICANT_LDFLAGS}
+
 SRCS+= eapol_supp_sm.c eap.c eap_common.c eap_methods.c
 CFLAGS+= -DIEEE8021X_EAPOL
 
 .if !defined(NO_CRYPT) && !defined(NO_OPENSSL)
-.PATH:  ${.CURDIR}/.. ${WPA_DISTDIR}/src/eap_common
-.PATH:  ${.CURDIR}/.. ${WPA_DISTDIR}/eap_peer/
 CFLAGS+=-DEAP_TLS -DEAP_PEAP -DEAP_MSCHAPv2 -DEAP_LEAP -DEAP_PSK \
-       -DEAP_TLV -DEAP_TLS_FUNCS
+       -DEAP_TLV -DEAP_TLS_FUNCS -DEAP_TLS_OPENSSL
 SRCS+= chap.c crypto_openssl.c \
        eap_leap.c \
        eap_mschapv2.c \
@@ -61,16 +70,79 @@ SRCS+=      eap_ttls.c eap_md5.c
 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
 
-DPADD+= ${LIBSSL} ${LIBCRYPTO}
-LDADD+= -lssl -lcrypto
+NEED_LIBSSL=   true
 .else
+CFLAGS+= -DEAP_TLS_NONE
 SRCS+= tls_none.c
 .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>
index 820b914..1bda801 100644 (file)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/usr.sbin/wpa/wpa_supplicant/Packet32.c,v 1.4 2007/07/11 16:04:08 sam Exp $
- * $DragonFly: src/usr.sbin/802_11/wpa_supplicant/Packet32.c,v 1.4 2008/11/12 21:44:59 swildner Exp $
+ * $FreeBSD: head/usr.sbin/wpa/wpa_supplicant/Packet32.c 189220 2009-03-01 08:01:38Z sam $
+ * $DragonFly$
  */
 
+
 /*
  * This file implements a small portion of the Winpcap API for the
  * Windows NDIS interface in wpa_supplicant. It provides just enough
@@ -48,7 +49,6 @@
 #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>
@@ -281,7 +281,7 @@ PacketGetAdapterNames(CHAR *namelist, ULONG *len)
                ifm = (struct if_msghdr *)next;
                if (ifm->ifm_type == RTM_IFINFO) {
                        sdl = (struct sockaddr_dl *)(ifm + 1);
-                       if (strnstr(sdl->sdl_data, "ndis", sdl->sdl_nlen)) {
+                       if (strnstr(sdl->sdl_data, "wlan", sdl->sdl_nlen)) {
                                if ((spc + sdl->sdl_nlen) > *len) {
                                        free(buf);
                                        return(FALSE);
@@ -314,7 +314,7 @@ PacketGetAdapterNames(CHAR *namelist, ULONG *len)
                ifm = (struct if_msghdr *)next;
                if (ifm->ifm_type == RTM_IFINFO) {
                        sdl = (struct sockaddr_dl *)(ifm + 1);
-                       if (strnstr(sdl->sdl_data, "ndis", sdl->sdl_nlen)) {
+                       if (strnstr(sdl->sdl_data, "wlan", sdl->sdl_nlen)) {
                                if ((spc + sdl->sdl_nlen) > *len) {
                                        free(buf);
                                        return(FALSE);
@@ -364,3 +364,53 @@ PacketCloseAdapter(void *iface)
 
        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
index 17e2535..3415c18 100644 (file)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/usr.sbin/wpa/wpa_supplicant/Packet32.h,v 1.2.2.1 2005/10/27 17:06:47 wpaul Exp $
- * $DragonFly: src/usr.sbin/802_11/wpa_supplicant/Packet32.h,v 1.1 2006/06/24 07:29:44 sephe Exp $
+ * $FreeBSD: head/usr.sbin/wpa/wpa_supplicant/Packet32.h 151517 2005-10-20 16:49:31Z wpaul $
+ * $DragonFly$
  */
 
 #ifndef _PACKET32_H_
 #define _PACKET32_H_
 
 #include <sys/types.h>
-#include <sys/ioccom.h>
 #include <ntddndis.h>
 
 struct PACKET_OID_DATA {
index 736fc4a..5c19a34 100644 (file)
@@ -11,8 +11,8 @@
  *
  * See README and COPYING for more details.
  *
- * $FreeBSD: src/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c,v 1.14 2007/06/11 03:57:46 sam Exp $
- * $DragonFly: src/usr.sbin/802_11/wpa_supplicant/driver_dragonfly.c,v 1.3 2008/01/19 07:03:55 sephe Exp $
+ * $FreeBSD: head/usr.sbin/wpa/wpa_supplicant/driver_freebsd.c 189263 2009-03-02 02:28:22Z sam $
+ * $DragonFly$
  */
 
 #include <stdlib.h>
@@ -23,7 +23,7 @@
 #include <errno.h>
 
 #include "common.h"
-#include "driver.h"
+#include "drivers/driver.h"
 #include "eloop.h"
 #include "l2_packet.h"
 #include "ieee802_11_defs.h"
@@ -32,8 +32,6 @@
 #include <net/if.h>
 #include <net/ethernet.h>
 
-#include <netproto/802_11/ieee80211.h>
-#include <netproto/802_11/ieee80211_crypto.h>
 #include <netproto/802_11/ieee80211_ioctl.h>
 
 struct wpa_driver_bsd_data {
@@ -45,6 +43,11 @@ struct wpa_driver_bsd_data {
        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 */
 };
 
 static int
@@ -131,7 +134,7 @@ getifflags(struct wpa_driver_bsd_data *drv, int *flags)
                perror("SIOCGIFFLAGS");
                return errno;
        }
-       *flags = ifr.ifr_flags & 0xffff;
+       *flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16);
        return 0;
 }
 
@@ -143,6 +146,7 @@ setifflags(struct wpa_driver_bsd_data *drv, int flags)
        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;
@@ -192,7 +196,21 @@ static int
 wpa_driver_bsd_set_wpa_ie(struct wpa_driver_bsd_data *drv,
        const char *wpa_ie, size_t wpa_ie_len)
 {
-       return set80211var(drv, IEEE80211_IOC_OPTIE, wpa_ie, 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
@@ -255,7 +273,7 @@ wpa_driver_bsd_set_key(void *priv, wpa_alg alg,
        struct ieee80211req_key wk;
        struct ether_addr ea;
        char *alg_name;
-       uint8_t cipher;
+       u_int8_t cipher;
 
        if (alg == WPA_ALG_NONE)
                return wpa_driver_bsd_del_key(drv, key_idx, addr);
@@ -281,11 +299,11 @@ wpa_driver_bsd_set_key(void *priv, wpa_alg alg,
 
        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);
+           "%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(uint64_t)) {
+       if (seq_len > sizeof(u_int64_t)) {
                wpa_printf(MSG_DEBUG, "%s: seq_len %zu too big",
                        __func__, seq_len);
                return -2;
@@ -348,6 +366,8 @@ 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;
@@ -362,6 +382,8 @@ 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;
@@ -414,6 +436,8 @@ wpa_driver_bsd_associate(void *priv, struct wpa_driver_associate_params *params)
                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;
 }
 
@@ -441,18 +465,53 @@ static int
 wpa_driver_bsd_scan(void *priv, const u8 *ssid, size_t ssid_len)
 {
        struct wpa_driver_bsd_data *drv = priv;
+       struct ieee80211_scan_req sr;
        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 || setifflags(drv, flags | IFF_UP) != 0)
+       if (getifflags(drv, &flags) != 0) {
+               wpa_printf(MSG_DEBUG, "%s did not mark interface UP", __func__);
                return -1;
-
-       /* set desired ssid before scan */
-       if (wpa_driver_bsd_set_ssid(drv, ssid, ssid_len) < 0)
+       }
+       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 (ssid_len != 0) {
+               /* XXX ssid_len must be <= IEEE80211_NWID_LEN */
+               memcpy(sr.sr_ssid[sr.sr_nssid].ssid, ssid, ssid_len);
+               sr.sr_ssid[sr.sr_nssid].len = ssid_len;
+               sr.sr_nssid++;
+       }
+       if (drv->lastssid_len != 0 &&
+           (drv->lastssid_len != ssid_len ||
+            memcmp(drv->lastssid, ssid, ssid_len) != 0)) {
+               /*
+                * If we are scanning because we received a deauth
+                * and the scan cache is warm then we'll find the
+                * ap there and short circuit a full-blown scan.
+                */
+               memcpy(sr.sr_ssid[sr.sr_nssid].ssid, drv->lastssid,
+                   drv->lastssid_len);
+               sr.sr_ssid[sr.sr_nssid].len = drv->lastssid_len;
+               sr.sr_nssid++;
+               /* NB: clear so we don't retry w/o associating first */
+               drv->lastssid_len = 0;
+       }
+       if (sr.sr_nssid != 0)           /* NB: check scan cache first */
+               sr.sr_flags |= IEEE80211_IOC_SCAN_CHECK;
 
        /* NB: net80211 delivers a scan complete event so no need to poll */
-       return set80211param(drv, IEEE80211_IOC_SCAN_REQ, 0);
+       return set80211var(drv, IEEE80211_IOC_SCAN_REQ, &sr, sizeof(sr));
 }
 
 #include <net/route.h>
@@ -601,14 +660,14 @@ getmaxrate(const uint8_t rates[15], uint8_t nrates)
 
 /* unalligned little endian access */     
 #define LE_READ_4(p)                                   \
-       ((uint32_t)                                     \
-        ((((const uint8_t *)(p))[0]      ) |           \
-         (((const uint8_t *)(p))[1] <<  8) |           \
-         (((const uint8_t *)(p))[2] << 16) |           \
-         (((const uint8_t *)(p))[3] << 24)))
+       ((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 uint8_t *frm)
+iswpaoui(const u_int8_t *frm)
 {
        return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI);
 }
@@ -641,9 +700,9 @@ wpa_driver_bsd_get_scan_results(void *priv,
                wsr->noise = sr->isr_noise;
                wsr->qual = sr->isr_rssi;
                wsr->level = 0;         /* XXX? */
-               wsr->caps = sr->isr_capinfo2;
+               wsr->caps = sr->isr_capinfo;
                wsr->maxrate = getmaxrate(sr->isr_rates, sr->isr_nrates);
-               vp = (uint8_t *)(sr+1);
+               vp = ((u_int8_t *)sr) + sr->isr_ie_off;
                memcpy(wsr->ssid, vp, sr->isr_ssid_len);
                if (sr->isr_ie_len > 0) {
                        vp += sr->isr_ssid_len;
@@ -681,12 +740,34 @@ wpa_driver_bsd_get_scan_results(void *priv,
 #undef min
 }
 
+#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)
 {
-#define        GETPARAM(drv, param, v) \
-       (((v) = get80211param(drv, param)) != -1)
        struct wpa_driver_bsd_data *drv;
+       struct ieee80211_devcaps_req devcaps;
+       int flags;
 
        drv = malloc(sizeof(*drv));
        if (drv == NULL)
@@ -707,14 +788,31 @@ wpa_driver_bsd_init(void *ctx, const char *ifname)
        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);
 
-       drv->ctx = ctx;
-       strncpy(drv->ifname, ifname, sizeof(drv->ifname));
+       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",
@@ -736,7 +834,18 @@ wpa_driver_bsd_init(void *ctx, const char *ifname)
                           "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));
@@ -749,8 +858,8 @@ fail:
 fail1:
        free(drv);
        return NULL;
-#undef GETPARAM
 }
+#undef GETPARAM
 
 static void
 wpa_driver_bsd_deinit(void *priv)
@@ -763,9 +872,17 @@ wpa_driver_bsd_deinit(void *priv)
                (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)
-               wpa_printf(MSG_DEBUG, "%s: failed to restore roaming state",
-                       __func__);
+       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 */
diff --git a/usr.sbin/802_11/wpa_supplicant/driver_wired.c b/usr.sbin/802_11/wpa_supplicant/driver_wired.c
new file mode 100644 (file)
index 0000000..ed9efb9
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * WPA Supplicant - wired Ethernet driver interface
+ * Copyright (c) 2005-2007, Jouni Malinen <j@w1.fi>
+ *
+ * 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: head/usr.sbin/wpa/wpa_supplicant/driver_wired.c 189263 2009-03-02 02:28:22Z sam $
+ */
+
+#include "includes.h"
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <net/if_dl.h>
+
+#include "common.h"
+#include "drivers/driver.h"
+#include "wpa.h"
+
+static const u8 pae_group_addr[ETH_ALEN] =
+{ 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03 };
+
+struct wpa_driver_wired_data {
+       int     sock;
+       char    ifname[IFNAMSIZ + 1];
+       int     multi;
+       int     flags;
+       void    *ctx;
+};
+
+static int
+getifflags(struct wpa_driver_wired_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_wired_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_wired_get_ssid(void *priv, u8 *ssid)
+{
+       ssid[0] = 0;
+       return 0;
+}
+
+static int
+wpa_driver_wired_get_bssid(void *priv, u8 *bssid)
+{
+       /* Report PAE group address as the "BSSID" for wired connection. */
+       os_memcpy(bssid, pae_group_addr, ETH_ALEN);
+       return 0;
+}
+
+static int
+siocmulti(struct wpa_driver_wired_data *drv, int op, const u8 *addr)
+{
+       struct ifreq ifr;
+       struct sockaddr_dl *dlp;
+
+       os_memset(&ifr, 0, sizeof(ifr));
+       os_strncpy(ifr.ifr_name, drv->ifname, IFNAMSIZ);
+       dlp = (struct sockaddr_dl *) &ifr.ifr_addr;
+       dlp->sdl_len = sizeof(struct sockaddr_dl);
+       dlp->sdl_family = AF_LINK;
+       dlp->sdl_index = 0;
+       dlp->sdl_nlen = 0;
+       dlp->sdl_alen = ETH_ALEN;
+       dlp->sdl_slen = 0;
+       os_memcpy(LLADDR(dlp), addr, ETH_ALEN); 
+       if (ioctl(drv->sock, op, (caddr_t) &ifr) < 0) {
+               wpa_printf(MSG_INFO, "ioctl[%s]: %s", op == SIOCADDMULTI ?
+                   "SIOCADDMULTI" : "SIOCDELMULTI", strerror(errno));
+               return -1;
+       }
+       return 0;
+}
+
+static void *
+wpa_driver_wired_init(void *ctx, const char *ifname)
+{
+       struct wpa_driver_wired_data *drv;
+       int flags;
+
+       drv = os_zalloc(sizeof(*drv));
+       if (drv == NULL)
+               return NULL;
+       os_strncpy(drv->ifname, ifname, sizeof(drv->ifname));
+       drv->sock = socket(PF_INET, SOCK_DGRAM, 0);
+       if (drv->sock < 0)
+               goto fail1;
+       drv->ctx = ctx;
+
+       if (getifflags(drv, &drv->flags) < 0) {
+               wpa_printf(MSG_INFO, "%s: Unable to get interface flags",
+                   __func__);
+               goto fail;
+       }
+       flags = drv->flags | IFF_UP;            /* NB: force interface up */
+
+       /* 
+        * Arrange to receive PAE mcast frames.  Try to add an
+        * explicit mcast address.  If that fails, fallback to
+        * the all multicast mechanism.
+        */
+       if (siocmulti(drv, SIOCADDMULTI, pae_group_addr) == 0) {
+               wpa_printf(MSG_DEBUG, "%s: Added PAE multicast address",
+                   __func__);
+               drv->multi = 1;
+       } else if ((drv->flags & IFF_ALLMULTI) == 0)
+               flags |= IFF_ALLMULTI;
+
+       if (flags != drv->flags) {
+               if (setifflags(drv, flags) < 0) {
+                       wpa_printf(MSG_INFO, "%s: Failed to set interface flags",
+                           __func__);
+                       goto fail;
+               }
+               if ((flags ^ drv->flags) & IFF_ALLMULTI)
+                       wpa_printf(MSG_DEBUG, "%s: Enabled all-multi mode",
+                           __func__);
+       }
+       return drv;
+fail:
+       close(drv->sock);
+fail1:
+       free(drv);
+       return NULL;
+}
+
+static void
+wpa_driver_wired_deinit(void *priv)
+{
+       struct wpa_driver_wired_data *drv = priv;
+
+       if (drv->multi) {
+               if (siocmulti(drv, SIOCDELMULTI, pae_group_addr) < 0) {
+                       wpa_printf(MSG_DEBUG, "%s: Failed to remove PAE "
+                           "multicast " "group (SIOCDELMULTI)", __func__);
+               }
+       }
+       if (setifflags(drv, drv->flags) < 0) {
+               wpa_printf(MSG_INFO, "%s: Failed to restore interface flags",
+                          __func__);
+       }
+       (void) close(drv->sock);
+       os_free(drv);
+}
+
+const struct wpa_driver_ops wpa_driver_wired_ops = {
+       .name           = "wired",
+       .desc           = "BSD wired Ethernet driver",
+       .get_ssid       = wpa_driver_wired_get_ssid,
+       .get_bssid      = wpa_driver_wired_get_bssid,
+       .init           = wpa_driver_wired_init,
+       .deinit         = wpa_driver_wired_deinit,
+};
diff --git a/usr.sbin/802_11/wpa_supplicant/driver_wired.c.patch b/usr.sbin/802_11/wpa_supplicant/driver_wired.c.patch
deleted file mode 100644 (file)
index b816b82..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-$DragonFly: src/usr.sbin/802_11/wpa_supplicant/driver_wired.c.patch,v 1.1 2007/08/07 11:25:37 sephe Exp $
-diff -urp wpa_supplicant-0.5.8/driver_wired.c /usr/src/contrib/wpa_supplicant-0.5.8/driver_wired.c
---- driver_wired.c     2007-05-29 08:41:52.000000000 +0800
-+++ driver_wired.c     2007-07-22 11:35:36.000000000 +0800
-@@ -18,9 +18,9 @@
- #ifdef __linux__
- #include <netpacket/packet.h>
- #endif /* __linux__ */
--#ifdef __FreeBSD__
-+#if defined(__FreeBSD__) || defined(__DragonFly__)
- #include <net/if_dl.h>
--#endif /* __FreeBSD__ */
-+#endif /* __FreeBSD__ || __DragonFly__ */
- #include "common.h"
- #include "driver.h"
-@@ -119,7 +119,7 @@ static int wpa_driver_wired_multi(const 
-       ifr.ifr_hwaddr.sa_family = AF_UNSPEC;
-       os_memcpy(ifr.ifr_hwaddr.sa_data, addr, ETH_ALEN);
- #endif /* __linux__ */
--#ifdef __FreeBSD__
-+#if defined(__FreeBSD__) || defined(__DragonFly__)
-       {
-               struct sockaddr_dl *dlp;
-               dlp = (struct sockaddr_dl *) &ifr.ifr_addr;
-@@ -131,7 +131,7 @@ static int wpa_driver_wired_multi(const 
-               dlp->sdl_slen = 0;
-               os_memcpy(LLADDR(dlp), addr, ETH_ALEN); 
-       }
--#endif /* __FreeBSD__ */
-+#endif /* __FreeBSD__ || __DragonFly__ */
-       if (ioctl(s, add ? SIOCADDMULTI : SIOCDELMULTI, (caddr_t) &ifr) < 0) {
-               perror("ioctl[SIOC{ADD/DEL}MULTI]");
diff --git a/usr.sbin/802_11/wpa_supplicant/events.c.patch b/usr.sbin/802_11/wpa_supplicant/events.c.patch
deleted file mode 100644 (file)
index 2eb4914..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-$DragonFly: src/usr.sbin/802_11/wpa_supplicant/events.c.patch,v 1.1 2007/08/07 11:25:37 sephe Exp $
-diff -urp wpa_supplicant-0.5.8/events.c /usr/src/contrib/wpa_supplicant-0.5.8/events.c
---- events.c   2007-05-29 08:39:51.000000000 +0800
-+++ events.c   2007-07-22 12:50:20.000000000 +0800
-@@ -802,6 +802,18 @@ wpa_supplicant_event_michael_mic_failure
- }
-+#ifdef CONFIG_TERMINATE_ONLASTIF
-+static int any_interfaces(struct wpa_supplicant *head)
-+{
-+      struct wpa_supplicant *wpa_s;
-+
-+      for (wpa_s = head; wpa_s != NULL; wpa_s = wpa_s->next)
-+              if (!wpa_s->interface_removed)
-+                      return 1;
-+      return 0;
-+}
-+#endif /* CONFIG_TERMINATE_ONLASTIF */
-+
- static void
- wpa_supplicant_event_interface_status(struct wpa_supplicant *wpa_s,
-                                     union wpa_event_data *data)
-@@ -826,6 +838,11 @@ wpa_supplicant_event_interface_status(st
-               wpa_supplicant_mark_disassoc(wpa_s);
-               l2_packet_deinit(wpa_s->l2);
-               wpa_s->l2 = NULL;
-+#ifdef CONFIG_TERMINATE_ONLASTIF
-+              /* check if last interface */
-+              if (!any_interfaces(wpa_s->global->ifaces))
-+                      eloop_terminate();
-+#endif /* CONFIG_TERMINATE_ONLASTIF */
-               break;
-       }
- }
index e6336b1..905abb1 100644 (file)
@@ -2,8 +2,7 @@
 #define _NTDDNDIS_H_
 
 /*
- * $FreeBSD: src/usr.sbin/wpa/wpa_supplicant/ntddndis.h,v 1.2.2.1 2005/10/27 17:06:47 wpaul Exp $
- * $DragonFly: src/usr.sbin/802_11/wpa_supplicant/ntddndis.h,v 1.1 2006/06/24 07:29:44 sephe Exp $
+ * $FreeBSD: head/usr.sbin/wpa/wpa_supplicant/ntddndis.h 151517 2005-10-20 16:49:31Z wpaul $
  */
 
 /*
@@ -28,7 +27,5 @@ typedef char * PCHAR;
 #define FALSE 0
 
 #define OID_802_3_CURRENT_ADDRESS               0x01010102
-#define        OID_802_3_MULTICAST_LIST                0x01010103
-
 
 #endif /* _NTDDNDIS_H_ */
index 37aab2a..fb89507 100644 (file)
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: src/usr.sbin/wpa/wpa_supplicant/wpa_supplicant.8,v 1.2 2005/06/27 06:40:43 ru Exp $
-.\" $DragonFly: src/usr.sbin/802_11/wpa_supplicant/wpa_supplicant.8,v 1.7 2008/03/09 11:04:35 swildner Exp $
+.\" $FreeBSD: head/usr.sbin/wpa/wpa_supplicant/wpa_supplicant.8 195644 2009-07-12 19:58:52Z sam $
+.\" $DragonFly$
 .\"
-.Dd July 22, 2007
+.Dd March 24, 2008
 .Dt WPA_SUPPLICANT 8
 .Os
 .Sh NAME
 .Nd "WPA/802.11i Supplicant for wireless network devices"
 .Sh SYNOPSIS
 .Nm
-.Op Fl BdehLqvw
+.Op Fl BdehLqsvw
 .Fl i Ar ifname
 .Fl c Ar config-file
-.Op Fl N i Ar ifname Fl c Ar config-file ...
 .Sh DESCRIPTION
 The
 .Nm
@@ -102,12 +101,20 @@ Show help text.
 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.
+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.
@@ -115,24 +122,21 @@ in the background.
 Include key information in debugging output.
 .It Fl L
 Display the license for this program on the terminal and exit.
-.It Fl N i Ar ifname Fl c Ar config-file ...
-Specify an additional interface and configuration file.
-If multiple interfaces are specified then
-.Nm
-will manage them all with a single process.
 .El
 .Sh SEE ALSO
-.Xr acx 4 ,
+.Xr an 4 ,
 .Xr ath 4 ,
-.Xr bwi 4 ,
+.Xr ipw 4 ,
 .Xr iwi 4 ,
-.Xr iwl 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
@@ -144,7 +148,7 @@ utility first appeared in
 The
 .Nm
 utility was written by
-.An Jouni Malinen Aq jkmaline@cc.hut.fi .
+.An Jouni Malinen Aq j@w1.fi .
 This manual page is derived from the
 .Pa README
 file included in the
index 7e6fadb..62c792a 100644 (file)
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: src/usr.sbin/wpa/wpa_supplicant/wpa_supplicant.conf.5,v 1.9 2007/07/11 16:04:08 sam Exp $
-.\" $DragonFly: src/usr.sbin/802_11/wpa_supplicant/wpa_supplicant.conf.5,v 1.4 2007/08/07 11:25:37 sephe Exp $
+.\" $FreeBSD: head/usr.sbin/wpa/wpa_supplicant/wpa_supplicant.conf.5 195644 2009-07-12 19:58:52Z sam $
 .\"
-.Dd July 22, 2007
+.Dd July 8, 2007
 .Dt WPA_SUPPLICANT.CONF 5
 .Os
 .Sh NAME
@@ -220,7 +219,11 @@ an 8-63 character
 passphrase.
 .Tn ASCII
 passphrases are dynamically converted to a 256-bit key at runtime
-using the network SSID.
+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.
@@ -236,10 +239,10 @@ used only as a Phase 2 method with EAP-PEAP or EAP-TTLS),
 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 method with EAP-PEAP or EAP-TTLS),
+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 method with EAP-PEAP or EAP-TTLS),
+used only as a Phase 2 metod with EAP-PEAP or EAP-TTLS),
 .Li TLS
 (EAP-TLS, client and server certificate),
 .Li PEAP
@@ -400,7 +403,7 @@ PAC is being provisioned or refreshed.
 Enable/disable EAP workarounds for various interoperability issues
 with misbehaving authentication servers.
 By default these workarounds are enabled.
-String EAP conformance can be configured by setting this to 0.
+Strict EAP conformance can be configured by setting this to 0.
 .El
 .Sh CERTIFICATES
 Some EAP authentication methods require use of certificates.
@@ -515,8 +518,14 @@ network={
         wep_key0=42FEEDDEAFBABEDEAFBEEFAA55
 }
 .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 SEE ALSO
 .Xr wpa_cli 8 ,
+.Xr wpa_passphrase 8 ,
 .Xr wpa_supplicant 8
 .Sh HISTORY
 The
@@ -533,4 +542,4 @@ and
 files in the
 .Nm wpa_supplicant
 distribution provided by
-.An Jouni Malinen Aq jkmaline@cc.hut.fi .
+.An Jouni Malinen Aq j@w1.fi .