diff --git a/usr.sbin/wpa/Makefile b/usr.sbin/wpa/Makefile index ce26e3ac5e87..31b3c746cb41 100644 --- a/usr.sbin/wpa/Makefile +++ b/usr.sbin/wpa/Makefile @@ -1,5 +1,5 @@ # $FreeBSD$ -SUBDIR= wpa_supplicant wpa_cli hostapd hostapd_cli +SUBDIR= wpa_supplicant wpa_cli hostapd hostapd_cli ndis_events .include diff --git a/usr.sbin/wpa/ndis_events/Makefile b/usr.sbin/wpa/ndis_events/Makefile new file mode 100644 index 000000000000..07caf5a48465 --- /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 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 000000000000..4735db0fa7cf --- /dev/null +++ b/usr.sbin/wpa/ndis_events/ndis_events.8 @@ -0,0 +1,118 @@ +.\" Copyright (c) 2005 +.\" Bill Paul 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 October 10, 2005 +.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 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] +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 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 ndisapi 9 , +.Xr wpa_supplicant 8 +.Sh HISTORY +The +.Nm +utility first appeared in +.Fx 7.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 000000000000..1741a645683e --- /dev/null +++ b/usr.sbin/wpa/ndis_events/ndis_events.c @@ -0,0 +1,330 @@ +/*- + * Copyright (c) 2005 + * Bill Paul . 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 +__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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +static int verbose = 0; +static int debug = 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 void announce_event(char *, int, struct sockaddr_in *); +static void usage(char *); + +static void +dbgmsg(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + if (debug) + vwarnx(fmt, ap); + else + vsyslog(LOG_INFO, 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 void +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) + return; + + 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); + dbgmsg("failed to read event info from %s\n", ifname); + return; + } + + if (e->ne_sts == NDIS_STATUS_MEDIA_CONNECT) { + type = EVENT_CONNECT; + if (verbose) + dbgmsg("Received a connect event for %s", ifname); + } + if (e->ne_sts == NDIS_STATUS_MEDIA_DISCONNECT) { + type = EVENT_DISCONNECT; + if (verbose) + dbgmsg("Received a disconnect event for %s", ifname); + } + 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) + return; + 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); + return; + } + *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; +} + +static void +usage(progname) + char *progname; +{ + fprintf(stderr, "Usage: ndis_events [-d] [-v]\n", progname); + 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, "dv")) != -1) { + switch(ch) { + case 'd': + debug++; + break; + case 'v': + verbose++; + break; + default: + usage(PROGNAME); + 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")) + announce_event(ifname, s, &sin); + else { + if (verbose) + dbgmsg("Skipping ifinfo message from %s", + ifname); + } + } + + /* NOTREACHED */ + exit(0); +} diff --git a/usr.sbin/wpa/wpa_supplicant/Makefile b/usr.sbin/wpa/wpa_supplicant/Makefile index 7ab6414c0e56..19e0b24667df 100644 --- a/usr.sbin/wpa/wpa_supplicant/Makefile +++ b/usr.sbin/wpa/wpa_supplicant/Makefile @@ -6,12 +6,14 @@ WPA_SUPPLICANT_DISTDIR?= ${.CURDIR}/../../../contrib/wpa_supplicant PROG= wpa_supplicant SRCS= config.c eloop.c common.c md5.c rc4.c sha1.c aes_wrap.c \ wpa_supplicant.c wpa.c \ - ctrl_iface.c l2_packet.c drivers.c driver_freebsd.c + ctrl_iface.c l2_packet.c drivers.c driver_freebsd.c \ + driver_ndis.c driver_ndis_.c Packet32.c MAN= wpa_supplicant.8 wpa_supplicant.conf.5 CFLAGS+= -I${.CURDIR} -I${WPA_SUPPLICANT_DISTDIR} CFLAGS+= -DCONFIG_DRIVER_BSD +CFLAGS+= -DCONFIG_DRIVER_NDIS CFLAGS+= -DCONFIG_CTRL_IFACE CFLAGS+= -g DPADD+= ${LIBPCAP} diff --git a/usr.sbin/wpa/wpa_supplicant/Packet32.c b/usr.sbin/wpa/wpa_supplicant/Packet32.c new file mode 100644 index 000000000000..dafa6b967e4a --- /dev/null +++ b/usr.sbin/wpa/wpa_supplicant/Packet32.c @@ -0,0 +1,388 @@ +/*- + * Copyright (c) 2005 + * Bill Paul . 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 +__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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#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]; +}; + +void * +PacketOpenAdapter(iface) + CHAR *iface; +{ + struct adapter *a; + int s; + int ifflags; + struct ifreq ifr; + + 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; + snprintf(a->name, IFNAMSIZ, "%s", iface); + + 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(iface, set, oid) + 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(namelist, len) + 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(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; + + /* 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, "ndis", sdl->sdl_nlen)) { + if ((spc + sdl->sdl_nlen) > *len) { + free(buf); + return(ENOSPC); + } + 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, "ndis", sdl->sdl_nlen)) { + if ((spc + sdl->sdl_nlen) > *len) { + free(buf); + return(ENOSPC); + } + 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(0); +} + +void +PacketCloseAdapter(iface) + void *iface; +{ + struct adapter *a; + struct ifreq ifr; + + if (iface == NULL) + return; + + a = iface; + + 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 000000000000..a3f715d79ff3 --- /dev/null +++ b/usr.sbin/wpa/wpa_supplicant/Packet32.h @@ -0,0 +1,66 @@ +/*- + * Copyright (c) 2005 + * Bill Paul . 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 +#include + +struct PACKET_OID_DATA { + uint32_t Oid; + uint32_t Length; + uint8_t Data[1]; +}; + + +typedef struct PACKET_OID_DATA PACKET_OID_DATA; + +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/ntddndis.h b/usr.sbin/wpa/wpa_supplicant/ntddndis.h new file mode 100644 index 000000000000..97dd608eab06 --- /dev/null +++ b/usr.sbin/wpa/wpa_supplicant/ntddndis.h @@ -0,0 +1,30 @@ +#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; + +#define TRUE 1 +#define FALSE 0 + +#define OID_802_3_CURRENT_ADDRESS 0x01010102 + +#endif /* _NTDDNDIS_H_ */