Enable -D ndis support in wpa_supplicant and add the ndis_events utility.

This allows wpa_supplicant to work with WPA and WPA2 compliant NDIS
drivers.
This commit is contained in:
Bill Paul 2005-10-10 17:51:12 +00:00
parent 475b5abcb7
commit 8ad9af2c27
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=151214
8 changed files with 944 additions and 2 deletions

View File

@ -1,5 +1,5 @@
# $FreeBSD$
SUBDIR= wpa_supplicant wpa_cli hostapd hostapd_cli
SUBDIR= wpa_supplicant wpa_cli hostapd hostapd_cli ndis_events
.include <bsd.subdir.mk>

View File

@ -0,0 +1,8 @@
# $FreeBSD$
PROG= ndis_events
SRCS+= ndis_events.c
MAN= ndis_events.8
.include <bsd.prog.mk>

View File

@ -0,0 +1,118 @@
.\" 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 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 .

View File

@ -0,0 +1,330 @@
/*-
* 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;
#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);
}

View File

@ -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}

View File

@ -0,0 +1,388 @@
/*-
* 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 <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];
};
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

View File

@ -0,0 +1,66 @@
/*-
* 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 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_ */

View File

@ -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_ */