summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2005-05-25 07:40:50 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2005-05-25 07:40:50 +0000
commit195394ca0fd77eaf853201a38a23a40bfb1d4e91 (patch)
treefa1f8457ab4564ce39538fc88528d2959064a196
parentdddc74b20f5c57dc55e2d67c27ee9a237c8021f3 (diff)
add ifconfig -M option to replace wicontrol -L and -l for ap scanning
and node listing. wicontrol is not supported by net80211 drivers anymore. further improvements will be done. ok dlg@, jsg@
-rw-r--r--sbin/ifconfig/ifconfig.811
-rw-r--r--sbin/ifconfig/ifconfig.c209
-rw-r--r--sbin/wicontrol/wicontrol.c6
-rw-r--r--sys/net80211/ieee80211.c9
-rw-r--r--sys/net80211/ieee80211.h33
-rw-r--r--sys/net80211/ieee80211_ioctl.c937
-rw-r--r--sys/net80211/ieee80211_ioctl.h90
-rw-r--r--sys/net80211/ieee80211_node.c38
-rw-r--r--sys/net80211/ieee80211_node.h5
-rw-r--r--sys/net80211/ieee80211_radiotap.h15
-rw-r--r--sys/net80211/ieee80211_var.h41
-rw-r--r--usr.sbin/hostapd/privsep.c32
12 files changed, 491 insertions, 935 deletions
diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8
index eef1f889167..980ef6b6c54 100644
--- a/sbin/ifconfig/ifconfig.8
+++ b/sbin/ifconfig/ifconfig.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ifconfig.8,v 1.104 2005/05/24 02:45:18 reyk Exp $
+.\" $OpenBSD: ifconfig.8,v 1.105 2005/05/25 07:40:49 reyk Exp $
.\" $NetBSD: ifconfig.8,v 1.11 1996/01/04 21:27:29 pk Exp $
.\" $FreeBSD: ifconfig.8,v 1.16 1998/02/01 07:03:29 steve Exp $
.\"
@@ -47,15 +47,11 @@
.Oc
.Op Ar parameters
.Nm ifconfig
-.Fl A | Am | a | am
+.Fl aAmM
.Op Ar address_family
.Nm ifconfig
.Fl C
.Nm ifconfig
-.Fl m
-.Ar interface
-.Op Ar address_family
-.Nm ifconfig
.Ar interface
.Cm create
.Nm ifconfig
@@ -165,6 +161,9 @@ but additionally prints interface media information for all interfaces.
Print the names of all network pseudo-devices that
can be created dynamically at runtime using
.Cm ifconfig create .
+.It Fl M
+For the chosen 802.11 interfaces, show the results of an access point
+scan. In Host AP mode, this will dump the list of known nodes.
.It Fl m Ar interface
Print media information for a given
.Ar interface .
diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
index ccc1ef1e70e..cb255485969 100644
--- a/sbin/ifconfig/ifconfig.c
+++ b/sbin/ifconfig/ifconfig.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ifconfig.c,v 1.139 2005/05/24 07:51:53 reyk Exp $ */
+/* $OpenBSD: ifconfig.c,v 1.140 2005/05/25 07:40:49 reyk Exp $ */
/* $NetBSD: ifconfig.c,v 1.40 1997/10/01 02:19:43 enami Exp $ */
/*
@@ -136,6 +136,7 @@ int clearaddr, s;
int newaddr = 0;
int af = AF_INET;
int mflag;
+int net80211flag;
int explicit_prefix = 0;
#ifdef INET6
int Lflag = 1;
@@ -358,6 +359,7 @@ int getinfo(struct ifreq *, int);
void getsock(int);
void printif(struct ifreq *, int);
void printb(char *, unsigned short, char *);
+void printb_status(unsigned short, char *);
void status(int, struct sockaddr_dl *);
void usage(int);
const char *get_string(const char *, const char *, u_int8_t *, int *);
@@ -398,6 +400,8 @@ void xns_getaddr(const char *, int);
void ipx_status(int);
void ipx_getaddr(const char *, int);
void ieee80211_status(void);
+void ieee80211_listnodes(void);
+void ieee80211_printnode(struct ieee80211_nodereq *);
/* Known address families */
const struct afswtch {
@@ -447,29 +451,42 @@ main(int argc, char *argv[])
exit(0);
}
argc--, argv++;
- if (!strcmp(*argv, "-a"))
- aflag = 1;
- else if (!strcmp(*argv, "-A")) {
- aflag = 1;
- ifaliases = 1;
- } else if (!strcmp(*argv, "-ma") || !strcmp(*argv, "-am")) {
- aflag = 1;
- mflag = 1;
- } else if (!strcmp(*argv, "-mA") || !strcmp(*argv, "-Am")) {
- aflag = 1;
- ifaliases = 1;
- mflag = 1;
- } else if (!strcmp(*argv, "-m")) {
- mflag = 1;
- argc--, argv++;
- if (argc < 1)
- usage(1);
- if (strlcpy(name, *argv, sizeof(name)) >= IFNAMSIZ)
- errx(1, "interface name '%s' too long", *argv);
- } else if (!strcmp(*argv, "-C")) {
- Cflag = 1;
- } else if (*argv[0] == '-') {
- usage(0);
+ if (*argv[0] == '-') {
+ int nomore = 0;
+
+ for (i = 1; argv[0][i]; i++) {
+ switch (argv[0][i]) {
+ case 'a':
+ aflag = 1;
+ nomore = 1;
+ break;
+ case 'A':
+ aflag = 1;
+ ifaliases = 1;
+ nomore = 1;
+ break;
+ case 'm':
+ mflag = 1;
+ break;
+ case 'M':
+ net80211flag = 1;
+ break;
+ case 'C':
+ Cflag = 1;
+ nomore = 1;
+ break;
+ default:
+ usage(1);
+ break;
+ }
+ }
+ if (nomore == 0) {
+ argc--, argv++;
+ if (argc < 1)
+ usage(1);
+ if (strlcpy(name, *argv, sizeof(name)) >= IFNAMSIZ)
+ errx(1, "interface name '%s' too long", *argv);
+ }
} else if (strlcpy(name, *argv, sizeof(name)) >= IFNAMSIZ)
errx(1, "interface name '%s' too long", *argv);
argc--, argv++;
@@ -1212,6 +1229,9 @@ setifnwkey(const char *val, int d)
struct ieee80211_nwkey nwkey;
u_int8_t keybuf[IEEE80211_WEP_NKID][16];
+ bzero(&nwkey, sizeof(nwkey));
+ bzero(&keybuf, sizeof(keybuf));
+
nwkey.i_wepon = IEEE80211_NWKEY_WEP;
nwkey.i_defkid = 1;
if (d == -1) {
@@ -1257,11 +1277,6 @@ setifnwkey(const char *val, int d)
i = 1;
}
}
- /* zero out any unset keys */
- for (; i < IEEE80211_WEP_NKID; i++) {
- nwkey.i_key[i].i_keylen = 0;
- nwkey.i_key[i].i_keydat = NULL;
- }
(void)strlcpy(nwkey.i_name, name, sizeof(nwkey.i_name));
if (ioctl(s, SIOCS80211NWKEY, (caddr_t)&nwkey) == -1)
warn("SIOCS80211NWKEY");
@@ -1405,7 +1420,7 @@ ieee80211_status(void)
if (len > IEEE80211_NWID_LEN)
len = IEEE80211_NWID_LEN;
fputs("nwid ", stdout);
- print_string(nwid.i_nwid, nwid.i_len);
+ print_string(nwid.i_nwid, len);
putchar(' ');
}
@@ -1483,11 +1498,108 @@ ieee80211_status(void)
printf("powersave on (%dms sleep) ", power.i_maxsleep);
if (itxpower == 0)
- printf("%ddBm %s", txpower.i_val,
- txpower.i_mode == IEEE80211_TXPOWER_MODE_AUTO ?
+ printf("%ddBm %s", txpower.i_val,
+ txpower.i_mode == IEEE80211_TXPOWER_MODE_AUTO ?
"(auto) " : "");
putchar('\n');
+ if (net80211flag)
+ ieee80211_listnodes();
+}
+
+void
+ieee80211_listnodes(void)
+{
+ struct ieee80211_nodereq_all na;
+ struct ieee80211_nodereq nr[512];
+ struct ifreq ifr;
+ int i, ret, down = 0;
+
+ if ((flags & IFF_UP) == 0) {
+ down = 1;
+ setifflags("up", IFF_UP);
+ }
+
+ bzero(&ifr, sizeof(ifr));
+ strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+
+ if (ioctl(s, SIOCS80211SCAN, (caddr_t)&ifr) != 0)
+ goto done;
+
+ bzero(&na, sizeof(na));
+ bzero(&nr, sizeof(nr));
+ na.na_node = nr;
+ na.na_size = sizeof(nr);
+ strlcpy(na.na_ifname, name, sizeof(na.na_ifname));
+ ret = 1;
+
+ if (ioctl(s, SIOCG80211ALLNODES, &na) != 0) {
+ warn("SIOCG80211ALLNODES");
+ goto done;
+ }
+
+ if (!na.na_nodes)
+ printf("\t\tnone\n");
+
+ for (i = 0; i < na.na_nodes; i++) {
+ printf("\t\t");
+ ieee80211_printnode(&nr[i]);
+ putchar('\n');
+ }
+
+ ret = 0;
+
+ done:
+ if (down)
+ setifflags("restore", -IFF_UP);
+
+ if (ret != 0)
+ exit(1);
+
+}
+
+void
+ieee80211_printnode(struct ieee80211_nodereq *nr)
+{
+ int len, i, isap;
+
+ if (nr->nr_flags & IEEE80211_NODEREQ_AP) {
+ len = nr->nr_nwid_len;
+ if (len > IEEE80211_NWID_LEN)
+ len = IEEE80211_NWID_LEN;
+ printf("nwid ");
+ print_string(nr->nr_nwid, len);
+ putchar(' ');
+
+ printf("chan %u ", nr->nr_channel);
+ }
+
+ if (nr->nr_flags & IEEE80211_NODEREQ_AP)
+ printf("bssid %s ",
+ ether_ntoa((struct ether_addr*)nr->nr_bssid));
+ else
+ printf("lladdr %s ",
+ ether_ntoa((struct ether_addr*)nr->nr_macaddr));
+
+ printf("%udB ", nr->nr_rssi);
+
+ if (nr->nr_pwrsave)
+ printf("powersave ");
+ if (nr->nr_nrates) {
+ /* Only print the fastest rate */
+ printf("%uM",
+ (nr->nr_rates[nr->nr_nrates - 1] & IEEE80211_RATE_VAL) / 2);
+ putchar(' ');
+ }
+ /* ESS is the default, skip it */
+ nr->nr_capinfo &= ~IEEE80211_CAPINFO_ESS;
+ if (nr->nr_capinfo) {
+ printb_status(nr->nr_capinfo, IEEE80211_CAPINFO_BITS);
+ putchar(' ');
+ }
+ if ((nr->nr_flags & IEEE80211_NODEREQ_AP) == 0)
+ printb_status(IEEE80211_NODEREQ_STATE(nr->nr_state),
+ IEEE80211_NODEREQ_STATE_BITS);
}
void
@@ -2016,7 +2128,6 @@ status(int link, struct sockaddr_dl *sdl)
timeslot_status();
trunk_status();
#endif
- ieee80211_status();
getifgroups();
(void) memset(&ifmr, 0, sizeof(ifmr));
@@ -2083,6 +2194,8 @@ status(int link, struct sockaddr_dl *sdl)
putchar('\n');
}
+ ieee80211_status();
+
if (mflag) {
int type, printed_type = 0;
@@ -3331,6 +3444,31 @@ printb(char *s, unsigned short v, char *bits)
}
}
+/*
+ * A simple version of printb for status output
+ */
+void
+printb_status(unsigned short v, char *bits)
+{
+ int i, any = 0;
+ char c;
+
+ bits++;
+ if (bits) {
+ while ((i = *bits++)) {
+ if (v & (1 << (i-1))) {
+ if (any)
+ putchar(',');
+ any = 1;
+ for (; (c = *bits) > 32; bits++)
+ putchar(tolower(c));
+ } else
+ for (; *bits > 32; bits++)
+ ;
+ }
+ }
+}
+
#ifdef INET6
#define SIN6(x) ((struct sockaddr_in6 *) &(x))
struct sockaddr_in6 *sin6tab[] = {
@@ -3455,9 +3593,7 @@ usage(int value)
"\t[802.2] [802.2tr] [802.3] [snap] [EtherII]\n"
"\t[pppoeac access-concentrator] [-pppoeac]\n"
"\t[pppoesvc service] [-pppoesvc]\n"
- " ifconfig -A | -Am | -a | -am [address_family]\n"
- " ifconfig -C\n"
- " ifconfig -m interface [address_family]\n"
+ " ifconfig [-aAmMC] [interface] [address_family]\n"
" ifconfig interface create\n"
" ifconfig interface destroy\n");
exit(value);
@@ -3572,3 +3708,4 @@ setiflladdr(const char *addr, int param)
if (ioctl(s, SIOCSIFLLADDR, (caddr_t)&ifr) < 0)
warn("SIOCSIFLLADDR");
}
+
diff --git a/sbin/wicontrol/wicontrol.c b/sbin/wicontrol/wicontrol.c
index d3b494460d7..9f3a1e24ec8 100644
--- a/sbin/wicontrol/wicontrol.c
+++ b/sbin/wicontrol/wicontrol.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wicontrol.c,v 1.57 2004/11/24 18:11:15 fgsch Exp $ */
+/* $OpenBSD: wicontrol.c,v 1.58 2005/05/25 07:40:49 reyk Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@@ -68,7 +68,7 @@
static const char copyright[] = "@(#) Copyright (c) 1997, 1998, 1999\
Bill Paul. All rights reserved.";
static const char rcsid[] =
- "@(#) $OpenBSD: wicontrol.c,v 1.57 2004/11/24 18:11:15 fgsch Exp $";
+ "@(#) $OpenBSD: wicontrol.c,v 1.58 2005/05/25 07:40:49 reyk Exp $";
#endif
int wi_getval(char *, struct wi_req *);
@@ -122,7 +122,7 @@ wi_getval(char *iface, struct wi_req *wreq)
if (error == -1) {
warn("SIOCGWAVELAN (0x%x)", wreq->wi_type);
- if (errno == ENXIO)
+ if (errno == ENXIO || errno == EINVAL)
exit(1);
}
close(s);
diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c
index dd2a6531467..4139d0ebe4b 100644
--- a/sys/net80211/ieee80211.c
+++ b/sys/net80211/ieee80211.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211.c,v 1.6 2005/04/21 22:47:15 reyk Exp $ */
+/* $OpenBSD: ieee80211.c,v 1.7 2005/05/25 07:40:49 reyk Exp $ */
/* $NetBSD: ieee80211.c,v 1.19 2004/06/06 05:45:29 dyoung Exp $ */
/*-
@@ -204,6 +204,7 @@ ieee80211_ifattach(struct ifnet *ifp)
if ((ic->ic_modecaps & (1<<ic->ic_curmode)) == 0)
ic->ic_curmode = IEEE80211_MODE_AUTO;
ic->ic_des_chan = IEEE80211_CHAN_ANYC; /* any channel is ok */
+ ic->ic_scan_lock = IEEE80211_SCAN_UNLOCKED;
ieee80211_setbasicrates(ic);
(void) ieee80211_setmode(ic, ic->ic_curmode);
@@ -802,13 +803,13 @@ ieee80211_setmode(struct ieee80211com *ic, enum ieee80211_phymode mode)
#undef N
}
-void
+enum ieee80211_phymode
ieee80211_next_mode(struct ifnet *ifp)
{
struct ieee80211com *ic = (void *)ifp;
if (IFM_MODE(ic->ic_media.ifm_cur->ifm_media) != IFM_AUTO)
- return;
+ return (IEEE80211_MODE_AUTO); /* Indicate a wrap around */
/*
* Get the next supported mode
@@ -827,6 +828,8 @@ ieee80211_next_mode(struct ifnet *ifp)
}
ieee80211_setmode(ic, ic->ic_curmode);
+
+ return (ic->ic_curmode);
}
/*
diff --git a/sys/net80211/ieee80211.h b/sys/net80211/ieee80211.h
index 92f01513b51..042a860e083 100644
--- a/sys/net80211/ieee80211.h
+++ b/sys/net80211/ieee80211.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211.h,v 1.8 2005/02/17 18:28:05 reyk Exp $ */
+/* $OpenBSD: ieee80211.h,v 1.9 2005/05/25 07:40:49 reyk Exp $ */
/* $NetBSD: ieee80211.h,v 1.6 2004/04/30 23:51:53 dyoung Exp $ */
/*-
@@ -316,7 +316,36 @@ typedef u_int8_t *ieee80211_mgt_beacon_t;
/* bits 14-15 are reserved */
#define IEEE80211_CAPINFO_BITS "\20\01ESS\02IBSS\03POLLABLE\04POLLREQ\05PRIVACY\06SHORT_PREAMBLE\07PBCC\10CHNL_AGILITY\13SHORT_SLOTTIME\14RSN\16DSSSOFDM"
+/*
+ * Channel attributes
+ */
+#define IEEE80211_CHAN_TURBO 0x0010 /* Turbo channel */
+#define IEEE80211_CHAN_CCK 0x0020 /* CCK channel */
+#define IEEE80211_CHAN_OFDM 0x0040 /* OFDM channel */
+#define IEEE80211_CHAN_2GHZ 0x0080 /* 2 GHz spectrum channel. */
+#define IEEE80211_CHAN_5GHZ 0x0100 /* 5 GHz spectrum channel */
+#define IEEE80211_CHAN_PASSIVE 0x0200 /* Only passive scan allowed */
+#define IEEE80211_CHAN_DYN 0x0400 /* Dynamic CCK-OFDM channel */
+#define IEEE80211_CHAN_GFSK 0x0800 /* GFSK channel (FHSS PHY) */
+#define IEEE80211_CHAN_XR 0x1000 /* Extended range OFDM channel */
+/*
+ * Useful combinations of channel characteristics.
+ */
+#define IEEE80211_CHAN_FHSS \
+ (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
+#define IEEE80211_CHAN_A \
+ (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
+#define IEEE80211_CHAN_B \
+ (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
+#define IEEE80211_CHAN_PUREG \
+ (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
+#define IEEE80211_CHAN_G \
+ (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
+#define IEEE80211_CHAN_T \
+ (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO)
+#define IEEE80211_CHAN_TG \
+ (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO)
/*
* 802.11i/WPA information element (maximally sized).
@@ -412,6 +441,8 @@ enum {
#define IEEE80211_RATE_BASIC 0x80
#define IEEE80211_RATE_VAL 0x7f
+#define IEEE80211_RATE_SIZE 8 /* 802.11 standard */
+#define IEEE80211_RATE_MAXSIZE 15 /* max rates we'll handle */
/* EPR information element flags */
#define IEEE80211_ERP_NON_ERP_PRESENT 0x01
diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c
index 2bfb9e71ba3..d89983aea63 100644
--- a/sys/net80211/ieee80211_ioctl.c
+++ b/sys/net80211/ieee80211_ioctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_ioctl.c,v 1.11 2005/04/03 08:06:14 uwe Exp $ */
+/* $OpenBSD: ieee80211_ioctl.c,v 1.12 2005/05/25 07:40:49 reyk Exp $ */
/* $NetBSD: ieee80211_ioctl.c,v 1.15 2004/05/06 02:58:16 dyoung Exp $ */
/*-
@@ -33,21 +33,10 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-#if defined(__FreeBSD__)
-__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_ioctl.c,v 1.13 2004/03/30 22:57:57 sam Exp $");
-#elif defined(__NetBSD__)
-__KERNEL_RCSID(0, "$NetBSD: ieee80211_ioctl.c,v 1.15 2004/05/06 02:58:16 dyoung Exp $");
-#endif
-
/*
* IEEE 802.11 ioctl support
*/
-#ifdef __NetBSD__
-#include "opt_inet.h"
-#endif
-
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/socket.h>
@@ -59,746 +48,89 @@ __KERNEL_RCSID(0, "$NetBSD: ieee80211_ioctl.c,v 1.15 2004/05/06 02:58:16 dyoung
#include <net/if.h>
#include <net/if_arp.h>
#include <net/if_media.h>
-#if defined(__NetBSD__)
-#include <net/if_ether.h>
-#endif
#ifdef INET
#include <netinet/in.h>
-#if defined(__OpenBSD__)
#include <netinet/if_ether.h>
#endif
-#ifndef __OpenBSD__
-#include <netinet/if_inarp.h>
-#endif
-#endif
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_ioctl.h>
-#if defined(__OpenBSD__)
-#include <dev/ic/if_wi_ieee.h>
-#include <dev/ic/if_wi_hostap.h>
-#else
-#include <dev/ic/wi_ieee.h>
-#endif
+void ieee80211_node2req(struct ieee80211com *, struct ieee80211_node *,
+ struct ieee80211_nodereq *);
+void ieee80211_req2node(struct ieee80211com *, struct ieee80211_nodereq *,
+ struct ieee80211_node *);
-#if defined(__OpenBSD__)
-void node2sta(struct ieee80211com *, struct ieee80211_node *,
- struct hostap_sta *);
-#endif
-
-/*
- * XXX
- * Wireless LAN specific configuration interface, which is compatible
- * with wicontrol(8).
- */
-
-int
-ieee80211_cfgget(struct ifnet *ifp, u_long cmd, caddr_t data)
+void
+ieee80211_node2req(struct ieee80211com *ic, struct ieee80211_node *ni,
+ struct ieee80211_nodereq *nr)
{
- struct ieee80211com *ic = (void *)ifp;
- int i, j, error;
- struct ifreq *ifr = (struct ifreq *)data;
- struct wi_req wreq;
- struct wi_ltv_keys *keys;
- struct wi_apinfo *ap;
- struct ieee80211_node *ni;
- struct ieee80211_rateset *rs;
-#ifdef WICACHE
- struct wi_sigcache wsc;
-#endif /* WICACHE */
- struct wi_scan_p2_hdr *p2;
- struct wi_scan_res *res;
-
- error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
- if (error)
- return error;
- wreq.wi_len = 0;
- switch (wreq.wi_type) {
- case WI_RID_SERIALNO:
- case WI_RID_STA_IDENTITY:
- case WI_RID_CARD_ID:
- case WI_RID_PROCFRAME:
- case WI_RID_SYMBOL_DIVERSITY:
- case WI_RID_ENH_SECURITY:
- case WI_RID_AUTH_STATION:
- /* nothing appropriate */
- break;
- case WI_RID_NODENAME:
- strlcpy((char *)&wreq.wi_val[1], hostname,
- sizeof(wreq.wi_val) - sizeof(wreq.wi_val[0]));
- wreq.wi_val[0] = htole16(strlen(hostname));
- wreq.wi_len = (1 + strlen(hostname) + 1) / 2;
- break;
- case WI_RID_CURRENT_SSID:
- if (ic->ic_state != IEEE80211_S_RUN) {
- wreq.wi_val[0] = 0;
- wreq.wi_len = 1;
- break;
- }
- wreq.wi_val[0] = htole16(ic->ic_bss->ni_esslen);
- memcpy(&wreq.wi_val[1], ic->ic_bss->ni_essid,
- ic->ic_bss->ni_esslen);
- wreq.wi_len = (1 + ic->ic_bss->ni_esslen + 1) / 2;
- break;
- case WI_RID_OWN_SSID:
- case WI_RID_DESIRED_SSID:
- wreq.wi_val[0] = htole16(ic->ic_des_esslen);
- memcpy(&wreq.wi_val[1], ic->ic_des_essid, ic->ic_des_esslen);
- wreq.wi_len = (1 + ic->ic_des_esslen + 1) / 2;
- break;
- case WI_RID_CURRENT_BSSID:
- if (ic->ic_state == IEEE80211_S_RUN)
- IEEE80211_ADDR_COPY(wreq.wi_val, ic->ic_bss->ni_bssid);
- else
- memset(wreq.wi_val, 0, IEEE80211_ADDR_LEN);
- wreq.wi_len = IEEE80211_ADDR_LEN / 2;
- break;
- case WI_RID_CHANNEL_LIST:
- memset(wreq.wi_val, 0, sizeof(wreq.wi_val));
- /*
- * Since channel 0 is not available for DS, channel 1
- * is assigned to LSB on WaveLAN.
- */
- if (ic->ic_phytype == IEEE80211_T_DS)
- i = 1;
- else
- i = 0;
- for (j = 0; i <= IEEE80211_CHAN_MAX; i++, j++)
- if (isset(ic->ic_chan_active, i)) {
- setbit((u_int8_t *)wreq.wi_val, j);
- wreq.wi_len = j / 16 + 1;
- }
- break;
- case WI_RID_OWN_CHNL:
- wreq.wi_val[0] = htole16(
- ieee80211_chan2ieee(ic, ic->ic_ibss_chan));
- wreq.wi_len = 1;
- break;
- case WI_RID_CURRENT_CHAN:
- wreq.wi_val[0] = htole16(
- ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan));
- wreq.wi_len = 1;
- break;
- case WI_RID_COMMS_QUALITY:
- wreq.wi_val[0] = 0; /* quality */
- wreq.wi_val[1] =
- htole16((*ic->ic_node_getrssi)(ic, ic->ic_bss));
- wreq.wi_val[2] = 0; /* noise */
- wreq.wi_len = 3;
- break;
- case WI_RID_PROMISC:
- wreq.wi_val[0] = htole16((ifp->if_flags & IFF_PROMISC) ? 1 : 0);
- wreq.wi_len = 1;
- break;
- case WI_RID_PORTTYPE:
- wreq.wi_val[0] = htole16(ic->ic_opmode);
- wreq.wi_len = 1;
- break;
- case WI_RID_MAC_NODE:
- IEEE80211_ADDR_COPY(wreq.wi_val, ic->ic_myaddr);
- wreq.wi_len = IEEE80211_ADDR_LEN / 2;
- break;
- case WI_RID_TX_RATE:
- if (ic->ic_fixed_rate == -1)
- wreq.wi_val[0] = 0; /* auto */
- else
- wreq.wi_val[0] = htole16(
- (ic->ic_sup_rates[ic->ic_curmode].rs_rates[ic->ic_fixed_rate] &
- IEEE80211_RATE_VAL) / 2);
- wreq.wi_len = 1;
- break;
- case WI_RID_CUR_TX_RATE:
- wreq.wi_val[0] = htole16(
- (ic->ic_bss->ni_rates.rs_rates[ic->ic_bss->ni_txrate] &
- IEEE80211_RATE_VAL) / 2);
- wreq.wi_len = 1;
- break;
- case WI_RID_FRAG_THRESH:
- wreq.wi_val[0] = htole16(ic->ic_fragthreshold);
- wreq.wi_len = 1;
- break;
- case WI_RID_RTS_THRESH:
- wreq.wi_val[0] = htole16(ic->ic_rtsthreshold);
- wreq.wi_len = 1;
- break;
- case WI_RID_CREATE_IBSS:
- wreq.wi_val[0] =
- htole16((ic->ic_flags & IEEE80211_F_IBSSON) ? 1 : 0);
- wreq.wi_len = 1;
- break;
- case WI_RID_MICROWAVE_OVEN:
- wreq.wi_val[0] = 0; /* no ... not supported */
- wreq.wi_len = 1;
- break;
- case WI_RID_ROAMING_MODE:
- wreq.wi_val[0] = htole16(1); /* enabled ... not supported */
- wreq.wi_len = 1;
- break;
- case WI_RID_SYSTEM_SCALE:
- wreq.wi_val[0] = htole16(1); /* low density ... not supp */
- wreq.wi_len = 1;
- break;
- case WI_RID_PM_ENABLED:
- wreq.wi_val[0] =
- htole16((ic->ic_flags & IEEE80211_F_PMGTON) ? 1 : 0);
- wreq.wi_len = 1;
- break;
- case WI_RID_MAX_SLEEP:
- wreq.wi_val[0] = htole16(ic->ic_lintval);
- wreq.wi_len = 1;
- break;
- case WI_RID_CUR_BEACON_INT:
- wreq.wi_val[0] = htole16(ic->ic_bss->ni_intval);
- wreq.wi_len = 1;
- break;
- case WI_RID_WEP_AVAIL:
- wreq.wi_val[0] =
- htole16((ic->ic_caps & IEEE80211_C_WEP) ? 1 : 0);
- wreq.wi_len = 1;
- break;
- case WI_RID_CNFAUTHMODE:
- wreq.wi_val[0] = htole16(1); /* TODO: open system only */
- wreq.wi_len = 1;
- break;
- case WI_RID_ENCRYPTION:
- wreq.wi_val[0] =
- htole16((ic->ic_flags & IEEE80211_F_WEPON) ? 1 : 0);
- wreq.wi_len = 1;
- break;
- case WI_RID_TX_CRYPT_KEY:
- wreq.wi_val[0] = htole16(ic->ic_wep_txkey);
- wreq.wi_len = 1;
- break;
- case WI_RID_DEFLT_CRYPT_KEYS:
- keys = (struct wi_ltv_keys *)&wreq;
- memset(keys, 0, sizeof(*keys));
- /* do not show keys to non-root user */
- error = suser(curproc, 0);
- if (error) {
- error = 0;
- break;
- }
- for (i = 0; i < IEEE80211_WEP_NKID; i++) {
- keys->wi_keys[i].wi_keylen =
- htole16(ic->ic_nw_keys[i].wk_len);
- memcpy(keys->wi_keys[i].wi_keydat,
- ic->ic_nw_keys[i].wk_key, ic->ic_nw_keys[i].wk_len);
- }
- wreq.wi_len = sizeof(*keys) / 2;
- break;
- case WI_RID_MAX_DATALEN:
- wreq.wi_val[0] = htole16(IEEE80211_MAX_LEN); /* TODO: frag */
- wreq.wi_len = 1;
- break;
- case WI_RID_DBM_ADJUST:
- /* not supported, we just pass rssi value from driver. */
- break;
- case WI_RID_IFACE_STATS:
- /* XXX: should be implemented in lower drivers */
- break;
- case WI_RID_READ_APS:
- if (ic->ic_opmode != IEEE80211_M_HOSTAP) {
- /*
- * Don't return results until active scan completes.
- */
- if (ic->ic_state == IEEE80211_S_SCAN &&
- (ic->ic_flags & IEEE80211_F_ASCAN)) {
- error = EINPROGRESS;
- break;
- }
- }
- i = 0;
- ap = (void *)((char *)wreq.wi_val + sizeof(i));
- TAILQ_FOREACH(ni, &ic->ic_node, ni_list) {
- if ((caddr_t)(ap + 1) > (caddr_t)(&wreq + 1))
- break;
- memset(ap, 0, sizeof(*ap));
- if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
- IEEE80211_ADDR_COPY(ap->bssid, ni->ni_macaddr);
- ap->namelen = ic->ic_des_esslen;
- if (ic->ic_des_esslen)
- memcpy(ap->name, ic->ic_des_essid,
- ic->ic_des_esslen);
- } else {
- IEEE80211_ADDR_COPY(ap->bssid, ni->ni_bssid);
- ap->namelen = ni->ni_esslen;
- if (ni->ni_esslen)
- memcpy(ap->name, ni->ni_essid,
- ni->ni_esslen);
- }
- ap->channel = ieee80211_chan2ieee(ic, ni->ni_chan);
- ap->signal = (*ic->ic_node_getrssi)(ic, ni);
- ap->capinfo = ni->ni_capinfo;
- ap->interval = ni->ni_intval;
- rs = &ni->ni_rates;
- for (j = 0; j < rs->rs_nrates; j++) {
- if (rs->rs_rates[j] & IEEE80211_RATE_BASIC) {
- ap->rate = (rs->rs_rates[j] &
- IEEE80211_RATE_VAL) * 5; /* XXX */
- }
- }
- i++;
- ap++;
- }
- memcpy(wreq.wi_val, &i, sizeof(i));
- wreq.wi_len = (sizeof(int) + sizeof(*ap) * i) / 2;
- break;
- case WI_RID_PRISM2:
- wreq.wi_val[0] = 1; /* XXX lie so SCAN_RES can give rates */
- wreq.wi_len = sizeof(u_int16_t) / 2;
- break;
- case WI_RID_SCAN_RES: /* compatibility interface */
- if (ic->ic_opmode != IEEE80211_M_HOSTAP &&
- ic->ic_state == IEEE80211_S_SCAN &&
- (ic->ic_flags & IEEE80211_F_ASCAN)) {
- error = EINPROGRESS;
- break;
- }
- /* NB: we use the Prism2 format so we can return rate info */
- p2 = (struct wi_scan_p2_hdr *)wreq.wi_val;
- res = (void *)&p2[1];
- i = 0;
- TAILQ_FOREACH(ni, &ic->ic_node, ni_list) {
- if ((caddr_t)(res + 1) > (caddr_t)(&wreq + 1))
- break;
- res->wi_chan = ieee80211_chan2ieee(ic, ni->ni_chan);
- res->wi_noise = 0;
- res->wi_signal = (*ic->ic_node_getrssi)(ic, ni);
- IEEE80211_ADDR_COPY(res->wi_bssid, ni->ni_bssid);
- res->wi_interval = ni->ni_intval;
- res->wi_capinfo = ni->ni_capinfo;
- res->wi_ssid_len = ni->ni_esslen;
- memcpy(res->wi_ssid, ni->ni_essid, IEEE80211_NWID_LEN);
- /* NB: assumes wi_srates holds <= ni->ni_rates */
- memcpy(res->wi_srates, ni->ni_rates.rs_rates,
- sizeof(res->wi_srates));
- if (ni->ni_rates.rs_nrates < 10)
- res->wi_srates[ni->ni_rates.rs_nrates] = 0;
- res->wi_rate = ni->ni_rates.rs_rates[ni->ni_txrate];
- res->wi_rsvd = 0;
- res++, i++;
- }
- p2->wi_rsvd = 0;
- p2->wi_reason = i;
- wreq.wi_len = (sizeof(*p2) + sizeof(*res) * i) / 2;
- break;
-#ifdef WICACHE
- case WI_RID_READ_CACHE:
- i = 0;
- TAILQ_FOREACH(ni, &ic->ic_node, ni_list) {
- if (i == (WI_MAX_DATALEN/sizeof(struct wi_sigcache))-1)
- break;
- IEEE80211_ADDR_COPY(wsc.macsrc, ni->ni_macaddr);
- memset(&wsc.ipsrc, 0, sizeof(wsc.ipsrc));
- wsc.signal = (*ic->ic_node_getrssi)(ic, ni);
- wsc.noise = 0;
- wsc.quality = 0;
- memcpy((caddr_t)wreq.wi_val + sizeof(wsc) * i,
- &wsc, sizeof(wsc));
- i++;
- }
- wreq.wi_len = sizeof(wsc) * i / 2;
- break;
-#endif /* WICACHE */
- case WI_RID_SCAN_APS:
- error = EINVAL;
- break;
- default:
- error = EINVAL;
- break;
- }
- if (error == 0) {
- wreq.wi_len++;
- error = copyout(&wreq, ifr->ifr_data, sizeof(wreq));
- }
- return error;
-}
+ /* Node address and name information */
+ IEEE80211_ADDR_COPY(nr->nr_macaddr, ni->ni_macaddr);
+ IEEE80211_ADDR_COPY(nr->nr_bssid, ni->ni_bssid);
+ nr->nr_nwid_len = ni->ni_esslen;
+ bcopy(ni->ni_essid, nr->nr_nwid, IEEE80211_NWID_LEN);
-static int
-findrate(struct ieee80211com *ic, enum ieee80211_phymode mode, int rate)
-{
-#define IEEERATE(_ic,_m,_i) \
- ((_ic)->ic_sup_rates[_m].rs_rates[_i] & IEEE80211_RATE_VAL)
- int i, nrates = ic->ic_sup_rates[mode].rs_nrates;
- for (i = 0; i < nrates; i++)
- if (IEEERATE(ic, mode, i) == rate)
- return i;
- return -1;
-#undef IEEERATE
-}
+ /* Channel and rates */
+ nr->nr_channel = ieee80211_chan2ieee(ic, ni->ni_chan);
+ nr->nr_chan_flags = ni->ni_chan->ic_flags;
+ nr->nr_nrates = ni->ni_rates.rs_nrates;
+ bcopy(ni->ni_rates.rs_rates, nr->nr_rates, IEEE80211_RATE_MAXSIZE);
-/*
- * Prepare to do a user-initiated scan for AP's. If no
- * current/default channel is setup or the current channel
- * is invalid then pick the first available channel from
- * the active list as the place to start the scan.
- */
-static int
-ieee80211_setupscan(struct ieee80211com *ic)
-{
- u_char *chanlist = ic->ic_chan_active;
- int i;
+ /* Node status information */
+ nr->nr_rssi = (*ic->ic_node_getrssi)(ic, ni);
+ bcopy(ni->ni_tstamp, nr->nr_tstamp, sizeof(nr->nr_tstamp));
+ nr->nr_intval = ni->ni_intval;
+ nr->nr_capinfo = ni->ni_capinfo;
+ nr->nr_fhdwell = ni->ni_fhdwell;
+ nr->nr_fhindex = ni->ni_fhindex;
+ nr->nr_erp = ni->ni_erp;
+ nr->nr_pwrsave = ni->ni_pwrsave;
+ nr->nr_associd = ni->ni_associd;
+ nr->nr_txseq = ni->ni_txseq;
+ nr->nr_rxseq = ni->ni_rxseq;
+ nr->nr_fails = ni->ni_fails;
+ nr->nr_inact = ni->ni_inact;
+ nr->nr_txrate = ni->ni_txrate;
+ nr->nr_state = ni->ni_state;
- if (ic->ic_ibss_chan == NULL ||
- isclr(chanlist, ieee80211_chan2ieee(ic, ic->ic_ibss_chan))) {
- for (i = 0; i <= IEEE80211_CHAN_MAX; i++)
- if (isset(chanlist, i)) {
- ic->ic_ibss_chan = &ic->ic_channels[i];
- goto found;
- }
- return EINVAL; /* no active channels */
-found:
- ;
- }
- if (ic->ic_bss->ni_chan == IEEE80211_CHAN_ANYC ||
- isclr(chanlist, ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan)))
- ic->ic_bss->ni_chan = ic->ic_ibss_chan;
- /*
- * XXX don't permit a scan to be started unless we
- * know the device is ready. For the moment this means
- * the device is marked up as this is the required to
- * initialize the hardware. It would be better to permit
- * scanning prior to being up but that'll require some
- * changes to the infrastructure.
- */
- return (ic->ic_if.if_flags & IFF_UP) ? 0 : ENETRESET;
+ /* Node flags */
+ nr->nr_flags = 0;
+ if (bcmp(nr->nr_macaddr, nr->nr_bssid, IEEE80211_ADDR_LEN) == 0)
+ nr->nr_flags |= IEEE80211_NODEREQ_AP;
+ if (ni == ic->ic_bss)
+ nr->nr_flags |= IEEE80211_NODEREQ_AP_BSS;
}
-int
-ieee80211_cfgset(struct ifnet *ifp, u_long cmd, caddr_t data)
+void
+ieee80211_req2node(struct ieee80211com *ic, struct ieee80211_nodereq *nr,
+ struct ieee80211_node *ni)
{
- struct ieee80211com *ic = (void *)ifp;
- int i, j, len, error, rate;
- struct ifreq *ifr = (struct ifreq *)data;
- struct wi_ltv_keys *keys;
- struct wi_req wreq;
- u_char chanlist[roundup(IEEE80211_CHAN_MAX, NBBY)];
+ /* Node address and name information */
+ IEEE80211_ADDR_COPY(ni->ni_macaddr, nr->nr_macaddr);
+ IEEE80211_ADDR_COPY(ni->ni_bssid, nr->nr_bssid);
+ ni->ni_esslen = nr->nr_nwid_len;
+ bcopy(nr->nr_nwid, ni->ni_essid, IEEE80211_NWID_LEN);
- error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
- if (error)
- return error;
- len = wreq.wi_len ? (wreq.wi_len - 1) * 2 : 0;
- switch (wreq.wi_type) {
- case WI_RID_SERIALNO:
- case WI_RID_NODENAME:
- return EPERM;
- case WI_RID_CURRENT_SSID:
- return EPERM;
- case WI_RID_OWN_SSID:
- case WI_RID_DESIRED_SSID:
- if (letoh16(wreq.wi_val[0]) * 2 > len ||
- letoh16(wreq.wi_val[0]) > IEEE80211_NWID_LEN) {
- error = ENOSPC;
- break;
- }
- memset(ic->ic_des_essid, 0, sizeof(ic->ic_des_essid));
- ic->ic_des_esslen = letoh16(wreq.wi_val[0]) * 2;
- memcpy(ic->ic_des_essid, &wreq.wi_val[1], ic->ic_des_esslen);
- error = ENETRESET;
- break;
- case WI_RID_CURRENT_BSSID:
- return EPERM;
- case WI_RID_OWN_CHNL:
- if (len != 2)
- return EINVAL;
- i = letoh16(wreq.wi_val[0]);
- if (i < 0 ||
- i > IEEE80211_CHAN_MAX ||
- isclr(ic->ic_chan_active, i))
- return EINVAL;
- ic->ic_ibss_chan = &ic->ic_channels[i];
- if (ic->ic_flags & IEEE80211_F_SIBSS)
- error = ENETRESET;
- break;
- case WI_RID_CURRENT_CHAN:
- return EPERM;
- case WI_RID_COMMS_QUALITY:
- return EPERM;
- case WI_RID_PROMISC:
- if (len != 2)
- return EINVAL;
- if (ifp->if_flags & IFF_PROMISC) {
- if (wreq.wi_val[0] == 0) {
- ifp->if_flags &= ~IFF_PROMISC;
- error = ENETRESET;
- }
- } else {
- if (wreq.wi_val[0] != 0) {
- ifp->if_flags |= IFF_PROMISC;
- error = ENETRESET;
- }
- }
- break;
- case WI_RID_PORTTYPE:
- if (len != 2)
- return EINVAL;
- switch (letoh16(wreq.wi_val[0])) {
- case IEEE80211_M_STA:
- break;
- case IEEE80211_M_IBSS:
- if (!(ic->ic_caps & IEEE80211_C_IBSS))
- return EINVAL;
- break;
- case IEEE80211_M_AHDEMO:
- if (ic->ic_phytype != IEEE80211_T_DS ||
- !(ic->ic_caps & IEEE80211_C_AHDEMO))
- return EINVAL;
- break;
- case IEEE80211_M_HOSTAP:
- if (!(ic->ic_caps & IEEE80211_C_HOSTAP))
- return EINVAL;
- break;
- default:
- return EINVAL;
- }
- if (letoh16(wreq.wi_val[0]) != ic->ic_opmode) {
- ic->ic_opmode = letoh16(wreq.wi_val[0]);
- error = ENETRESET;
- }
- break;
-#if 0
- case WI_RID_MAC_NODE:
- if (len != IEEE80211_ADDR_LEN)
- return EINVAL;
- IEEE80211_ADDR_COPY(LLADDR(ifp->if_sadl), wreq.wi_val);
- /* if_init will copy lladdr into ic_myaddr */
- error = ENETRESET;
- break;
-#endif
- case WI_RID_TX_RATE:
- if (len != 2)
- return EINVAL;
- if (wreq.wi_val[0] == 0) {
- /* auto */
- ic->ic_fixed_rate = -1;
- break;
- }
- rate = 2 * letoh16(wreq.wi_val[0]);
- if (ic->ic_curmode == IEEE80211_MODE_AUTO) {
- /*
- * In autoselect mode search for the rate. We take
- * the first instance which may not be right, but we
- * are limited by the interface. Note that we also
- * lock the mode to insure the rate is meaningful
- * when it is used.
- */
- for (j = IEEE80211_MODE_11A;
- j < IEEE80211_MODE_MAX; j++) {
- if ((ic->ic_modecaps & (1<<j)) == 0)
- continue;
- i = findrate(ic, j, rate);
- if (i != -1) {
- /* lock mode too */
- ic->ic_curmode = j;
- goto setrate;
- }
- }
- } else {
- i = findrate(ic, ic->ic_curmode, rate);
- if (i != -1)
- goto setrate;
- }
- return EINVAL;
- setrate:
- ic->ic_fixed_rate = i;
- error = ENETRESET;
- break;
- case WI_RID_CUR_TX_RATE:
- return EPERM;
- case WI_RID_FRAG_THRESH:
- if (len != 2)
- return EINVAL;
- ic->ic_fragthreshold = letoh16(wreq.wi_val[0]);
- error = ENETRESET;
- break;
- case WI_RID_RTS_THRESH:
- if (len != 2)
- return EINVAL;
- ic->ic_rtsthreshold = letoh16(wreq.wi_val[0]);
- error = ENETRESET;
- break;
- case WI_RID_CREATE_IBSS:
- if (len != 2)
- return EINVAL;
- if (wreq.wi_val[0] != 0) {
- if ((ic->ic_caps & IEEE80211_C_IBSS) == 0)
- return EINVAL;
- if ((ic->ic_flags & IEEE80211_F_IBSSON) == 0) {
- ic->ic_flags |= IEEE80211_F_IBSSON;
- if (ic->ic_opmode == IEEE80211_M_IBSS &&
- ic->ic_state == IEEE80211_S_SCAN)
- error = ENETRESET;
- }
- } else {
- if (ic->ic_flags & IEEE80211_F_IBSSON) {
- ic->ic_flags &= ~IEEE80211_F_IBSSON;
- if (ic->ic_flags & IEEE80211_F_SIBSS) {
- ic->ic_flags &= ~IEEE80211_F_SIBSS;
- error = ENETRESET;
- }
- }
- }
- break;
- case WI_RID_MICROWAVE_OVEN:
- if (len != 2)
- return EINVAL;
- if (wreq.wi_val[0] != 0)
- return EINVAL; /* not supported */
- break;
- case WI_RID_ROAMING_MODE:
- if (len != 2)
- return EINVAL;
- if (letoh16(wreq.wi_val[0]) != 1)
- return EINVAL; /* not supported */
- break;
- case WI_RID_SYSTEM_SCALE:
- if (len != 2)
- return EINVAL;
- if (letoh16(wreq.wi_val[0]) != 1)
- return EINVAL; /* not supported */
- break;
- case WI_RID_PM_ENABLED:
- if (len != 2)
- return EINVAL;
- if (wreq.wi_val[0] != 0) {
- if ((ic->ic_caps & IEEE80211_C_PMGT) == 0)
- return EINVAL;
- if ((ic->ic_flags & IEEE80211_F_PMGTON) == 0) {
- ic->ic_flags |= IEEE80211_F_PMGTON;
- error = ENETRESET;
- }
- } else {
- if (ic->ic_flags & IEEE80211_F_PMGTON) {
- ic->ic_flags &= ~IEEE80211_F_PMGTON;
- error = ENETRESET;
- }
- }
- break;
- case WI_RID_MAX_SLEEP:
- if (len != 2)
- return EINVAL;
- ic->ic_lintval = letoh16(wreq.wi_val[0]);
- if (ic->ic_flags & IEEE80211_F_PMGTON)
- error = ENETRESET;
- break;
- case WI_RID_CUR_BEACON_INT:
- return EPERM;
- case WI_RID_WEP_AVAIL:
- return EPERM;
- case WI_RID_CNFAUTHMODE:
- if (len != 2)
- return EINVAL;
- if (letoh16(wreq.wi_val[0]) != 1)
- return EINVAL; /* TODO: shared key auth */
- break;
- case WI_RID_ENCRYPTION:
- if (len != 2)
- return EINVAL;
- if (wreq.wi_val[0] != 0) {
- if ((ic->ic_caps & IEEE80211_C_WEP) == 0)
- return EINVAL;
- if ((ic->ic_flags & IEEE80211_F_WEPON) == 0) {
- ic->ic_flags |= IEEE80211_F_WEPON;
- error = ENETRESET;
- }
- } else {
- if (ic->ic_flags & IEEE80211_F_WEPON) {
- ic->ic_flags &= ~IEEE80211_F_WEPON;
- error = ENETRESET;
- }
- }
- break;
- case WI_RID_TX_CRYPT_KEY:
- if (len != 2)
- return EINVAL;
- i = letoh16(wreq.wi_val[0]);
- if (i >= IEEE80211_WEP_NKID)
- return EINVAL;
- ic->ic_wep_txkey = i;
- break;
- case WI_RID_DEFLT_CRYPT_KEYS:
- if (len != sizeof(struct wi_ltv_keys))
- return EINVAL;
- keys = (struct wi_ltv_keys *)&wreq;
- for (i = 0; i < IEEE80211_WEP_NKID; i++) {
- len = letoh16(keys->wi_keys[i].wi_keylen);
- if (len < 0 || len > sizeof(ic->ic_nw_keys[i].wk_key))
- return EINVAL;
- }
- memset(ic->ic_nw_keys, 0, sizeof(ic->ic_nw_keys));
- for (i = 0; i < IEEE80211_WEP_NKID; i++) {
- len = letoh16(keys->wi_keys[i].wi_keylen);
- ic->ic_nw_keys[i].wk_len = len;
- memcpy(ic->ic_nw_keys[i].wk_key,
- keys->wi_keys[i].wi_keydat, len);
- }
- error = ENETRESET;
- break;
- case WI_RID_MAX_DATALEN:
- if (len != 2)
- return EINVAL;
- len = letoh16(wreq.wi_val[0]);
- if (len < 350 /* ? */ || len > IEEE80211_MAX_LEN)
- return EINVAL;
- if (len != IEEE80211_MAX_LEN)
- return EINVAL; /* TODO: fragment */
- ic->ic_fragthreshold = len;
- error = ENETRESET;
- break;
- case WI_RID_IFACE_STATS:
- error = EPERM;
- break;
- case WI_RID_SCAN_REQ: /* XXX wicontrol */
- if (ic->ic_opmode == IEEE80211_M_HOSTAP)
- break;
- error = ieee80211_setupscan(ic);
- if (error == 0)
- error = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
- break;
- case WI_RID_SCAN_APS:
- if (ic->ic_opmode == IEEE80211_M_HOSTAP)
- break;
- len--; /* XXX: tx rate? */
- /* FALLTHRU */
- case WI_RID_CHANNEL_LIST:
- memset(chanlist, 0, sizeof(chanlist));
- /*
- * Since channel 0 is not available for DS, channel 1
- * is assigned to LSB on WaveLAN.
- */
- if (ic->ic_phytype == IEEE80211_T_DS)
- i = 1;
- else
- i = 0;
- for (j = 0; i <= IEEE80211_CHAN_MAX; i++, j++) {
- if ((j / 8) >= len)
- break;
- if (isclr((u_int8_t *)wreq.wi_val, j))
- continue;
- if (isclr(ic->ic_chan_active, i)) {
- if (wreq.wi_type != WI_RID_CHANNEL_LIST)
- continue;
- if (isclr(ic->ic_chan_avail, i))
- return EPERM;
- }
- setbit(chanlist, i);
- }
- memcpy(ic->ic_chan_active, chanlist,
- sizeof(ic->ic_chan_active));
- error = ieee80211_setupscan(ic);
- if (wreq.wi_type == WI_RID_CHANNEL_LIST) {
- /* NB: ignore error from ieee80211_setupscan */
- error = ENETRESET;
- } else if (error == 0)
- error = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
- break;
- default:
- error = EINVAL;
- break;
- }
- return error;
+ /* Rates */
+ ni->ni_rates.rs_nrates = nr->nr_nrates;
+ bcopy(nr->nr_rates, ni->ni_rates.rs_rates, IEEE80211_RATE_MAXSIZE);
+
+ /* Node information */
+ ni->ni_intval = nr->nr_intval;
+ ni->ni_capinfo = nr->nr_capinfo;
+ ni->ni_fhdwell = nr->nr_fhdwell;
+ ni->ni_fhindex = nr->nr_fhindex;
+ ni->ni_erp = nr->nr_erp;
+ ni->ni_pwrsave = nr->nr_pwrsave;
+ ni->ni_associd = nr->nr_associd;
+ ni->ni_txseq = nr->nr_txseq;
+ ni->ni_rxseq = nr->nr_rxseq;
+ ni->ni_fails = nr->nr_fails;
+ ni->ni_inact = nr->nr_inact;
+ ni->ni_txrate = nr->nr_txrate;
+ ni->ni_state = nr->nr_state;
}
int
@@ -818,20 +150,14 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
static const u_int8_t empty_macaddr[IEEE80211_ADDR_LEN] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
-#if defined(__OpenBSD__)
+ struct ieee80211_nodereq *nr, nrbuf;
+ struct ieee80211_nodereq_all *na;
struct ieee80211_node *ni;
- struct hostap_getall reqall;
- struct hostap_sta stabuf;
-#endif
switch (cmd) {
case SIOCSIFADDR:
case SIOCGIFADDR:
-#ifdef __OpenBSD__
error = ether_ioctl(ifp, &ic->ic_ac, cmd, data);
-#else
- error = ether_ioctl(ifp, cmd, data);
-#endif
break;
case SIOCSIFMEDIA:
case SIOCGIFMEDIA:
@@ -1050,15 +376,6 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
}
chanreq->i_channel = ieee80211_chan2ieee(ic, chan);
break;
- case SIOCGIFGENERIC:
- error = ieee80211_cfgget(ifp, cmd, data);
- break;
- case SIOCSIFGENERIC:
- error = suser(curproc, 0);
- if (error)
- break;
- error = ieee80211_cfgset(ifp, cmd, data);
- break;
#if 0
case SIOCG80211ZSTATS:
#endif
@@ -1101,15 +418,64 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
else
ifp->if_mtu = ifr->ifr_mtu;
break;
-#if defined(__OpenBSD__)
- case SIOCHOSTAP_DEL:
- if ((error = suser(curproc, 0)))
+ case SIOCS80211SCAN:
+ if ((error = suser(curproc, 0)) != 0)
+ break;
+ if (ic->ic_opmode == IEEE80211_M_HOSTAP)
break;
- if ((error = copyin(ifr->ifr_data, &stabuf, sizeof(stabuf))))
+ if ((ifp->if_flags & IFF_UP) == 0) {
+ error = ENETDOWN;
break;
- ni = ieee80211_find_node(ic, stabuf.addr);
+ }
+ if ((ic->ic_scan_lock & IEEE80211_SCAN_REQUEST) == 0) {
+ if (ic->ic_scan_lock & IEEE80211_SCAN_LOCKED)
+ ic->ic_scan_lock |= IEEE80211_SCAN_RESUME;
+ ic->ic_scan_lock |= IEEE80211_SCAN_REQUEST;
+ if (ic->ic_state != IEEE80211_S_SCAN)
+ ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
+ }
+ /* Let the userspace process wait for completion */
+ error = tsleep(&ic->ic_scan_lock, PCATCH, "80211scan",
+ hz * IEEE80211_SCAN_TIMEOUT);
+ break;
+ case SIOCG80211NODE:
+ nr = (struct ieee80211_nodereq *)data;
+ ni = ieee80211_find_node(ic, nr->nr_macaddr);
+ if (ni == NULL) {
+ error = ENOENT;
+ break;
+ }
+ ieee80211_node2req(ic, ni, nr);
+ break;
+ case SIOCS80211NODE:
+ if ((error = suser(curproc, 0)) != 0)
+ break;
+ if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
+ error = EINVAL;
+ break;
+ }
+ nr = (struct ieee80211_nodereq *)data;
+
+ ni = ieee80211_find_node(ic, nr->nr_macaddr);
if (ni == NULL)
+ ni = ieee80211_alloc_node(ic, nr->nr_macaddr);
+ if (ni == NULL) {
error = ENOENT;
+ break;
+ }
+
+ if (nr->nr_flags & IEEE80211_NODEREQ_COPY)
+ ieee80211_req2node(ic, nr, ni);
+ break;
+ case SIOCS80211DELNODE:
+ if ((error = suser(curproc, 0)) != 0)
+ break;
+ nr = (struct ieee80211_nodereq *)data;
+ ni = ieee80211_find_node(ic, nr->nr_macaddr);
+ if (ni == NULL)
+ error = ENOENT;
+ else if (ni == ic->ic_bss)
+ error = EPERM;
else {
if (ni->ni_state == IEEE80211_STA_COLLECT)
break;
@@ -1129,64 +495,25 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
ieee80211_release_node(ic, ni);
}
break;
- case SIOCHOSTAP_GET:
- if ((error = copyin(ifr->ifr_data, &stabuf, sizeof(stabuf))))
- break;
- ni = ieee80211_find_node(ic, stabuf.addr);
- if (ni == NULL)
- error = ENOENT;
- else {
- node2sta(ic, ni, &stabuf);
- error = copyout(&stabuf, ifr->ifr_data,
- sizeof(stabuf));
- }
- break;
- case SIOCHOSTAP_GETALL:
- if ((error = copyin(ifr->ifr_data, &reqall, sizeof(reqall))))
- break;
-
- reqall.nstations = i = 0;
+ case SIOCG80211ALLNODES:
+ na = (struct ieee80211_nodereq_all *)data;
+ na->na_nodes = i = 0;
ni = TAILQ_FIRST(&ic->ic_node);
- while(ni && reqall.size >= i + sizeof(struct hostap_sta)) {
- node2sta(ic, ni, &stabuf);
- error = copyout(&stabuf, (caddr_t) reqall.addr + i,
- sizeof(struct hostap_sta));
+ while (ni && na->na_size >=
+ i + sizeof(struct ieee80211_nodereq)) {
+ ieee80211_node2req(ic, ni, &nrbuf);
+ error = copyout(&nrbuf, (caddr_t)na->na_node + i,
+ sizeof(struct ieee80211_nodereq));
if (error)
break;
- i += sizeof(struct hostap_sta);
- reqall.nstations++;
+ i += sizeof(struct ieee80211_nodereq);
+ na->na_nodes++;
ni = TAILQ_NEXT(ni, ni_list);
}
-
- if (!error)
- error = copyout(&reqall, ifr->ifr_data,
- sizeof(reqall));
break;
- case SIOCHOSTAP_ADD:
- case SIOCHOSTAP_GFLAGS:
- case SIOCHOSTAP_SFLAGS:
-#endif
default:
error = EINVAL;
break;
}
return error;
}
-
-#if defined(__OpenBSD__)
-void
-node2sta(struct ieee80211com *ic, struct ieee80211_node *ni,
- struct hostap_sta *sta)
-{
- bcopy(ni->ni_macaddr, sta->addr, IEEE80211_ADDR_LEN);
- sta->flags = 0;
- if (ni->ni_state >= IEEE80211_STA_AUTH)
- sta->flags |= HOSTAP_FLAGS_AUTHEN;
- if (ni->ni_state >= IEEE80211_STA_ASSOC)
- sta->flags |= HOSTAP_FLAGS_ASSOC;
- sta->asid = ni->ni_associd;
- sta->capinfo = ni->ni_capinfo;
- sta->sig_info = (*ic->ic_node_getrssi)(ic, ni);
- sta->rates = 0x00; /* not compatible */
-}
-#endif
diff --git a/sys/net80211/ieee80211_ioctl.h b/sys/net80211/ieee80211_ioctl.h
index a3462e067a4..b81a4214f40 100644
--- a/sys/net80211/ieee80211_ioctl.h
+++ b/sys/net80211/ieee80211_ioctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_ioctl.h,v 1.3 2005/02/27 22:27:56 reyk Exp $ */
+/* $OpenBSD: ieee80211_ioctl.h,v 1.4 2005/05/25 07:40:49 reyk Exp $ */
/* $NetBSD: ieee80211_ioctl.h,v 1.7 2004/04/30 22:51:04 dyoung Exp $ */
/*-
@@ -41,6 +41,7 @@
* IEEE 802.11 ioctls.
*/
+/* per-interface statistics */
struct ieee80211_stats {
u_int32_t is_rx_badversion; /* rx frame with bad version */
u_int32_t is_rx_tooshort; /* rx frame too short */
@@ -85,7 +86,9 @@ struct ieee80211_stats {
u_int32_t is_crypto_nomem; /* no memory for crypto ctx */
};
-/* nwid is pointed at by ifr.ifr_data */
+#define SIOCG80211STATS _IOWR('i', 242, struct ifreq)
+
+/* network identifier (ESSID), nwid is pointed at by ifr.ifr_data */
struct ieee80211_nwid {
u_int8_t i_len;
u_int8_t i_nwid[IEEE80211_NWID_LEN];
@@ -94,7 +97,7 @@ struct ieee80211_nwid {
#define SIOCS80211NWID _IOWR('i', 230, struct ifreq)
#define SIOCG80211NWID _IOWR('i', 231, struct ifreq)
-/* the first member must be matched with struct ifreq */
+/* network key (WEP), the first member must be matched with struct ifreq */
struct ieee80211_nwkey {
char i_name[IFNAMSIZ]; /* if_name, e.g. "wi0" */
int i_wepon; /* wep enabled flag */
@@ -104,14 +107,15 @@ struct ieee80211_nwkey {
u_int8_t *i_keydat;
} i_key[IEEE80211_WEP_NKID];
};
-#define SIOCS80211NWKEY _IOW('i', 232, struct ieee80211_nwkey)
-#define SIOCG80211NWKEY _IOWR('i', 233, struct ieee80211_nwkey)
-/* i_wepon */
+
#define IEEE80211_NWKEY_OPEN 0 /* No privacy */
#define IEEE80211_NWKEY_WEP 1 /* WEP enabled */
#define IEEE80211_NWKEY_EAP 2 /* EAP enabled */
#define IEEE80211_NWKEY_PERSIST 0x100 /* designate persist keyset */
+#define SIOCS80211NWKEY _IOW('i', 232, struct ieee80211_nwkey)
+#define SIOCG80211NWKEY _IOWR('i', 233, struct ieee80211_nwkey)
+
/* power management parameters */
struct ieee80211_power {
char i_name[IFNAMSIZ]; /* if_name, e.g. "wi0" */
@@ -121,6 +125,7 @@ struct ieee80211_power {
#define SIOCS80211POWER _IOW('i', 234, struct ieee80211_power)
#define SIOCG80211POWER _IOWR('i', 235, struct ieee80211_power)
+/* authentication type */
struct ieee80211_auth {
char i_name[IFNAMSIZ]; /* if_name, e.g. "wi0" */
int i_authtype;
@@ -133,6 +138,7 @@ struct ieee80211_auth {
#define SIOCS80211AUTH _IOW('i', 236, struct ieee80211_auth)
#define SIOCG80211AUTH _IOWR('i', 237, struct ieee80211_auth)
+/* channel request */
struct ieee80211chanreq {
char i_name[IFNAMSIZ]; /* if_name, e.g. "wi0" */
u_int16_t i_channel;
@@ -145,6 +151,7 @@ struct ieee80211chanreq {
#define SIOCS80211CHANNEL _IOW('i', 238, struct ieee80211chanreq)
#define SIOCG80211CHANNEL _IOWR('i', 239, struct ieee80211chanreq)
+/* BSS identifier */
struct ieee80211_bssid {
char i_name[IFNAMSIZ]; /* if_name, e.g. "wi0" */
u_int8_t i_bssid[IEEE80211_ADDR_LEN];
@@ -153,8 +160,7 @@ struct ieee80211_bssid {
#define SIOCS80211BSSID _IOW('i', 240, struct ieee80211_bssid)
#define SIOCG80211BSSID _IOWR('i', 241, struct ieee80211_bssid)
-#define SIOCG80211STATS _IOWR('i', 242, struct ifreq)
-
+/* transmit power */
struct ieee80211_txpower {
char i_name[IFNAMSIZ]; /* if_name, e.g. "wi0" */
int i_mode; /* auto, manual */
@@ -167,4 +173,72 @@ struct ieee80211_txpower {
#define IEEE80211_TXPOWER_MODE_FIXED 0 /* fixed tx power value */
#define IEEE80211_TXPOWER_MODE_AUTO 1 /* auto level control */
+/* scan request (will block) */
+#define IEEE80211_SCAN_TIMEOUT 30 /* timeout in seconds */
+
+#define SIOCS80211SCAN _IOW('i', 210, struct ifreq)
+
+/* node and requests */
+struct ieee80211_nodereq {
+ char nr_ifname[IFNAMSIZ]; /* e.g. "ath0" */
+
+ /* Node address and name information */
+ u_int8_t nr_macaddr[IEEE80211_ADDR_LEN]; /* node lladdr */
+ u_int8_t nr_bssid[IEEE80211_ADDR_LEN]; /* bssid */
+ u_int8_t nr_nwid_len; /* ESSID length */
+ u_int8_t nr_nwid[IEEE80211_NWID_LEN]; /* ESSID */
+
+ /* Channel and rates */
+ u_int16_t nr_channel; /* last channel */
+ u_int16_t nr_chan_flags; /* channel flags */
+ u_int8_t nr_nrates; /* rate count */
+ u_int8_t nr_rates[IEEE80211_RATE_MAXSIZE]; /* rate set */
+
+ /* Node status information */
+ u_int8_t nr_rssi; /* received signal strength */
+ u_int8_t nr_tstamp[8]; /* from last received beacon */
+ u_int16_t nr_intval; /* beacon interval */
+ u_int16_t nr_capinfo; /* capabilities */
+ u_int16_t nr_fhdwell; /* FH only */
+ u_int8_t nr_fhindex; /* FH only */
+ u_int8_t nr_erp; /* 11g only */
+ u_int8_t nr_pwrsave; /* power saving mode */
+ u_int16_t nr_associd; /* assoc response */
+ u_int16_t nr_txseq; /* seq to be transmitted */
+ u_int16_t nr_rxseq; /* seq previous received */
+ u_int32_t nr_fails; /* failure count to associate */
+ u_int32_t nr_inact; /* inactivity mark count */
+ u_int8_t nr_txrate; /* index to nr_rates[] */
+ u_int16_t nr_state; /* node state in the cache */
+
+ /* Node flags */
+ u_int8_t nr_flags;
+};
+
+#define IEEE80211_NODEREQ_STATE(_s) (1 << _s)
+#define IEEE80211_NODEREQ_STATE_BITS "\20\01CACHE\02BSS\03AUTH\04ASSOC\05COLLECT"
+
+#define IEEE80211_NODEREQ_STA 0x00 /* station */
+#define IEEE80211_NODEREQ_AP 0x01 /* access point */
+#define IEEE80211_NODEREQ_AP_BSS 0x02 /* current bss access point */
+#define IEEE80211_NODEREQ_COPY 0x04 /* add node with flags */
+
+#define SIOCG80211NODE _IOWR('i', 211, struct ieee80211_nodereq)
+#define SIOCS80211NODE _IOW('i', 212, struct ieee80211_nodereq)
+#define SIOCS80211DELNODE _IOW('i', 213, struct ieee80211_nodereq)
+
+/* get the entire node cache */
+struct ieee80211_nodereq_all {
+ char na_ifname[IFNAMSIZ]; /* e.g. "ath0" */
+
+ int na_nodes; /* returned count */
+ size_t na_size; /* size of node buffer */
+ struct ieee80211_nodereq *na_node; /* allocated node buffer */
+
+ /* Match nodes by flag */
+ u_int8_t na_flags; /* IEEE80211_NODEREQ_* */
+};
+
+#define SIOCG80211ALLNODES _IOWR('i', 214, struct ieee80211_nodereq)
+
#endif /* _NET80211_IEEE80211_IOCTL_H_ */
diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c
index 7bed1fc2b3b..084cb68a816 100644
--- a/sys/net80211/ieee80211_node.c
+++ b/sys/net80211/ieee80211_node.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_node.c,v 1.4 2005/04/21 22:47:15 reyk Exp $ */
+/* $OpenBSD: ieee80211_node.c,v 1.5 2005/05/25 07:40:49 reyk Exp $ */
/* $NetBSD: ieee80211_node.c,v 1.14 2004/05/09 09:18:47 dyoung Exp $ */
/*-
@@ -216,6 +216,10 @@ ieee80211_begin_scan(struct ifnet *ifp)
{
struct ieee80211com *ic = (void *)ifp;
+ if (ic->ic_scan_lock & IEEE80211_SCAN_LOCKED)
+ return;
+ ic->ic_scan_lock |= IEEE80211_SCAN_LOCKED;
+
/*
* In all but hostap mode scanning starts off in
* an active mode before switching to passive.
@@ -245,6 +249,8 @@ ieee80211_begin_scan(struct ifnet *ifp)
ieee80211_setmode(ic, ic->ic_curmode);
}
+ ic->ic_scan_count = 0;
+
/* Scan the next channel. */
ieee80211_next_scan(ifp);
}
@@ -399,7 +405,9 @@ ieee80211_end_scan(struct ifnet *ifp)
(ic->ic_flags & IEEE80211_F_ASCAN) ?
"active" : "passive");
- ic->ic_flags &= ~IEEE80211_F_ASCAN;
+ if (ic->ic_scan_count)
+ ic->ic_flags &= ~IEEE80211_F_ASCAN;
+
ni = TAILQ_FIRST(&ic->ic_node);
if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
@@ -426,7 +434,7 @@ ieee80211_end_scan(struct ifnet *ifp)
break;
}
ieee80211_create_ibss(ic, &ic->ic_channels[i]);
- return;
+ goto wakeup;
}
if (ni == NULL) {
IEEE80211_DPRINTF(("%s: no scan candidate\n", __func__));
@@ -435,16 +443,26 @@ ieee80211_end_scan(struct ifnet *ifp)
(ic->ic_flags & IEEE80211_F_IBSSON) &&
ic->ic_des_esslen != 0) {
ieee80211_create_ibss(ic, ic->ic_ibss_chan);
- return;
+ goto wakeup;
}
/*
* Scan the next mode if nothing has been found. This
* is necessary if the device supports different
* incompatible modes in the same channel range, like
- * like 11b and "pure" 11G mode.
+ * like 11b and "pure" 11G mode. This will loop
+ * forever except for user-initiated scans.
*/
- ieee80211_next_mode(ifp);
+ if (ieee80211_next_mode(ifp) == IEEE80211_MODE_AUTO) {
+ if (ic->ic_scan_lock & IEEE80211_SCAN_REQUEST &&
+ ic->ic_scan_lock & IEEE80211_SCAN_RESUME) {
+ ic->ic_scan_lock = IEEE80211_SCAN_LOCKED;
+ /* Return from an user-initiated scan */
+ wakeup(&ic->ic_scan_lock);
+ } else if (ic->ic_scan_lock & IEEE80211_SCAN_REQUEST)
+ goto wakeup;
+ ic->ic_scan_count++;
+ }
/*
* Reset the list of channels to scan and start again.
@@ -487,6 +505,14 @@ ieee80211_end_scan(struct ifnet *ifp)
} else {
ieee80211_new_state(ic, IEEE80211_S_AUTH, -1);
}
+
+ wakeup:
+ if (ic->ic_scan_lock & IEEE80211_SCAN_REQUEST) {
+ /* Return from an user-initiated scan */
+ wakeup(&ic->ic_scan_lock);
+ }
+
+ ic->ic_scan_lock = IEEE80211_SCAN_UNLOCKED;
}
int
diff --git a/sys/net80211/ieee80211_node.h b/sys/net80211/ieee80211_node.h
index 153527353f0..fdc2f4d489e 100644
--- a/sys/net80211/ieee80211_node.h
+++ b/sys/net80211/ieee80211_node.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_node.h,v 1.3 2005/02/17 18:28:05 reyk Exp $ */
+/* $OpenBSD: ieee80211_node.h,v 1.4 2005/05/25 07:40:49 reyk Exp $ */
/* $NetBSD: ieee80211_node.h,v 1.9 2004/04/30 22:57:32 dyoung Exp $ */
/*-
@@ -48,9 +48,6 @@
#define IEEE80211_NODE_HASH(addr) \
(((u_int8_t *)(addr))[IEEE80211_ADDR_LEN - 1] % IEEE80211_NODE_HASHSIZE)
-#define IEEE80211_RATE_SIZE 8 /* 802.11 standard */
-#define IEEE80211_RATE_MAXSIZE 15 /* max rates we'll handle */
-
struct ieee80211_rateset {
u_int8_t rs_nrates;
u_int8_t rs_rates[IEEE80211_RATE_MAXSIZE];
diff --git a/sys/net80211/ieee80211_radiotap.h b/sys/net80211/ieee80211_radiotap.h
index 1d355d2af0e..93b8ecc1b88 100644
--- a/sys/net80211/ieee80211_radiotap.h
+++ b/sys/net80211/ieee80211_radiotap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_radiotap.h,v 1.5 2005/01/07 16:28:38 reyk Exp $ */
+/* $OpenBSD: ieee80211_radiotap.h,v 1.6 2005/05/25 07:40:49 reyk Exp $ */
/* $FreeBSD: src/sys/net80211/ieee80211_radiotap.h,v 1.3 2004/04/05 22:13:21 sam Exp $ */
/* $NetBSD: ieee80211_radiotap.h,v 1.9 2004/06/06 04:13:28 dyoung Exp $ */
@@ -178,19 +178,6 @@ enum ieee80211_radiotap_type {
IEEE80211_RADIOTAP_EXT = 31
};
-#ifndef _KERNEL
-/* Channel flags. */
-#define IEEE80211_CHAN_TURBO 0x0010 /* Turbo channel */
-#define IEEE80211_CHAN_CCK 0x0020 /* CCK channel */
-#define IEEE80211_CHAN_OFDM 0x0040 /* OFDM channel */
-#define IEEE80211_CHAN_2GHZ 0x0080 /* 2 GHz spectrum channel. */
-#define IEEE80211_CHAN_5GHZ 0x0100 /* 5 GHz spectrum channel */
-#define IEEE80211_CHAN_PASSIVE 0x0200 /* Only passive scan allowed */
-#define IEEE80211_CHAN_DYN 0x0400 /* Dynamic CCK-OFDM channel */
-#define IEEE80211_CHAN_GFSK 0x0800 /* GFSK channel (FHSS PHY) */
-#define IEEE80211_CHAN_XR 0x1000 /* eXtended Range */
-#endif /* !_KERNEL */
-
/* For IEEE80211_RADIOTAP_FLAGS */
#define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received
* during CFP
diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h
index c4c94604727..d153907c4af 100644
--- a/sys/net80211/ieee80211_var.h
+++ b/sys/net80211/ieee80211_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_var.h,v 1.8 2005/05/13 01:06:41 jsg Exp $ */
+/* $OpenBSD: ieee80211_var.h,v 1.9 2005/05/25 07:40:49 reyk Exp $ */
/* $NetBSD: ieee80211_var.h,v 1.7 2004/05/06 03:07:10 dyoung Exp $ */
/*-
@@ -100,36 +100,6 @@ struct ieee80211_channel {
u_int16_t ic_flags; /* see below */
};
-/* bits 0-3 are for private use by drivers */
-/* channel attributes */
-#define IEEE80211_CHAN_TURBO 0x0010 /* Turbo channel */
-#define IEEE80211_CHAN_CCK 0x0020 /* CCK channel */
-#define IEEE80211_CHAN_OFDM 0x0040 /* OFDM channel */
-#define IEEE80211_CHAN_2GHZ 0x0080 /* 2 GHz spectrum channel. */
-#define IEEE80211_CHAN_5GHZ 0x0100 /* 5 GHz spectrum channel */
-#define IEEE80211_CHAN_PASSIVE 0x0200 /* Only passive scan allowed */
-#define IEEE80211_CHAN_DYN 0x0400 /* Dynamic CCK-OFDM channel */
-#define IEEE80211_CHAN_GFSK 0x0800 /* GFSK channel (FHSS PHY) */
-#define IEEE80211_CHAN_XR 0x1000 /* Extended range OFDM channel */
-
-/*
- * Useful combinations of channel characteristics.
- */
-#define IEEE80211_CHAN_FHSS \
- (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
-#define IEEE80211_CHAN_A \
- (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
-#define IEEE80211_CHAN_B \
- (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
-#define IEEE80211_CHAN_PUREG \
- (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
-#define IEEE80211_CHAN_G \
- (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
-#define IEEE80211_CHAN_T \
- (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO)
-#define IEEE80211_CHAN_TG \
- (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO)
-
#define IEEE80211_IS_CHAN_FHSS(_c) \
(((_c)->ic_flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS)
#define IEEE80211_IS_CHAN_A(_c) \
@@ -168,6 +138,11 @@ struct ieee80211_channel {
#define IEEE80211_PS_MAX_QUEUE 50 /* maximum saved packets */
+#define IEEE80211_SCAN_UNLOCKED 0x0
+#define IEEE80211_SCAN_LOCKED 0x1
+#define IEEE80211_SCAN_REQUEST 0x2
+#define IEEE80211_SCAN_RESUME 0x4
+
struct ieee80211com {
#ifdef __NetBSD__
struct ethercom ic_ec;
@@ -193,6 +168,8 @@ struct ieee80211com {
u_char ic_chan_scan[roundup(IEEE80211_CHAN_MAX,NBBY)];
struct ifqueue ic_mgtq;
struct ifqueue ic_pwrsaveq;
+ u_int ic_scan_lock; /* user-initiated scan */
+ u_int8_t ic_scan_count; /* count scans */
u_int32_t ic_flags; /* state flags */
u_int32_t ic_caps; /* capabilities */
u_int16_t ic_modecaps; /* set of mode capabilities */
@@ -321,7 +298,7 @@ u_int ieee80211_mhz2ieee(u_int, u_int);
u_int ieee80211_chan2ieee(struct ieee80211com *, struct ieee80211_channel *);
u_int ieee80211_ieee2mhz(u_int, u_int);
int ieee80211_setmode(struct ieee80211com *, enum ieee80211_phymode);
-void ieee80211_next_mode(struct ifnet *);
+enum ieee80211_phymode ieee80211_next_mode(struct ifnet *);
enum ieee80211_phymode ieee80211_chan2mode(struct ieee80211com *,
struct ieee80211_channel *);
diff --git a/usr.sbin/hostapd/privsep.c b/usr.sbin/hostapd/privsep.c
index e9848f8803c..40a11b4358a 100644
--- a/usr.sbin/hostapd/privsep.c
+++ b/usr.sbin/hostapd/privsep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: privsep.c,v 1.10 2005/05/23 22:55:15 henning Exp $ */
+/* $OpenBSD: privsep.c,v 1.11 2005/05/25 07:40:49 reyk Exp $ */
/*
* Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net>
@@ -34,9 +34,8 @@
#include <netinet/if_ether.h>
#include <arpa/inet.h>
-#include <dev/ic/if_wi_ieee.h>
-#include <dev/ic/if_wireg.h>
-#include <dev/ic/if_wi_hostap.h>
+#include <net80211/ieee80211.h>
+#include <net80211/ieee80211_ioctl.h>
#include <errno.h>
#include <event.h>
@@ -169,7 +168,7 @@ hostapd_priv(int fd, short sig, void *arg)
struct hostapd_config *cfg = (struct hostapd_config *)arg;
struct hostapd_node node;
struct ieee80211_bssid bssid;
- struct hostap_sta sta;
+ struct ieee80211_nodereq nr;
struct ifreq ifr;
int ret, cmd;
@@ -178,7 +177,7 @@ hostapd_priv(int fd, short sig, void *arg)
return;
bzero(&node, sizeof(struct hostapd_node));
- bzero(&sta, sizeof(struct hostap_sta));
+ bzero(&nr, sizeof(struct ieee80211_nodereq));
/* Get privsep command */
if (hostapd_may_read(fd, &cmd, sizeof(int)))
@@ -210,25 +209,24 @@ hostapd_priv(int fd, short sig, void *arg)
"[priv]: msg PRIV_APME_GETNODE received\n");
hostapd_must_read(fd, &node, sizeof(struct hostapd_node));
- bcopy(node.ni_macaddr, sta.addr, IEEE80211_ADDR_LEN);
+ bcopy(node.ni_macaddr, nr.nr_macaddr, IEEE80211_ADDR_LEN);
- strlcpy(ifr.ifr_name, cfg->c_apme_iface, sizeof(ifr.ifr_name));
- ifr.ifr_data = (caddr_t)&sta;
+ strlcpy(nr.nr_ifname, cfg->c_apme_iface, sizeof(ifr.ifr_name));
/* Try to get a station from the APME */
if (cfg->c_flags & HOSTAPD_CFG_F_APME) {
if ((ret = ioctl(cfg->c_apme,
- SIOCHOSTAP_GET, &ifr)) != 0)
+ SIOCG80211NODE, &nr)) != 0)
ret = errno;
} else
ret = ENXIO;
hostapd_must_write(fd, &ret, sizeof(int));
if (ret == 0) {
- node.ni_associd = sta.asid;
- node.ni_flags = sta.flags;
- node.ni_rssi = sta.sig_info;
- node.ni_capinfo = sta.capinfo;
+ node.ni_associd = nr.nr_associd;
+ node.ni_flags = IEEE80211_NODEREQ_STATE(nr.nr_state);
+ node.ni_rssi = nr.nr_rssi;
+ node.ni_capinfo = nr.nr_capinfo;
hostapd_must_write(fd, &node,
sizeof(struct hostapd_node));
@@ -240,12 +238,12 @@ hostapd_priv(int fd, short sig, void *arg)
"[priv]: msg PRIV_APME_DELNODE received\n");
hostapd_must_read(fd, &node, sizeof(struct hostapd_node));
- bcopy(node.ni_macaddr, sta.addr, IEEE80211_ADDR_LEN);
+ bcopy(node.ni_macaddr, nr.nr_macaddr, IEEE80211_ADDR_LEN);
/* Try to delete a station from the APME */
if (cfg->c_flags & HOSTAPD_CFG_F_APME) {
if ((ret = ioctl(cfg->c_apme,
- SIOCHOSTAP_DEL, &sta)) != 0)
+ SIOCS80211DELNODE, &nr)) != 0)
ret = errno;
} else
ret = ENXIO;
@@ -374,7 +372,7 @@ void
hostapd_sig_chld(int sig)
{
struct timeval tv;
-
+
tv.tv_sec = 0;
tv.tv_usec = 0;