diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2005-05-25 07:40:50 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2005-05-25 07:40:50 +0000 |
commit | 195394ca0fd77eaf853201a38a23a40bfb1d4e91 (patch) | |
tree | fa1f8457ab4564ce39538fc88528d2959064a196 | |
parent | dddc74b20f5c57dc55e2d67c27ee9a237c8021f3 (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.8 | 11 | ||||
-rw-r--r-- | sbin/ifconfig/ifconfig.c | 209 | ||||
-rw-r--r-- | sbin/wicontrol/wicontrol.c | 6 | ||||
-rw-r--r-- | sys/net80211/ieee80211.c | 9 | ||||
-rw-r--r-- | sys/net80211/ieee80211.h | 33 | ||||
-rw-r--r-- | sys/net80211/ieee80211_ioctl.c | 937 | ||||
-rw-r--r-- | sys/net80211/ieee80211_ioctl.h | 90 | ||||
-rw-r--r-- | sys/net80211/ieee80211_node.c | 38 | ||||
-rw-r--r-- | sys/net80211/ieee80211_node.h | 5 | ||||
-rw-r--r-- | sys/net80211/ieee80211_radiotap.h | 15 | ||||
-rw-r--r-- | sys/net80211/ieee80211_var.h | 41 | ||||
-rw-r--r-- | usr.sbin/hostapd/privsep.c | 32 |
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; |