experimental OpenBSD support
Brian Fundakowski Feldman
bfeldman
Tue Jun 24 10:39:43 PDT 2003
I've completed support for using OpenBSD as a kernel-only HostAP in
conjunction with hostapd as an 802.1x authenticator. Has anyone else
tried something like this? Check it out and tell me what you think!
Not all of the changes are useful only to OpenBSD, so hopefully it's
helpful to some other folks as well. Here are some miscellaneous notes:
1. Per-station keys could be quite a bit more expensive and not really
any more secure than broadcast keys changing "quickly" so I haven't
implemented them. I don't think there are many situations where it's
truly useful to have partitioning of individual AP's traffic from
eachother's view.
2. The kernel changes to OpenBSD are not all required, but there are
several important bug fixes/feature additions that the hostapd will
need. The kernel headers need to be reinstalled after patching.
3. Authorization is implemented differently in that it is divorced from
802.1x and accessed using the "back-channel" mechanisms on the network
interface (bpf + bpf-ioctl(BIOCSTAGGED)).
4. I've simply disabled the parts of hostapd on OpenBSD that should not
be used (/yet). I believe that it should still work on Linux with the
non-OpenBSD-specific changes made.
5. Thanks for making such a nice hostapd and authenticator! I'll be
happy to answer any questions about my changes.
--
Brian Fundakowski Feldman |
http://www.fla.fujitsu.com/
Software Specialist | Fujitsu Laboratories of
America
-------------- next part --------------
Index: hostapd/Makefile
===================================================================
RCS file: /u/cvs/SNOWNET/Snownet/hostap/hostapd/Makefile,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -u -r1.1.1.1 -r1.3
--- hostapd/Makefile 17 Jun 2003 19:01:21 -0000 1.1.1.1
+++ hostapd/Makefile 24 Jun 2003 13:06:28 -0000 1.3
@@ -1,8 +1,5 @@
-CC=gcc
-
-ifndef CFLAGS
-CFLAGS = -MMD -O2 -Wall -g
-endif
+DEBUG?= -g
+CFLAGS+= -Wall
# define HOSTAPD_DUMP_STATE to include SIGUSR1 handler for dumping state to
# a file (undefine it, if you want to save in binary size)
@@ -15,15 +12,17 @@
# CFLAGS += -DUSE_KERNEL_HEADERS -I/usr/src/linux/include
OBJS = hostapd.o eloop.o ieee802_1x.o eapol_sm.o radius.o md5.o rc4.o \
- common.o iapp.o ieee802_11.o config.o ieee802_11_auth.o accounting.o \
+ common.o ieee802_11.o config.o accounting.o \
sta_info.o driver.o receive.o radius_client.o
+NOTOPENBSD = iapp.o ieee802_11_auth.o
+LIBS = -lpcap
all: hostapd
hostapd: $(OBJS)
- $(CC) -o hostapd $(OBJS)
+ $(CC) $(LDFLAGS) -o hostapd $(OBJS) $(LIBS)
clean:
rm -f core *~ *.o hostapd *.d
--include $(OBJS:%.o=%.d)
+#-include $(OBJS:%.o=%.d)
Index: hostapd/accounting.c
===================================================================
RCS file: /u/cvs/SNOWNET/Snownet/hostap/hostapd/accounting.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- hostapd/accounting.c 17 Jun 2003 19:01:21 -0000 1.1.1.1
+++ hostapd/accounting.c 17 Jun 2003 19:04:18 -0000 1.2
@@ -151,7 +151,10 @@
{
struct radius_msg *msg;
int cause = sta->acct_terminate_cause;
+#ifndef __OpenBSD__
+ /* XXX OpenBSD has no support for per-host wireless accounting. */
struct hostap_sta_driver_data data;
+#endif
if (!hapd->conf->acct_server)
return;
@@ -168,6 +171,7 @@
goto fail;
}
+#ifndef __OpenBSD__
if (hostapd_read_sta_driver_data(hapd, &data, sta->addr) == 0) {
if (!radius_msg_add_attr_int32(msg,
RADIUS_ATTR_ACCT_INPUT_PACKETS,
@@ -194,6 +198,7 @@
goto fail;
}
}
+#endif
if (eloop_terminated())
cause = RADIUS_ACCT_TERMINATE_CAUSE_ADMIN_REBOOT;
Index: hostapd/ap.h
===================================================================
RCS file: /u/cvs/SNOWNET/Snownet/hostap/hostapd/ap.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ap.h
--- hostapd/ap.h 17 Jun 2003 19:01:21 -0000 1.1.1.1
+++ hostapd/ap.h 24 Jun 2003 13:15:09 -0000
@@ -73,6 +73,13 @@
#define STA_HASH(sta) (sta[5])
+#ifdef __OpenBSD__
+/*
+ * Since we're only polling the kernel for when _it_ has removed a client,
+ * we can check more often on OpenBSD.
+ */
+#define AP_MAX_INACTIVITY 10
+#else
/* Default value for maximum station inactivity. After AP_MAX_INACTIVITY has
* passed since last received frame from the station, a nullfunc data frame is
* sent to the station. If this frame is not acknowledged and no other frames
@@ -81,6 +88,7 @@
* AP_DEAUTH_DELAY. AP_TIMEOUT_RESOLUTION is the resolution that is used with
* max inactivity timer. All these times are in seconds. */
#define AP_MAX_INACTIVITY (5 * 60)
+#endif
#define AP_DISASSOC_DELAY (1)
#define AP_DEAUTH_DELAY (1)
Index: hostapd/common.h
===================================================================
RCS file: /u/cvs/SNOWNET/Snownet/hostap/hostapd/common.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- hostapd/common.h 17 Jun 2003 19:01:21 -0000 1.1.1.1
+++ hostapd/common.h 17 Jun 2003 19:04:19 -0000 1.2
@@ -1,6 +1,24 @@
#ifndef COMMON_H
#define COMMON_H
+#ifdef __OpenBSD__
+#include <sys/types.h>
+#include <machine/endian.h>
+#define le_to_host16(n) letoh16(n)
+#define host_to_le16(n) htole16(n)
+#define be_to_host16(n) betoh16(n)
+#define host_to_be16(n) htobe16(n)
+
+typedef u_int64_t u64;
+typedef u_int32_t u32;
+typedef u_int16_t u16;
+typedef u_int8_t u8;
+typedef int64_t s64;
+typedef int32_t s32;
+typedef int16_t s16;
+typedef int8_t s8;
+
+#else
#include <endian.h>
#include <byteswap.h>
#if __BYTE_ORDER == __LITTLE_ENDIAN
@@ -25,6 +43,7 @@
typedef int32_t s32;
typedef int16_t s16;
typedef int8_t s8;
+#endif
int hostapd_get_rand(u8 *buf, size_t len);
void hostapd_hexdump(const char *title, u8 *buf, size_t len);
Index: hostapd/config.c
===================================================================
RCS file: /u/cvs/SNOWNET/Snownet/hostap/hostapd/config.c,v
retrieving revision 1.1.1.1
retrieving revision 1.4
diff -u -r1.1.1.1 -r1.4
--- hostapd/config.c 17 Jun 2003 19:01:21 -0000 1.1.1.1
+++ hostapd/config.c 24 Jun 2003 12:24:34 -0000 1.4
@@ -193,6 +193,7 @@
if (pos == NULL) {
printf("Line %d: invalid line '%s'\n", line, buf);
errors++;
+ continue;
}
*pos = '\0';
pos++;
@@ -252,6 +253,8 @@
conf->assoc_ap = 1;
} else if (strcmp(buf, "ieee8021x") == 0) {
conf->ieee802_1x = atoi(pos);
+ } else if (strcmp(buf, "port_authorization") == 0) {
+ conf->port_authorization = atoi(pos);
} else if (strcmp(buf, "minimal_eap") == 0) {
conf->minimal_eap = atoi(pos);
} else if (strcmp(buf, "eap_message") == 0) {
@@ -284,6 +287,8 @@
}
} else if (strcmp(buf, "eapol_key_index_workaround") == 0) {
conf->eapol_key_index_workaround = atoi(pos);
+ } else if (strcmp(buf, "wep_need_two_keys_immediately") == 0) {
+ conf->wep_need_two_keys = atoi(pos);
} else if (strcmp(buf, "iapp_interface") == 0) {
conf->ieee802_11f = 1;
snprintf(conf->iapp_iface, sizeof(conf->iapp_iface),
Index: hostapd/config.h
===================================================================
RCS file: /u/cvs/SNOWNET/Snownet/hostap/hostapd/config.h,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -u -r1.1.1.1 -r1.3
--- hostapd/config.h 17 Jun 2003 19:01:21 -0000 1.1.1.1
+++ hostapd/config.h 24 Jun 2003 12:24:34 -0000 1.3
@@ -34,6 +34,7 @@
int daemonize; /* fork into background */
int ieee802_1x; /* use IEEE 802.1X */
+ int port_authorization; /* enable/disable 802.11 ports via kernel */
int minimal_eap; /* test version of EAP authentication that only
* requires EAP Response-Identity and authorizes any
* station */
@@ -55,6 +56,7 @@
size_t default_wep_key_len;
int individual_wep_key_len;
int wep_rekeying_period;
+ int wep_need_two_keys;
int ieee802_11f; /* use IEEE 802.11f (IAPP) */
char iapp_iface[IFNAMSIZ + 1]; /* interface used with IAPP broadcast
Index: hostapd/driver.c
===================================================================
RCS file: /u/cvs/SNOWNET/Snownet/hostap/hostapd/driver.c,v
retrieving revision 1.1.1.1
retrieving revision 1.4
diff -u -r1.1.1.1 -r1.4
--- hostapd/driver.c 17 Jun 2003 19:01:21 -0000 1.1.1.1
+++ hostapd/driver.c 24 Jun 2003 11:46:46 -0000 1.4
@@ -13,10 +13,19 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <sys/types.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
-#ifdef USE_KERNEL_HEADERS
+#if defined(__OpenBSD__)
+#include <sys/socket.h>
+#include <net/if.h>
+#include <net/if_media.h>
+#include <net/if_arp.h>
+#include <netinet/if_ether.h> /* The L2 protocols */
+#include <net/if_ieee80211.h>
+#include <dev/ic/if_wi_hostap.h>
+#elif defined(USE_KERNEL_HEADERS)
#include <asm/types.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h> /* The L2 protocols */
@@ -31,6 +40,7 @@
#include "hostapd.h"
#include "driver.h"
#include "ieee802_1x.h"
+#include "ieee802_11.h"
int hostapd_set_iface_flags(hostapd *hapd, int dev_up)
@@ -41,7 +51,11 @@
return -1;
memset(&ifr, 0, sizeof(ifr));
+#ifdef __OpenBSD__
+ strncpy(ifr.ifr_name, hapd->conf->iface, IFNAMSIZ);
+#else
snprintf(ifr.ifr_name, IFNAMSIZ, "%sap", hapd->conf->iface);
+#endif
if (ioctl(hapd->ioctl_sock, SIOCGIFFLAGS, &ifr) != 0) {
perror("ioctl[SIOCGIFFLAGS]");
@@ -59,6 +73,31 @@
}
if (dev_up) {
+#ifdef __OpenBSD__
+ int flags;
+
+ ifr.ifr_media = IFM_MAKEWORD(IFM_TYPE(IFM_IEEE80211),
+ IFM_SUBTYPE(IFM_AUTO),
+ IFM_OPTIONS(IFM_IEEE80211|IFM_IEEE80211_HOSTAP),
+ IFM_INST(0));
+ if (ioctl(hapd->ioctl_sock, SIOCSIFMEDIA, &ifr) != 0) {
+ perror("ioctl[SIOCSIFMEDIA]");
+ return -1;
+ }
+ ifr.ifr_data = (void *)&flags;
+ if (ioctl(hapd->ioctl_sock, SIOCHOSTAP_GFLAGS, &ifr) != 0) {
+ perror("ioctl[SIOCHOSTAP_GFLAGS]");
+ return -1;
+ }
+ if (hapd->conf->port_authorization)
+ flags |= WIHAPFL_AUTHORIZED_FILT;
+ else
+ flags &= ~WIHAPFL_AUTHORIZED_FILT;
+ if (ioctl(hapd->ioctl_sock, SIOCHOSTAP_SFLAGS, &ifr) != 0) {
+ perror("ioctl[SIOCHOSTAP_SFLAGS]");
+ return -1;
+ }
+#else
memset(&ifr, 0, sizeof(ifr));
snprintf(ifr.ifr_name, IFNAMSIZ, "%sap", hapd->conf->iface);
ifr.ifr_mtu = HOSTAPD_MTU;
@@ -67,12 +106,139 @@
printf("Setting MTU failed - trying to survive with "
"current value\n");
}
+#endif
}
return 0;
}
+#ifdef __OpenBSD__
+int hostap_ioctl_setiwessid(hostapd *hapd, char *buf, int len)
+{
+ struct ieee80211_nwid nwid;
+ struct ifreq ifr;
+
+ len--; /* The NUL byte has been included. */
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, hapd->conf->iface, IFNAMSIZ);
+ nwid.i_len = len < sizeof(nwid.i_nwid) ? len : sizeof(nwid.i_nwid);
+ memcpy(nwid.i_nwid, buf, nwid.i_len);
+ ifr.ifr_data = (void *)&nwid;
+ if (ioctl(hapd->ioctl_sock, SIOCS80211NWID, &ifr) != 0) {
+ perror("ioctl[SIOCS80211NWID]");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+void remove_sta(hostapd *hapd, struct sta_info *sta)
+{
+ struct hostap_sta hapsta;
+ struct ifreq ifr;
+ int error;
+
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, hapd->conf->iface, IFNAMSIZ);
+ ifr.ifr_data = (void *)&hapsta;
+ memcpy(hapsta.addr, sta->addr, ETH_ALEN);
+ if (sta->flags & WLAN_STA_ASSOC && sta->flags & WLAN_STA_AUTH) {
+ /* Here, we are called FROM ieee802_1x_set_port_enabled(). */
+ error = ioctl(hapd->ioctl_sock, SIOCHOSTAP_GET, &ifr);
+ if (error == 0) {
+ hapsta.flags &= ~HOSTAP_FLAGS_AUTHORIZED;
+ error = ioctl(hapd->ioctl_sock, SIOCHOSTAP_CHANGE,
+ &ifr);
+ }
+ } else if (sta->flags & (WLAN_STA_ASSOC | WLAN_STA_AUTH)) {
+ /* Remove just assoc or auth. */
+ error = ioctl(hapd->ioctl_sock, SIOCHOSTAP_GET, &ifr);
+ if (error == 0) {
+ if (sta->flags & WLAN_STA_AUTH)
+ hapsta.flags &= ~HOSTAP_FLAGS_ASSOC;
+ else
+ hapsta.flags &= ~HOSTAP_FLAGS_AUTHEN;
+ error = ioctl(hapd->ioctl_sock, SIOCHOSTAP_CHANGE,
+ &ifr);
+ }
+ } else {
+ ieee802_1x_set_port_enabled(hapd, sta, 0);
+ error = ioctl(hapd->ioctl_sock, SIOCHOSTAP_DEL, &ifr);
+ }
+ if (error != 0) {
+ perror("ioctl");
+ printf("Could not remove STA " MACSTR " from kernel driver.\n",
+ MAC2STR(sta->addr));
+ }
+}
+
+
+void hostapd_set_sta_authorized(hostapd *hapd, struct sta_info *sta)
+{
+ struct hostap_sta hapsta;
+ struct ifreq ifr;
+ int error;
+
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, hapd->conf->iface, IFNAMSIZ);
+ ifr.ifr_data = (void *)&hapsta;
+ memcpy(hapsta.addr, sta->addr, ETH_ALEN);
+ error = ioctl(hapd->ioctl_sock, SIOCHOSTAP_GET, &ifr);
+ if (error == 0) {
+ hapsta.flags |= HOSTAP_FLAGS_AUTHORIZED;
+ error = ioctl(hapd->ioctl_sock, SIOCHOSTAP_CHANGE, &ifr);
+ }
+ if (error != 0) {
+ perror("ioctl");
+ printf("Could not authorize STA " MACSTR " in kernel driver.\n",
+ MAC2STR(sta->addr));
+ }
+}
+
+
+int hostapd_read_sta_driver_flags(hostapd *hapd, u8 *sta)
+{
+ struct hostap_sta hapsta;
+ struct ifreq ifr;
+
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, hapd->conf->iface, IFNAMSIZ);
+ ifr.ifr_data = (void *)&hapsta;
+ memcpy(hapsta.addr, sta, ETH_ALEN);
+ if (ioctl(hapd->ioctl_sock, SIOCHOSTAP_GET, &ifr) != 0)
+ return -1;
+ return (((hapsta.flags & HOSTAP_FLAGS_AUTHEN) ? WLAN_STA_AUTH : 0) |
+ ((hapsta.flags & HOSTAP_FLAGS_ASSOC) ? WLAN_STA_ASSOC : 0) |
+ ((hapsta.flags & HOSTAP_FLAGS_AUTHORIZED) ?
+ WLAN_STA_AUTHORIZED : 0));
+}
+
+
+int hostapd_set_encryption(hostapd *hapd, const char *alg, u8 *addr,
+ int idx, u8 *key, size_t key_len)
+{
+ struct ieee80211_nwkey nwkey;
+
+ memset(&nwkey, 0, sizeof(nwkey));
+ if (addr != NULL) {
+ printf("Cannot use per-host WEP on OpenBSD.\n");
+ return -1;
+ }
+ strncpy(nwkey.i_name, hapd->conf->iface, IFNAMSIZ);
+ nwkey.i_wepon = IEEE80211_NWKEY_WEP;
+ nwkey.i_defkid = idx + 1;
+ nwkey.i_key[idx].i_keylen = key_len;
+ nwkey.i_key[idx].i_keydat = key;
+ if (ioctl(hapd->ioctl_sock, SIOCS80211NWKEY, &nwkey) != 0) {
+ printf("Failed to set encryption.\n");
+ return -1;
+ }
+
+ return 0;
+}
+#else
int hostapd_ioctl(hostapd *hapd, struct prism2_hostapd_param *param, int len)
{
struct iwreq iwr;
@@ -222,12 +388,18 @@
{
struct prism2_hostapd_param param;
- ieee802_1x_set_port_enabled(hapd, sta, 0);
-
memset(¶m, 0, sizeof(param));
- param.cmd = PRISM2_HOSTAPD_REMOVE_STA;
memcpy(param.sta_addr, sta->addr, ETH_ALEN);
- if (hostapd_ioctl(hapd, ¶m, sizeof(param))) {
- printf("Could not remove station from kernel driver.\n");
+ if (sta->flags & WLAN_STA_ASSOC && sta->flags & WLAN_STA_AUTH) {
+ /* Removed WLAN_STA_AUTHORIZED */
+ param.cmd = PRISM2_HOSTAPD_SET_FLAGS_STA;
+ param.u.set_flags_sta.flags_and = ~WLAN_STA_AUTHORIZED;
+ } else {
+ /* Removing station completely */
+ ieee802_1x_set_port_enabled(hapd, sta, 0);
+ param.cmd = PRISM2_HOSTAPD_REMOVE_STA;
}
+ if (hostapd_ioctl(hapd, ¶m, sizeof(param)))
+ printf("Could not remove station from kernel driver.\n");
}
+#endif
Index: hostapd/driver.h
===================================================================
RCS file: /u/cvs/SNOWNET/Snownet/hostap/hostapd/driver.h,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -u -r1.1.1.1 -r1.3
--- hostapd/driver.h 17 Jun 2003 19:01:21 -0000 1.1.1.1
+++ hostapd/driver.h 23 Jun 2003 21:43:25 -0000 1.3
@@ -12,10 +12,14 @@
int hostap_ioctl_setiwessid(hostapd *hapd, char *buf, int len);
int hostapd_set_encryption(hostapd *hapd, const char *alg, u8 *addr,
int idx, u8 *key, size_t key_len);
+void hostapd_set_sta_authorized(hostapd *hapd, struct sta_info *sta);
void remove_sta(hostapd *hapd, struct sta_info *sta);
int hostapd_flush(hostapd *hapd);
int hostapd_read_sta_driver_data(hostapd *hapd,
struct hostap_sta_driver_data *data,
u8 *addr);
+#ifdef __OpenBSD__
+int hostapd_read_sta_driver_flags(hostapd *hapd, u8 *sta);
+#endif
#endif /* DRIVER_H */
Index: hostapd/eloop.c
===================================================================
RCS file: /u/cvs/SNOWNET/Snownet/hostap/hostapd/eloop.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- hostapd/eloop.c 17 Jun 2003 19:01:21 -0000 1.1.1.1
+++ hostapd/eloop.c 17 Jun 2003 19:04:19 -0000 1.2
@@ -39,6 +39,7 @@
int sig;
void *user_data;
void (*handler)(int sig, void *eloop_ctx, void *signal_ctx);
+ int raised;
};
struct eloop_data {
@@ -170,16 +171,30 @@
}
+/* Execute signals in a safe context so non-recursive functions can be used. */
static void eloop_handle_signal(int sig)
{
int i;
for (i = 0; i < eloop.signal_count; i++) {
if (eloop.signals[i].sig == sig) {
+ eloop.signals[i].raised = 1;
+ break;
+ }
+ }
+}
+
+
+static void eloop_do_signal_handlers(void)
+{
+ int i;
+
+ for (i = 0; i < eloop.signal_count; i++) {
+ if (eloop.signals[i].raised) {
+ eloop.signals[i].raised = 0;
eloop.signals[i].handler(eloop.signals[i].sig,
eloop.user_data,
eloop.signals[i].user_data);
- break;
}
}
}
@@ -202,6 +217,7 @@
tmp[eloop.signal_count].sig = sig;
tmp[eloop.signal_count].user_data = user_data;
tmp[eloop.signal_count].handler = handler;
+ tmp[eloop.signal_count].raised = 0;
eloop.signal_count++;
eloop.signals = tmp;
signal(sig, eloop_handle_signal);
@@ -235,9 +251,12 @@
FD_SET(eloop.readers[i].sock, &rfds);
res = select(eloop.max_sock + 1, &rfds, NULL, NULL,
eloop.timeout ? &tv : NULL);
- if (res < 0 && errno != EINTR) {
- perror("select");
- return;
+ if (res < 0) {
+ if (errno != EINTR) {
+ perror("select");
+ return;
+ }
+ eloop_do_signal_handlers();
}
/* check if some registered timeouts have occurred */
Index: hostapd/hostapd.c
===================================================================
RCS file: /u/cvs/SNOWNET/Snownet/hostap/hostapd/hostapd.c,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -u -r1.1.1.1 -r1.3
--- hostapd/hostapd.c 17 Jun 2003 19:01:21 -0000 1.1.1.1
+++ hostapd/hostapd.c 24 Jun 2003 12:24:34 -0000 1.3
@@ -20,6 +20,7 @@
#include <stdarg.h>
#include <sys/types.h>
#include <sys/socket.h>
+#include <pcap.h>
#include "eloop.h"
#include "hostapd.h"
@@ -27,7 +28,9 @@
#include "ieee802_11.h"
#include "accounting.h"
#include "eapol_sm.h"
+#ifndef __OpenBSD__
#include "iapp.h"
+#endif
#include "ap.h"
#include "ieee802_11_auth.h"
#include "sta_info.h"
@@ -146,9 +149,11 @@
/* This function will be called whenever a station associates with the AP */
void hostapd_new_assoc_sta(hostapd *hapd, struct sta_info *sta)
{
+#ifndef __OpenBSD__
/* IEEE 802.11f (IAPP) */
if (hapd->conf->ieee802_11f)
iapp_new_station(hapd, sta);
+#endif
/* Start accounting here, if IEEE 802.1X is not used. IEEE 802.1X code
* will start accounting after the station has been authorized. */
@@ -293,13 +298,21 @@
* the key index, and direct Key Transmit State Machines of all of the
* authenticators to send a new key to the authenticated stations.
*/
-static void hostapd_rotate_wep(void *eloop_ctx, void *timeout_ctx)
+static void hostapd_do_rotate_wep(hostapd *hapd)
{
struct sta_info *s;
- hostapd *hapd = eloop_ctx;
- if (hapd->default_wep_key)
+ if (hapd->conf->wep_need_two_keys) {
+ /*
+ * Generate two WEP keys here, the minimum for Windows if not
+ * using any unicast keys.
+ */
+ free(hapd->default_wep_key_2);
+ hapd->default_wep_key_2 = hapd->default_wep_key;
+ hapd->default_wep_key_idx_2 = hapd->default_wep_key_idx;
+ } else {
free(hapd->default_wep_key);
+ }
if (hapd->default_wep_key_idx >= 3)
hapd->default_wep_key_idx =
@@ -327,7 +340,15 @@
hapd->conf->default_wep_key_len)) {
printf("Could not set WEP encryption.\n");
}
+}
+
+/* Rotate WEP keys and register for rekeying if necessary. */
+static void hostapd_rotate_wep(void *eloop_ctx, void *timeout_ctx)
+{
+ hostapd *hapd = eloop_ctx;
+
+ hostapd_do_rotate_wep(hapd);
if (hapd->conf->wep_rekeying_period > 0)
eloop_register_timeout(hapd->conf->wep_rekeying_period, 0,
hostapd_rotate_wep, hapd, NULL);
@@ -336,16 +357,25 @@
static void hostapd_cleanup(hostapd *hapd)
{
- if (hapd->sock >= 0)
- close(hapd->sock);
+ if (hapd->sock >= 0) {
+ if (hapd->pcap != NULL)
+ pcap_close(hapd->pcap);
+ else
+ close(hapd->sock);
+ }
if (hapd->ioctl_sock >= 0)
close(hapd->ioctl_sock);
free(hapd->default_wep_key);
+ free(hapd->default_wep_key_2);
+#ifndef __OpenBSD__
if (hapd->conf->ieee802_11f)
iapp_deinit(hapd);
+#endif
accounting_deinit(hapd);
ieee802_1x_deinit(hapd);
+#ifndef __OpenBSD__
hostapd_acl_deinit(hapd);
+#endif
radius_client_deinit(hapd);
hostapd_config_free(hapd->conf);
@@ -359,11 +389,13 @@
{
int ret = 0;
+#ifndef __OpenBSD__
printf("Flushing old station entries\n");
if (hostapd_flush(hapd)) {
printf("Could not connect to kernel driver.\n");
ret = -1;
}
+#endif
printf("Deauthenticate all stations\n");
hostapd_deauth_all_stas(hapd);
@@ -376,13 +408,22 @@
if (HOSTAPD_DEBUG_COND(HOSTAPD_DEBUG_MINIMAL))
hostapd_hexdump("Default WEP key", hapd->default_wep_key,
hapd->conf->default_wep_key_len);
+ if (HOSTAPD_DEBUG_COND(HOSTAPD_DEBUG_MINIMAL) &&
+ hapd->default_wep_key_2 != NULL)
+ hostapd_hexdump("Default WEP key #2", hapd->default_wep_key_2,
+ hapd->conf->default_wep_key_len);
hostapd_set_encryption(hapd, "none", NULL, 0, NULL, 0);
if (hostapd_set_encryption(hapd, "WEP", NULL,
hapd->default_wep_key_idx,
hapd->default_wep_key,
- hapd->conf->default_wep_key_len)) {
+ hapd->conf->default_wep_key_len) ||
+ (hapd->default_wep_key_2 != NULL &&
+ hostapd_set_encryption(hapd, "WEP", NULL,
+ hapd->default_wep_key_idx_2,
+ hapd->default_wep_key_2,
+ hapd->conf->default_wep_key_len))) {
printf("Could not set WEP encryption.\n");
return -1;
}
@@ -408,16 +449,18 @@
return -1;
}
+#ifndef __OpenBSD__
if (hostap_ioctl_prism2param(hapd, PRISM2_PARAM_HOSTAPD, 1)) {
printf("Could not enable hostapd mode for interface %s\n",
hapd->conf->iface);
return -1;
}
+#endif
if (hostapd_init_sockets(hapd))
return -1;
- printf("Using interface %sap with hwaddr " MACSTR " and ssid '%s'\n",
+ printf("Using interface %s with hwaddr " MACSTR " and ssid '%s'\n",
hapd->conf->iface, MAC2STR(hapd->own_addr), hapd->conf->ssid);
/* Set SSID for the kernel driver (to be used in beacon and probe
@@ -433,10 +476,12 @@
return -1;
}
+#ifndef __OpenBSD__
if (hostapd_acl_init(hapd)) {
printf("ACL initialization failed.\n");
return -1;
}
+#endif
if (ieee802_1x_init(hapd)) {
printf("IEEE 802.1X initialization failed.\n");
@@ -448,10 +493,12 @@
return -1;
}
+#ifndef __OpenBSD__
if (hapd->conf->ieee802_11f && iapp_init(hapd)) {
printf("IEEE 802.11f (IAPP) initialization failed.\n");
return -1;
}
+#endif
if (hapd->default_wep_key && hostapd_setup_encryption(hapd))
return -1;
@@ -561,6 +608,7 @@
eloop_register_signal(SIGINT, handle_term, NULL);
eloop_register_signal(SIGTERM, handle_term, NULL);
eloop_register_signal(SIGUSR1, handle_dump_state, NULL);
+ eloop_register_signal(SIGINFO, handle_dump_state, NULL);
for (i = 0; i < interfaces.count; i++) {
printf("Configuration file: %s\n", argv[optind + i]);
@@ -568,6 +616,8 @@
if (!interfaces.hapd[i])
goto out;
hostapd_set_broadcast_wep(interfaces.hapd[i]);
+ if (interfaces.hapd[i]->conf->wep_need_two_keys)
+ hostapd_do_rotate_wep(interfaces.hapd[i]);
if (hostapd_setup_interface(interfaces.hapd[i]))
goto out;
}
@@ -593,8 +643,10 @@
if (!interfaces.hapd[i])
continue;
(void) hostapd_set_iface_flags(interfaces.hapd[i], 0);
+#ifndef __OpenBSD__
(void) hostap_ioctl_prism2param(interfaces.hapd[i],
PRISM2_PARAM_HOSTAPD, 0);
+#endif
hostapd_cleanup(interfaces.hapd[i]);
free(interfaces.hapd[i]);
Index: hostapd/hostapd.conf
===================================================================
RCS file: /u/cvs/SNOWNET/Snownet/hostap/hostapd/hostapd.conf,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -u -r1.1.1.1 -r1.3
--- hostapd/hostapd.conf 17 Jun 2003 19:01:21 -0000 1.1.1.1
+++ hostapd/hostapd.conf 24 Jun 2003 12:44:10 -0000 1.3
@@ -3,7 +3,7 @@
# AP netdevice name (without 'ap' prefix, i.e., wlan0 uses wlan0ap for
# management frames)
-interface=wlan0
+interface=wi0
# hostapd event logger configuration
#
@@ -26,22 +26,22 @@
logger_syslog=-1
logger_syslog_level=2
logger_stdout=-1
-logger_stdout_level=2
+logger_stdout_level=4
# Debugging: 0 = no, 1 = minimal, 2 = verbose, 3 = msg dumps
-debug=0
+debug=3
-# Dump file for state information (on SIGUSR1)
-dump_file=/tmp/hostapd.dump
+# Dump file for state information (on SIGUSR1/SIGINFO)
+dump_file=/dev/stderr
# Daemonize hostapd process (i.e., fork to background)
-daemonize=1
+daemonize=0
##### IEEE 802.11 related configuration #######################################
# SSID to be used in IEEE 802.11 management frames
-ssid=test
+ssid=something
# Station MAC address -based authentication
# 0 = accept unless in deny list
@@ -61,7 +61,7 @@
# Bit fields of allowed authentication algorithms:
# bit 0 = Open System Authentication
# bit 1 = Shared Key Authentication (requires WEP)
-auth_algs=3
+auth_algs=0
# Associate as a station to another AP while still acting as an AP on the same
# channel.
@@ -71,7 +71,10 @@
##### IEEE 802.1X (and IEEE 802.1aa/D4) related configuration #################
# Require IEEE 802.1X authorization
-#ieee8021x=1
+ieee8021x=1
+
+# Use OS's 802.11 port authorization
+port_authorization=1
# Use internal minimal EAP Authentication Server for testing IEEE 802.1X.
# This should only be used for testing since it authorizes all users that
@@ -79,20 +82,26 @@
minimal_eap=0
# Optional displayable message sent with EAP Request-Identity
-eap_message=hello
+eap_message=Snownet
# WEP rekeying (disabled if key lengths are not set or are set to 0)
# Key lengths for default/broadcast and individual/unicast keys:
# 5 = 40-bit WEP (also known as 64-bit WEP with 40 secret bits)
# 13 = 104-bit WEP (also known as 128-bit WEP with 104 secret bits)
-#wep_key_len_broadcast=5
-#wep_key_len_unicast=5
+wep_key_len_broadcast=5
+# Unicast keys aren't supported on OpenBSD
+wep_key_len_unicast=0
# Rekeying period in seconds. 0 = do not rekey (i.e., set keys only once)
-#wep_rekey_period=300
+wep_rekey_period=300
# EAPOL-Key index workaround (set bit7) for WinXP Supplicant (needed only if
# only broadcast keys are used)
-eapol_key_index_workaround=0
+eapol_key_index_workaround=1
+
+# WEP keying workaround for Windows supplicants et al which require two
+# keys immediately. This is necessary only if unicast keys are disabled
+# (wep_key_len_unicast=0).
+wep_need_two_keys_immediately=1
##### IEEE 802.11f - Inter-Access Point Protocol (IAPP) #######################
@@ -106,12 +115,12 @@
# authentication with external ACL for MAC addresses, and accounting
# The own IP address of the access point (used as NAS-IP-Address)
-own_ip_addr=127.0.0.1
+own_ip_addr=128.8.244.58
# RADIUS authentication server
-#auth_server_addr=127.0.0.1
-#auth_server_port=1812
-#auth_server_shared_secret=secret
+auth_server_addr=128.8.244.14
+auth_server_port=1812
+auth_server_shared_secret=12345678
# RADIUS accounting server
#acct_server_addr=127.0.0.1
Index: hostapd/hostapd.h
===================================================================
RCS file: /u/cvs/SNOWNET/Snownet/hostap/hostapd/hostapd.h,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -u -r1.1.1.1 -r1.3
--- hostapd/hostapd.h 17 Jun 2003 19:01:21 -0000 1.1.1.1
+++ hostapd/hostapd.h 24 Jun 2003 12:24:34 -0000 1.3
@@ -13,10 +13,14 @@
#ifndef ETH_P_ALL
#define ETH_P_ALL 0x0003
#endif
+#ifndef ETH_P_PAE
+#define ETH_P_PAE 0x888e
+#endif
#include "hostap_wlan.h"
#include "config.h"
+struct pcap;
struct ieee80211_hdr {
u16 frame_control;
@@ -49,6 +53,7 @@
char *config_fname;
int sock; /* raw packet socket for driver access */
+ struct pcap *pcap; /* possible pcap associated with sock */
int ioctl_sock; /* socket for ioctl() use */
u8 own_addr[6];
@@ -63,8 +68,8 @@
struct sta_info *sta_aid[MAX_AID_TABLE_SIZE];
- u8 *default_wep_key;
- u8 default_wep_key_idx;
+ u8 *default_wep_key, *default_wep_key_2;
+ u8 default_wep_key_idx, default_wep_key_idx_2;
struct radius_client_data *radius;
Index: hostapd/ieee802_11.c
===================================================================
RCS file: /u/cvs/SNOWNET/Snownet/hostap/hostapd/ieee802_11.c,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -u -r1.1.1.1 -r1.3
--- hostapd/ieee802_11.c 17 Jun 2003 19:01:21 -0000 1.1.1.1
+++ hostapd/ieee802_11.c 23 Jun 2003 21:43:25 -0000 1.3
@@ -12,7 +12,10 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
#include <net/if.h>
+#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
@@ -28,6 +31,93 @@
#include "rc4.h"
+static struct sta_info * auth_get_sta(hostapd *hapd, u8 *addr, int *isnew)
+{
+ struct sta_info *sta;
+
+ if (isnew != NULL)
+ *isnew = 0;
+ sta = ap_get_sta(hapd, addr);
+ if (sta)
+ return sta;
+
+ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, " New STA\n");
+ if (hapd->num_sta >= MAX_STA_COUNT) {
+ /* FIX: might try to remove some old STAs first? */
+ printf(" no more room for new STAs (%d/%d)\n",
+ hapd->num_sta, MAX_STA_COUNT);
+ return NULL;
+ }
+
+ sta = (struct sta_info *) malloc(sizeof(struct sta_info));
+ if (sta == NULL) {
+ printf(" malloc failed\n");
+ return NULL;
+ }
+ memset(sta, 0, sizeof(struct sta_info));
+ sta->radius_identifier = -1;
+ sta->acct_session_id_lo = hapd->radius->acct_session_id_lo++;
+
+ /* initialize STA info data */
+ eloop_register_timeout(AP_MAX_INACTIVITY, 0, ap_handle_timer,
+ hapd, sta);
+ memcpy(sta->addr, addr, ETH_ALEN);
+ sta->next = hapd->sta_list;
+ hapd->sta_list = sta;
+ hapd->num_sta++;
+ ap_sta_hash_add(hapd, sta);
+ if (isnew != NULL)
+ *isnew = 1;
+ return sta;
+}
+
+
+#ifdef __OpenBSD__
+struct sta_info * ieee802_11_locate_sta(hostapd *hapd, u8 *addr)
+{
+ struct sta_info *sta;
+ int isnew;
+
+ sta = auth_get_sta(hapd, addr, &isnew);
+ if (isnew) {
+ sta->flags |= WLAN_STA_ASSOC | WLAN_STA_AUTH;
+ hostapd_new_assoc_sta(hapd, sta);
+ }
+ return sta;
+}
+
+
+void ieee802_11_send_disassoc(hostapd *hapd, u8 *addr, u8 reason)
+{
+
+ /* Cheat for "the" broadcast address. */
+ if (memcmp("\377\377\377\377\377\377", addr, 6) != 0) {
+ struct sta_info *sta;
+
+ sta = ap_get_sta(hapd, addr);
+ if (sta != NULL) {
+ sta->flags &= ~WLAN_STA_ASSOC;
+ remove_sta(hapd, sta);
+ }
+ } else {
+ hostapd_free_stas(hapd);
+ }
+}
+
+
+void ieee802_11_send_deauth(hostapd *hapd, u8 *addr, u8 reason)
+{
+ struct sta_info *sta;
+
+ sta = ap_get_sta(hapd, addr);
+ if (sta != NULL) {
+ sta->flags &= ~WLAN_STA_ASSOC;
+ remove_sta(hapd, sta);
+ }
+}
+
+
+#else
static u8 * hostapd_eid_supp_rates(hostapd *hapd, u8 *eid)
{
u8 *pos = eid;
@@ -252,43 +342,6 @@
}
-static struct sta_info * auth_get_sta(hostapd *hapd, u8 *addr)
-{
- struct sta_info *sta;
-
- sta = ap_get_sta(hapd, addr);
- if (sta)
- return sta;
-
- HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, " New STA\n");
- if (hapd->num_sta >= MAX_STA_COUNT) {
- /* FIX: might try to remove some old STAs first? */
- printf(" no more room for new STAs (%d/%d)\n",
- hapd->num_sta, MAX_STA_COUNT);
- return NULL;
- }
-
- sta = (struct sta_info *) malloc(sizeof(struct sta_info));
- if (sta == NULL) {
- printf(" malloc failed\n");
- return NULL;
- }
- memset(sta, 0, sizeof(struct sta_info));
- sta->radius_identifier = -1;
- sta->acct_session_id_lo = hapd->radius->acct_session_id_lo++;
-
- /* initialize STA info data */
- eloop_register_timeout(AP_MAX_INACTIVITY, 0, ap_handle_timer,
- hapd, sta);
- memcpy(sta->addr, addr, ETH_ALEN);
- sta->next = hapd->sta_list;
- hapd->sta_list = sta;
- hapd->num_sta++;
- ap_sta_hash_add(hapd, sta);
- return sta;
-}
-
-
static u16 auth_shared_key(hostapd *hapd, struct sta_info *sta,
u16 auth_transaction, u8 *challenge, int iswep)
{
@@ -471,7 +524,7 @@
return;
}
- sta = auth_get_sta(hapd, mgmt->sa);
+ sta = auth_get_sta(hapd, mgmt->sa, NULL);
if (!sta) {
resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
goto fail;
@@ -1046,3 +1099,4 @@
break;
}
}
+#endif
Index: hostapd/ieee802_11.h
===================================================================
RCS file: /u/cvs/SNOWNET/Snownet/hostap/hostapd/ieee802_11.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- hostapd/ieee802_11.h 17 Jun 2003 19:01:21 -0000 1.1.1.1
+++ hostapd/ieee802_11.h 17 Jun 2003 19:04:19 -0000 1.2
@@ -85,6 +85,9 @@
int ok);
ParseRes ieee802_11_parse_elems(hostapd *hapd, u8 *start, size_t len,
struct ieee802_11_elems *elems);
+#ifdef __OpenBSD__
+struct sta_info * ieee802_11_locate_sta(hostapd *hapd, u8 *addr);
+#endif
#endif /* IEEE802_11_H */
Index: hostapd/ieee802_11_auth.c
===================================================================
RCS file: /u/cvs/SNOWNET/Snownet/hostap/hostapd/ieee802_11_auth.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- hostapd/ieee802_11_auth.c 17 Jun 2003 19:01:21 -0000 1.1.1.1
+++ hostapd/ieee802_11_auth.c 17 Jun 2003 19:04:19 -0000 1.2
@@ -13,9 +13,10 @@
#include <stdio.h>
#include <string.h>
#include <time.h>
-#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
#include "hostapd.h"
#include "ieee802_11.h"
Index: hostapd/ieee802_1x.c
===================================================================
RCS file: /u/cvs/SNOWNET/Snownet/hostap/hostapd/ieee802_1x.c,v
retrieving revision 1.1.1.1
retrieving revision 1.5
diff -u -r1.1.1.1 -r1.5
--- hostapd/ieee802_1x.c 17 Jun 2003 19:01:21 -0000 1.1.1.1
+++ hostapd/ieee802_1x.c 24 Jun 2003 13:06:47 -0000 1.5
@@ -12,6 +12,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
+#include <sys/types.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/ioctl.h>
@@ -20,7 +21,12 @@
#include <time.h>
#include <sys/time.h>
#include <sys/socket.h>
-
+#ifdef __OpenBSD__
+#include <net/if.h>
+#include <net/bpf.h>
+#include <netinet/if_ether.h>
+#include <dev/ic/if_wi_ieee.h>
+#endif
#include "hostapd.h"
#include "ieee802_1x.h"
@@ -35,6 +41,84 @@
#include "driver.h"
+#ifdef __OpenBSD__
+void ieee802_1x_set_sta_authorized(hostapd *hapd, struct sta_info *sta,
+ int authorized)
+{
+ if (authorized) {
+ sta->flags |= WLAN_STA_AUTHORIZED;
+ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
+ HOSTAPD_LEVEL_DEBUG, "authorizing port");
+ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
+ HOSTAPD_LEVEL_DEBUG, "authorizing port");
+ accounting_sta_start(hapd, sta);
+ hostapd_set_sta_authorized(hapd, sta);
+ } else {
+ sta->flags &= ~WLAN_STA_AUTHORIZED;
+ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
+ HOSTAPD_LEVEL_DEBUG, "unauthorizing port");
+ remove_sta(hapd, sta);
+ }
+}
+
+
+static void ieee802_1x_send(hostapd *hapd, struct sta_info *sta, u8 type,
+ u8 *data, size_t datalen)
+{
+ char *buf;
+ struct ether_header *hdr;
+ struct ieee802_1x_hdr *xhdr;
+ struct bpf_sendtagged bs;
+ struct wi_tag_change_tx_key *tag;
+ size_t len;
+
+ len = sizeof(*hdr) + 2 + sizeof(*xhdr) + datalen;
+ buf = (char *) malloc(len);
+ if (buf == NULL) {
+ printf("malloc() failed for ieee802_1x_send(len=%d)\n", len);
+ return;
+ }
+
+ memset(buf, 0, len);
+
+ hdr = (struct ether_header *) buf;
+#if 0
+ /* TODO:
+ * According to IEEE 802.1aa/D4 EAPOL-Key should be sent before any
+ * remaining EAP frames, if possible. This would allow rest of the
+ * frames to be encrypted. This code could be used to request
+ * encryption from the kernel driver. */
+ if (sta->eapol_sm &&
+ sta->eapol_sm->be_auth.state == BE_AUTH_SUCCESS &&
+ sta->eapol_sm->keyTxEnabled)
+ send using a key;
+#endif
+ memcpy(hdr->ether_dhost, sta->addr, ETH_ALEN);
+ memcpy(hdr->ether_shost, hapd->own_addr, ETH_ALEN);
+ hdr->ether_type = htons(ETH_P_PAE);
+
+ xhdr = (struct ieee802_1x_hdr *)(hdr + 1);
+ xhdr->version = EAPOL_VERSION;
+ xhdr->type = type;
+ xhdr->length = htons(datalen);
+
+ if (datalen > 0 && data != NULL)
+ memcpy(xhdr + 1, data, datalen);
+
+ bs.bs_buf = buf;
+ bs.bs_bufbytes = len;
+ tag = (struct wi_tag_change_tx_key *)bs.bs_tag;
+ bs.bs_tagbytes = sizeof(*tag);
+ tag->type = WI_TAG_CHANGE_TX_KEY; /* use alternate WEP: */
+ tag->change_tx_key = 255; /* no key */
+ if (ioctl(hapd->sock, BIOCSTAGGED, &bs) == -1) {
+ perror("ieee802_1x_send: BIOCSTAGGED");
+ printf("ieee802_1x_send - packet len: %d - failed\n", len);
+ }
+
+ free(buf);
+}
+#else
static void ieee802_1x_send(hostapd *hapd, struct sta_info *sta, u8 type,
u8 *data, size_t datalen)
{
@@ -102,28 +186,28 @@
void ieee802_1x_set_sta_authorized(hostapd *hapd, struct sta_info *sta,
int authorized)
{
- struct prism2_hostapd_param param;
-
- memset(¶m, 0, sizeof(param));
- param.cmd = PRISM2_HOSTAPD_SET_FLAGS_STA;
- memcpy(param.sta_addr, sta->addr, ETH_ALEN);
if (authorized) {
+ struct prism2_hostapd_param param;
+
+ memset(¶m, 0, sizeof(param));
+ param.cmd = PRISM2_HOSTAPD_SET_FLAGS_STA;
+ memcpy(param.sta_addr, sta->addr, ETH_ALEN);
sta->flags |= WLAN_STA_AUTHORIZED;
param.u.set_flags_sta.flags_or = WLAN_STA_AUTHORIZED;
param.u.set_flags_sta.flags_and = ~0;
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
HOSTAPD_LEVEL_DEBUG, "authorizing port");
accounting_sta_start(hapd, sta);
+ if (hostapd_ioctl(hapd, ¶m, sizeof(param)))
+ printf("Could not set station flags for kernel driver.\n");
} else {
sta->flags &= ~WLAN_STA_AUTHORIZED;
- param.u.set_flags_sta.flags_and = ~WLAN_STA_AUTHORIZED;
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
HOSTAPD_LEVEL_DEBUG, "unauthorizing port");
+ remove_sta(hapd, sta);
}
-
- if (hostapd_ioctl(hapd, ¶m, sizeof(param)))
- printf("Could not set station flags for kernel driver.\n");
}
+#endif
void ieee802_1x_request_identity(hostapd *hapd, struct sta_info *sta, u8 id)
@@ -264,6 +348,7 @@
key->key_index |= BIT(7);
}
+ /* XXX iterate over all sta here */
/* Key is encrypted using "Key-IV + sta->eapol_key_crypt" as the
* RC4-key */
memcpy((u8 *) (key + 1), key_data, key_len);
@@ -307,6 +392,10 @@
"IEEE 802.1X: Sending EAPOL-Key(s) to " MACSTR
" (identifier %d)\n", MAC2STR(sta->addr), id);
+ if (hapd->default_wep_key_2)
+ ieee802_1x_tx_key_one(hapd, sta, hapd->default_wep_key_idx_2, 1,
+ hapd->default_wep_key_2,
+ hapd->conf->default_wep_key_len);
if (hapd->default_wep_key)
ieee802_1x_tx_key_one(hapd, sta, hapd->default_wep_key_idx, 1,
hapd->default_wep_key,
@@ -1090,6 +1179,7 @@
static int ieee802_1x_init_kernel_1x(hostapd *hapd)
{
+#ifndef __OpenBSD__
/* enable kernel driver support for IEEE 802.1X */
if (hostap_ioctl_prism2param(hapd, PRISM2_PARAM_IEEE_802_1X, 1)) {
printf("Could not setup IEEE 802.1X support in kernel driver."
@@ -1105,6 +1195,7 @@
"driver.\n");
return -1;
}
+#endif
return 0;
}
Index: hostapd/md5.c
===================================================================
RCS file: /u/cvs/SNOWNET/Snownet/hostap/hostapd/md5.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- hostapd/md5.c 17 Jun 2003 19:01:21 -0000 1.1.1.1
+++ hostapd/md5.c 17 Jun 2003 19:04:19 -0000 1.2
@@ -12,9 +12,11 @@
#include <assert.h>
#include <string.h>
+#ifndef __OpenBSD__
#include <endian.h>
#if __BYTE_ORDER == __BIG_ENDIAN
#define WORDS_BIGENDIAN
+#endif
#endif
#include "common.h"
Index: hostapd/receive.c
===================================================================
RCS file: /u/cvs/SNOWNET/Snownet/hostap/hostapd/receive.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- hostapd/receive.c 17 Jun 2003 19:01:21 -0000 1.1.1.1
+++ hostapd/receive.c 17 Jun 2003 19:04:19 -0000 1.2
@@ -16,7 +16,17 @@
#include <sys/socket.h>
#include <sys/ioctl.h>
-#ifdef USE_KERNEL_HEADERS
+#if defined(__OpenBSD__)
+#include <pcap.h>
+#include <fcntl.h>
+#include <net/bpf.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <ifaddrs.h>
+#include <net/if_dl.h>
+#include <netinet/if_ether.h>
+#include <net/if_types.h>
+#elif defined(USE_KERNEL_HEADERS)
#include <asm/types.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h> /* The L2 protocols */
@@ -37,6 +47,78 @@
#include "driver.h"
+#ifdef __OpenBSD__
+static void handle_read_packet(u_char *hapdp, const struct pcap_pkthdr *hdr,
+ const u_char *constbuf)
+{
+ hostapd *hapd;
+ struct sta_info *sta;
+ struct ether_header *eh;
+ u8 *sa, buf[/* XXX */ 3000];
+ size_t len;
+
+ hapd = (hostapd *)hapdp;
+ len = hdr->caplen;
+ eh = (struct ether_header *)buf;
+
+ if (len > sizeof(buf)) {
+ printf("Packet size should not be this large!\n");
+ return;
+ }
+ memcpy(buf, constbuf, len);
+ HOSTAPD_DEBUG(HOSTAPD_DEBUG_VERBOSE,
+ "Received %d bytes ethernet frame\n", len);
+ if (HOSTAPD_DEBUG_COND(HOSTAPD_DEBUG_MSGDUMPS)) {
+ int i;
+ printf(" dump:");
+ for (i = 0; i < len; i++)
+ printf(" %02x", buf[i]);
+ printf("\n");
+ }
+
+ sa = eh->ether_shost;
+ /*
+ * For OpenBSD, we merely act as an 802.1x authenticator and
+ * not a full 802.11 AP daemon. Because of this, there's no
+ * reason to consider a station as anything but nonexistant
+ * until its supplicant's authorization begins.
+ */
+ sta = ieee802_11_locate_sta(hapd, sa);
+ if (!sta || !(sta->flags & WLAN_STA_ASSOC)) {
+ printf("Data frame from not associated STA " MACSTR "\n",
+ MAC2STR(sa));
+ return;
+ }
+ switch (ntohs(eh->ether_type)) {
+ case ETH_P_PAE:
+ if (hapd->conf->ieee802_1x)
+ ieee802_1x_receive(hapd, sa, buf + sizeof(*eh),
+ len - sizeof(*eh));
+ else
+ printf("IEEE 802.1X is not configured to be used - "
+ "dropping packet\n");
+ break;
+
+ default:
+ printf("Unknown ethertype 0x%04x in data frame\n",
+ ntohs(eh->ether_type));
+ break;
+ }
+}
+
+void handle_read(int sock, void *eloop_ctx, void *sock_ctx)
+{
+ hostapd *hapd = (hostapd *) eloop_ctx;
+
+ HOSTAPD_DEBUG(HOSTAPD_DEBUG_VERBOSE,
+ "Data received on %s.\n", hapd->conf->iface);
+ if (pcap_dispatch(hapd->pcap, -1, handle_read_packet,
+ (u_char *)hapd) == -1)
+ pcap_perror(hapd->pcap, "reading packet");
+}
+
+#else
+
static void handle_data(hostapd *hapd, char *buf, size_t len, u16 stype)
{
struct ieee80211_hdr *hdr;
@@ -233,24 +315,106 @@
handle_frame(hapd, buf, len);
}
+#endif
int hostapd_init_sockets(hostapd *hapd)
{
+#ifdef __OpenBSD__
+ char pcap_errbuf[PCAP_ERRBUF_SIZE];
+ struct bpf_program program;
+ struct sockaddr_dl *sdl;
+ struct ifaddrs *ifa, *ifalist;
+ char *strprogram;
+#else
struct ifreq ifr;
struct sockaddr_ll addr;
+#endif
+#ifdef __OpenBSD__
+ if (getifaddrs(&ifalist) == -1) {
+ perror("getifaddrs");
+ return -1;
+ }
+ for (ifa = ifalist; ifa != NULL; ifa = ifa->ifa_next) {
+ if (strcmp(ifa->ifa_name, hapd->conf->iface) == 0 &&
+ ifa->ifa_addr->sa_family == AF_LINK)
+ break;
+ }
+ if (ifa == NULL) {
+ freeifaddrs(ifalist);
+ printf("No link-level interfaces found for %s.",
+ hapd->conf->iface);
+ return -1;
+ }
+ sdl = (struct sockaddr_dl *)ifa->ifa_addr;
+ if (sdl->sdl_type != IFT_ETHER || sdl->sdl_alen != ETH_ALEN) {
+ freeifaddrs(ifalist);
+ printf("getifaddrs() returned wrong address type\n");
+ return -1;
+ }
+ memcpy(hapd->own_addr, LLADDR(sdl), ETH_ALEN);
+ freeifaddrs(ifalist);
+ if (hostapd_set_iface_flags(hapd, 1) == -1) {
+ perror("Failed to set interface 'up'.\n");
+ return -1;
+ }
+ hapd->pcap = pcap_open_live(hapd->conf->iface, /* XXX */ 3000, 0, 0,
+ pcap_errbuf);
+ if (hapd->pcap == NULL) {
+ printf("%s: %s\n", hapd->conf->iface, pcap_errbuf);
+ return -1;
+ }
+ hapd->sock = pcap_fileno(hapd->pcap);
+ if (pcap_datalink(hapd->pcap) != DLT_EN10MB) {
+ printf("pcap_datalink(%s) is not ether\n", hapd->conf->iface);
+ return -1;
+ }
+#if 0
+ if ((fdflags = fcntl(hapd->sock, F_GETFL, 0)) == -1 ||
+ fcntl(hapd->sock, F_SETFL, fdflags | O_NONBLOCK) == -1) {
+ perror("setting non-blocking on pcap descriptor");
+ return -1;
+ }
+#endif
+ if (asprintf(&strprogram, "ether dst " MACSTR " and ether proto %#x",
+ MAC2STR(hapd->own_addr), ETH_P_PAE) == -1) {
+ perror("asprintf");
+ return -1;
+ }
+ if (pcap_compile(hapd->pcap, &program, strprogram, 1, 0) == -1) {
+ free(strprogram);
+ perror("creating filter");
+ return -1;
+ }
+ HOSTAPD_DEBUG(HOSTAPD_DEBUG_VERBOSE,
+ "Setting bpf program '%s' on %s.\n", strprogram,
+ hapd->conf->iface);
+ free(strprogram);
+ if (pcap_setfilter(hapd->pcap, &program) == -1) {
+ pcap_freecode(&program);
+ perror("setting filter");
+ return -1;
+ }
+ pcap_freecode(&program);
+#else
hapd->sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (hapd->sock < 0) {
perror("socket[PF_PACKET,SOCK_RAW]");
return -1;
}
+#endif
if (eloop_register_read_sock(hapd->sock, handle_read, hapd, NULL)) {
printf("Could not register read socket\n");
return -1;
}
+ if (hostapd_set_iface_flags(hapd, 1)) {
+ return -1;
+ }
+
+#ifndef __OpenBSD__
memset(&ifr, 0, sizeof(ifr));
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%sap",
hapd->conf->iface);
@@ -259,10 +423,6 @@
return -1;
}
- if (hostapd_set_iface_flags(hapd, 1)) {
- return -1;
- }
-
memset(&addr, 0, sizeof(addr));
addr.sll_family = AF_PACKET;
addr.sll_ifindex = ifr.ifr_ifindex;
@@ -288,6 +448,7 @@
return -1;
}
memcpy(hapd->own_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
+#endif
return 0;
}
Index: hostapd/sta_info.c
===================================================================
RCS file: /u/cvs/SNOWNET/Snownet/hostap/hostapd/sta_info.c,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -u -r1.1.1.1 -r1.3
--- hostapd/sta_info.c 17 Jun 2003 19:01:21 -0000 1.1.1.1
+++ hostapd/sta_info.c 23 Jun 2003 21:43:26 -0000 1.3
@@ -105,16 +105,10 @@
void ap_free_sta(hostapd *hapd, struct sta_info *sta)
{
- struct prism2_hostapd_param param;
-
accounting_sta_stop(hapd, sta);
- memset(¶m, 0, sizeof(param));
- param.cmd = PRISM2_HOSTAPD_REMOVE_STA;
- memcpy(param.sta_addr, sta->addr, ETH_ALEN);
- if (hostapd_ioctl(hapd, ¶m, sizeof(param))) {
- printf("Could not remove station from kernel driver.\n");
- }
+ sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
+ remove_sta(hapd, sta);
ap_sta_hash_del(hapd, sta);
ap_sta_list_del(hapd, sta);
@@ -151,6 +145,47 @@
}
+#ifdef __OpenBSD__
+/*
+ * Trust kernel's HostAP to do any timeouts. We'll simply act on those
+ * timeouts when they occur.
+ */
+void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
+{
+ hostapd *hapd = eloop_ctx;
+ struct sta_info *sta = timeout_ctx;
+ int flags;
+
+ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
+ "Checking STA " MACSTR " inactivity: ",
+ MAC2STR(sta->addr));
+ flags = hostapd_read_sta_driver_flags(hapd, sta->addr);
+ if (flags != -1 && !(flags & WLAN_STA_ASSOC)) {
+ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
+ "disassociated due to inactivity\n");
+ if (sta->timeout_next != STA_DEAUTH) {
+ sta->flags &= ~WLAN_STA_ASSOC;
+ ieee802_1x_set_port_enabled(hapd, sta, 0);
+ sta->timeout_next = STA_DEAUTH;
+ eloop_register_timeout(AP_MAX_INACTIVITY, 0,
+ ap_handle_timer, hapd, sta);
+ }
+ } else if (flags == -1 || !(flags & WLAN_STA_AUTH)) {
+ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
+ "deauthenticated due to inactivity\n");
+ if (!sta->acct_terminate_cause)
+ sta->acct_terminate_cause =
+ RADIUS_ACCT_TERMINATE_CAUSE_IDLE_TIMEOUT;
+ ap_free_sta(hapd, sta);
+ } else {
+ HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
+ "currently active\n");
+ sta->timeout_next = STA_NULLFUNC;
+ eloop_register_timeout(AP_MAX_INACTIVITY, 0, ap_handle_timer,
+ hapd, sta);
+ }
+}
+#else
void ap_handle_timer(void *eloop_ctx, void *timeout_ctx)
{
hostapd *hapd = eloop_ctx;
@@ -267,6 +302,7 @@
break;
}
}
+#endif
void ap_handle_session_timer(void *eloop_ctx, void *timeout_ctx)
-------------- next part --------------
Index: sys/sys/mbuf.h
===================================================================
RCS file: /u/cvs/SNOWNET/Soekris/OpenBSD-src/sys/sys/mbuf.h,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -u -r1.1.1.1 -r1.3
--- sys/sys/mbuf.h 3 Jul 2002 21:19:08 -0000 1.1.1.1
+++ sys/sys/mbuf.h 24 Jun 2003 13:12:56 -0000 1.3
@@ -597,6 +597,7 @@
#define PACKET_TAG_PF_GENERATED 11 /* PF generated, pass always */
#define PACKET_TAG_PF_ROUTED 12 /* PF routed, no route loops */
#define PACKET_TAG_PF_FRAGCACHE 13 /* PF fragment cached */
+#define PACKET_TAG_DRIVER_SPECIFIC 16 /* NIC specified format */
#ifdef MBTYPES
int mbtypes[] = { /* XXX */
Index: sys/net/bpf.c
===================================================================
RCS file: /u/cvs/SNOWNET/Soekris/OpenBSD-src/sys/net/bpf.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- sys/net/bpf.c 6 Jun 2002 21:34:16 -0000 1.1.1.1
+++ sys/net/bpf.c 5 Jun 2003 13:17:04 -0000 1.2
@@ -93,6 +93,7 @@
void bpf_catchpacket(struct bpf_d *, u_char *, size_t, size_t,
void (*)(const void *, void *, size_t));
void bpf_reset_d(struct bpf_d *);
+static int bpf_write(dev_t, struct uio *, int, struct m_tag *);
void filt_bpfrdetach(struct knote *);
int filt_bpfread(struct knote *, long);
@@ -489,14 +490,28 @@
struct uio *uio;
int ioflag;
{
+
+ return (bpf_write(dev, uio, ioflag, NULL));
+}
+
+static int
+bpf_write(dev, uio, ioflag, devtag)
+ dev_t dev;
+ struct uio *uio;
+ int ioflag;
+ struct m_tag *devtag;
+{
register struct bpf_d *d = &bpf_dtab[minor(dev)];
struct ifnet *ifp;
struct mbuf *m;
int error, s;
struct sockaddr dst;
- if (d->bd_bif == 0)
+ if (d->bd_bif == 0) {
+ if (devtag != NULL)
+ m_tag_free(devtag);
return (ENXIO);
+ }
ifp = d->bd_bif->bif_ifp;
@@ -504,8 +519,13 @@
return (0);
error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, &m, &dst);
- if (error)
+ if (error) {
+ if (devtag != NULL)
+ m_tag_free(devtag);
return (error);
+ }
+ if (devtag != NULL)
+ m_tag_prepend(m, devtag);
if (m->m_pkthdr.len > ifp->if_mtu) {
m_freem(m);
@@ -559,6 +579,7 @@
* BIOCVERSION Get filter language version.
* BIOCGHDRCMPLT Get "header already complete" flag
* BIOCSHDRCMPLT Set "header already complete" flag
+ * BIOCSTAGGED Send a packet with a device-specific m_tag.
*/
/* ARGSUSED */
int
@@ -788,6 +809,35 @@
}
case BIOCGRSIG:
*(u_int *)addr = d->bd_sig;
+ break;
+ case BIOCSTAGGED: /* Send a packet, with a user tag */
+ {
+ struct uio uio;
+ struct iovec iov;
+ struct bpf_sendtagged *bs;
+ struct m_tag *mt;
+
+ bs = (struct bpf_sendtagged *)addr;
+ if (bs->bs_tagbytes > BPF_MAXTAGSIZE)
+ return (EINVAL);
+ if (bs->bs_bufbytes == 0)
+ return (0);
+ mt = m_tag_get(PACKET_TAG_DRIVER_SPECIFIC,
+ bs->bs_tagbytes, M_WAIT);
+ if (mt == NULL)
+ return (ENOMEM);
+ bcopy(bs->bs_tag, (char *)&mt[1], bs->bs_tagbytes);
+ iov.iov_base = (char *)bs->bs_buf;
+ iov.iov_len = bs->bs_bufbytes;
+ uio.uio_iov = &iov;
+ uio.uio_iovcnt = 1;
+ uio.uio_resid = iov.iov_len;
+ uio.uio_rw = UIO_WRITE;
+ uio.uio_segflg = UIO_USERSPACE;
+ uio.uio_procp = p;
+
+ return (bpf_write(dev, &uio, 0, mt));
+ }
break;
}
return (error);
Index: sys/net/bpf.h
===================================================================
RCS file: /u/cvs/SNOWNET/Soekris/OpenBSD-src/sys/net/bpf.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 bpf.h
--- sys/net/bpf.h 14 Mar 2002 01:27:09 -0000 1.1.1.1
+++ sys/net/bpf.h 24 Jun 2003 13:14:28 -0000
@@ -60,6 +60,18 @@
#define BPF_MAXBUFSIZE 0x80000
#define BPF_MINBUFSIZE 32
+#define BPF_MAXTAGSIZE 256
+
+/*
+ * Structure for BIOCSTAGGED.
+ */
+struct bpf_sendtagged {
+ const void *bs_buf;
+ size_t bs_bufbytes;
+ size_t bs_tagbytes;
+ u_char bs_tag[BPF_MAXTAGSIZE];
+};
+
/*
* Structure for BIOCSETF.
*/
@@ -115,6 +127,7 @@
#define BIOCGRSIG _IOR('B',115, u_int)
#define BIOCGHDRCMPLT _IOR('B',116, u_int)
#define BIOCSHDRCMPLT _IOW('B',117, u_int)
+#define BIOCSTAGGED _IOW('B',118, struct bpf_sendtagged)
struct bpf_timeval {
u_int32_t tv_sec;
@@ -170,6 +183,8 @@
#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */
#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */
#define DLT_PFLOG 17 /* Packet filter logging */
+#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */
+#define DLT_PRISM_HEADER 119 /* Prism II monitoring + 802.11 */
/*
* The instruction encodings.
Index: sys/dev/ic/if_wi.c
===================================================================
RCS file: /u/cvs/SNOWNET/Soekris/OpenBSD-src/sys/dev/ic/if_wi.c,v
retrieving revision 1.1.1.1
retrieving revision 1.15
diff -u -r1.1.1.1 -r1.15
--- sys/dev/ic/if_wi.c 30 Aug 2002 08:19:49 -0000 1.1.1.1
+++ sys/dev/ic/if_wi.c 24 Jun 2003 12:25:34 -0000 1.15
@@ -91,6 +91,7 @@
#if NBPFILTER > 0
#include <net/bpf.h>
+#include <net/bpfdesc.h>
#endif
#include <machine/bus.h>
@@ -121,6 +122,11 @@
#else /* !WIDEBUG */
#define DPRINTF(mask,args)
#endif /* WIDEBUG */
+#define wi_init_keep_hostap(sc) do { \
+ (sc)->wi_flags |= WI_FLAGS_KEEP_HOSTAP_UP; \
+ wi_init(sc); \
+ (sc)->wi_flags &= ~WI_FLAGS_KEEP_HOSTAP_UP; \
+} while (0)
#if !defined(lint) && !defined(__OpenBSD__)
static const char rcsid[] =
@@ -140,6 +146,9 @@
STATIC void wi_txeof(struct wi_softc *, int);
STATIC void wi_update_stats(struct wi_softc *);
STATIC void wi_setmulti(struct wi_softc *);
+#if NBPFILTER > 0
+STATIC void wi_reset_bpf_linktype(struct wi_softc *);
+#endif
STATIC int wi_cmd(struct wi_softc *, int, int, int, int);
STATIC int wi_read_record(struct wi_softc *, struct wi_ltv_gen *);
@@ -427,6 +436,7 @@
if (status & WI_EV_ALLOC) {
int id;
id = CSR_READ_2(sc, WI_ALLOC_FID);
+
CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
if (id == sc->wi_tx_data_id)
wi_txeof(sc, status);
@@ -455,24 +465,56 @@
return (1);
}
+#if NBPFILTER > 0
+/* Already called at splimp(). */
+STATIC void
+wi_reset_bpf_linktype(struct wi_softc *sc)
+{
+ struct bpf_d *d;
+ struct bpf_if *ifb;
+ extern struct bpf_if *bpf_iflist;
+ struct ifnet *ifp;
+ u_int dlt;
+
+ if (sc->wi_prism2hdr)
+ dlt = DLT_PRISM_HEADER;
+ else if (sc->wi_debug.wi_monitor || sc->wi_procframe)
+ dlt = DLT_IEEE802_11;
+ else
+ dlt = DLT_EN10MB;
+ ifp = &sc->sc_arpcom.ac_if;
+ for (ifb = bpf_iflist; ifb != NULL; ifb = ifb->bif_next)
+ if (ifb->bif_ifp == ifp)
+ break;
+ if (ifb == NULL)
+ return;
+ ifb->bif_dlt = dlt;
+ for (d = ifb->bif_dlist; d != NULL; d = d->bd_next)
+ d->bd_bif->bif_dlt = dlt;
+}
+#endif
+
STATIC void
wi_rxeof(sc)
struct wi_softc *sc;
{
+ struct wi_frame rx_frame;
struct ifnet *ifp;
struct ether_header *eh;
struct mbuf *m;
u_int16_t msg_type;
- int id;
+ int id, dontbpf = 0, unauth = 0;
ifp = &sc->sc_arpcom.ac_if;
id = CSR_READ_2(sc, WI_RX_FID);
- if (sc->wi_procframe || sc->wi_debug.wi_monitor) {
+ if (sc->wi_procframe || sc->wi_debug.wi_monitor ||
+ sc->wi_prism2hdr) {
struct wi_frame *rx_frame;
- int datlen, hdrlen;
+ int datlen, hdrlen, isdata = 0;
+ dontbpf = 1;
MGETHDR(m, M_DONTWAIT, MT_DATA);
if (m == NULL) {
ifp->if_ierrors++;
@@ -484,6 +526,9 @@
ifp->if_ierrors++;
return;
}
+ /* To possibly M_PREPEND() with later. */
+ m->m_data += sizeof(struct prism2_header);
+ m->m_len -= sizeof(struct prism2_header);
m->m_pkthdr.rcvif = ifp;
@@ -510,6 +555,7 @@
case WI_FTYPE_DATA:
hdrlen = WI_DATA_HDRLEN;
datlen = letoh16(rx_frame->wi_dat_len);
+ isdata = 1;
break;
case WI_FTYPE_MGMT:
hdrlen = WI_MGMT_HDRLEN;
@@ -530,6 +576,7 @@
case 0:
hdrlen = WI_DATA_HDRLEN;
datlen = letoh16(rx_frame->wi_dat_len);
+ isdata = 1;
break;
default:
printf(WI_PRT_FMT ": received packet on invalid port "
@@ -540,7 +587,8 @@
return;
}
- if ((hdrlen + datlen + 2) > MCLBYTES) {
+ if ((hdrlen + datlen + 2 + sizeof(struct prism2_header)) >
+ MCLBYTES) {
m_freem(m);
ifp->if_ierrors++;
return;
@@ -553,166 +601,251 @@
return;
}
- m->m_pkthdr.len = m->m_len = hdrlen + datlen;
- } else {
- struct wi_frame rx_frame;
+ /*
+ * Remove the non-802.11 section of the packet that nothing
+ * really knows how to deal with if we're requested to
+ * just return the frames.
+ */
+ if (sc->wi_procframe || sc->wi_debug.wi_monitor ||
+ sc->wi_prism2hdr) {
+ const size_t begin_80211 =
+ offsetof(struct wi_frame, wi_frame_ctl);
+ const size_t begin_data =
+#ifdef include_802_3
+ offsetof(struct wi_frame, wi_dst_addr);
+#else
+ offsetof(struct wi_frame, wi_dat);
+#endif
+ size_t end_80211;
+ caddr_t data;
- /* First read in the frame header */
- if (wi_read_data(sc, id, 0, (caddr_t)&rx_frame,
- sizeof(rx_frame))) {
- ifp->if_ierrors++;
- return;
+ /* from and to DS both being set means + addr4 */
+ if ((~letoh16(rx_frame->wi_frame_ctl) &
+ (WI_FCTL_TODS | WI_FCTL_FROMDS)) == 0)
+ end_80211 = offsetof(struct wi_frame,
+ wi_dat_len);
+ else
+ end_80211 = offsetof(struct wi_frame,
+ wi_addr4);
+#ifdef questionable
+ /* Turn off the WEP bit if we know we decoded it. */
+ if (?)
+ rx_frame->wi_frame_ctl &= ~htole16(WI_FCTL_WEP);
+#endif
+ /* chop off everything before the 802.11 header */
+ data = mtod(m, caddr_t);
+ bcopy(data + begin_80211, data,
+ end_80211 - begin_80211);
+ if (datlen > 0) {
+ /*
+ * Slide down (ETHER/LLC)+DATA or MGMT+DATA.
+ */
+ bcopy(data + begin_data,
+ data + end_80211 - begin_80211, datlen);
+ m->m_pkthdr.len = m->m_len = datlen
+ - begin_80211 + end_80211;
+ } else {
+ m->m_pkthdr.len = m->m_len =
+ hdrlen - begin_80211;
+ }
+ if (sc->wi_prism2hdr) {
+ struct prism2_header *p2;
+ struct timeval tv;
+
+ /* We have the space we need already. */
+ M_PREPEND(m, sizeof(*p2), M_DONTWAIT);
+ p2 = mtod(m, struct prism2_header *);
+ p2->version = htonl(PRISM2_HEADER_VERSION);
+ p2->length = htonl(sizeof(*p2));
+ p2->mac_time =
+ htobe64(letoh32((rx_frame->wi_time0 << 16)
+ + rx_frame->wi_time1));
+ microtime(&tv);
+ p2->host_time =
+ htobe64((u_int64_t)tv.tv_sec * 1000000 +
+ tv.tv_usec);
+ p2->phy_type = htonl(4); /* DSSS 802.11b */
+ p2->channel = htonl(sc->wi_channel);
+ p2->data_rate = htonl(rx_frame->wi_rx_rate);
+ p2->antenna = htonl(0);
+ p2->priority = htonl(0);
+ p2->ssi_type = htonl(3); /* Raw RSSI */
+ p2->ssi_signal =
+ htonl((letoh16(rx_frame->wi_q_info)
+ & 0xff00) >> 8);
+ p2->ssi_noise =
+ htonl(letoh16(rx_frame->wi_q_info) & 0xff);
+ p2->preamble = htonl(0);
+ p2->encoding = htonl(1); /* CCK */
+ }
}
-
- /* Drop undecryptable or packets with receive errors here */
- if (rx_frame.wi_status & htole16(WI_STAT_ERRSTAT)) {
- ifp->if_ierrors++;
+#if NBPFILTER > 0
+ /* Handle BPF listeners. */
+ if (ifp->if_bpf)
+ BPF_MTAP(ifp, m);
+#endif
+ m_freem(m);
+ if (!isdata)
return;
- }
+ }
- /* Stash message type in host byte order for later use */
- msg_type = letoh16(rx_frame.wi_status) & WI_RXSTAT_MSG_TYPE;
+ /* First read in the frame header */
+ if (wi_read_data(sc, id, 0, (caddr_t)&rx_frame,
+ sizeof(rx_frame))) {
+ ifp->if_ierrors++;
+ return;
+ }
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL) {
- ifp->if_ierrors++;
+ /* Drop undecryptable or packets with receive errors here */
+ if (rx_frame.wi_status & htole16(WI_STAT_ERRSTAT)) {
+ ifp->if_ierrors++;
+ return;
+ }
+
+ /* Stash message type in host byte order for later use */
+ msg_type = letoh16(rx_frame.wi_status) & WI_RXSTAT_MSG_TYPE;
+
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
+ if (m == NULL) {
+ ifp->if_ierrors++;
+ return;
+ }
+ MCLGET(m, M_DONTWAIT);
+ if (!(m->m_flags & M_EXT)) {
+ m_freem(m);
+ ifp->if_ierrors++;
+ return;
+ }
+
+ /* Align the data after the ethernet header */
+ m->m_data = (caddr_t)ALIGN(m->m_data +
+ sizeof(struct ether_header)) - sizeof(struct ether_header);
+
+ eh = mtod(m, struct ether_header *);
+ m->m_pkthdr.rcvif = ifp;
+
+ if (msg_type == WI_STAT_MGMT &&
+ sc->wi_ptype == WI_PORTTYPE_HOSTAP) {
+
+ u_int16_t rxlen = letoh16(rx_frame.wi_dat_len);
+
+ if ((WI_802_11_OFFSET_RAW + rxlen + 2) > MCLBYTES) {
+ printf("%s: oversized mgmt packet received in "
+ "hostap mode (wi_dat_len=%d, "
+ "wi_status=0x%x)\n", sc->sc_dev.dv_xname,
+ rxlen, letoh16(rx_frame.wi_status));
+ m_freem(m);
+ ifp->if_ierrors++;
return;
}
- MCLGET(m, M_DONTWAIT);
- if (!(m->m_flags & M_EXT)) {
+
+ /* Put the whole header in there. */
+ bcopy(&rx_frame, mtod(m, void *),
+ sizeof(struct wi_frame));
+ if (wi_read_data(sc, id, WI_802_11_OFFSET_RAW,
+ mtod(m, caddr_t) + WI_802_11_OFFSET_RAW,
+ rxlen + 2)) {
m_freem(m);
+ if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
+ printf("wihap: failed to copy header\n");
ifp->if_ierrors++;
return;
}
- /* Align the data after the ethernet header */
- m->m_data = (caddr_t)ALIGN(m->m_data +
- sizeof(struct ether_header)) - sizeof(struct ether_header);
-
- eh = mtod(m, struct ether_header *);
- m->m_pkthdr.rcvif = ifp;
-
- if (msg_type == WI_STAT_MGMT &&
- sc->wi_ptype == WI_PORTTYPE_HOSTAP) {
+ m->m_pkthdr.len = m->m_len =
+ WI_802_11_OFFSET_RAW + rxlen;
- u_int16_t rxlen = letoh16(rx_frame.wi_dat_len);
+ /* XXX: consider giving packet to bhp? */
- if ((WI_802_11_OFFSET_RAW + rxlen + 2) > MCLBYTES) {
- printf("%s: oversized mgmt packet received in "
- "hostap mode (wi_dat_len=%d, "
- "wi_status=0x%x)\n", sc->sc_dev.dv_xname,
- rxlen, letoh16(rx_frame.wi_status));
- m_freem(m);
- ifp->if_ierrors++;
- return;
- }
-
- /* Put the whole header in there. */
- bcopy(&rx_frame, mtod(m, void *),
- sizeof(struct wi_frame));
- if (wi_read_data(sc, id, WI_802_11_OFFSET_RAW,
- mtod(m, caddr_t) + WI_802_11_OFFSET_RAW,
- rxlen + 2)) {
- m_freem(m);
- if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
- printf("wihap: failed to copy header\n");
- ifp->if_ierrors++;
- return;
- }
-
- m->m_pkthdr.len = m->m_len =
- WI_802_11_OFFSET_RAW + rxlen;
+ wihap_mgmt_input(sc, &rx_frame, m);
- /* XXX: consider giving packet to bhp? */
-
- wihap_mgmt_input(sc, &rx_frame, m);
+ return;
+ }
+ switch (msg_type) {
+ case WI_STAT_1042:
+ case WI_STAT_TUNNEL:
+ case WI_STAT_WMP_MSG:
+ if ((letoh16(rx_frame.wi_dat_len) + WI_SNAPHDR_LEN) >
+ MCLBYTES) {
+ printf(WI_PRT_FMT ": oversized packet received "
+ "(wi_dat_len=%d, wi_status=0x%x)\n",
+ WI_PRT_ARG(sc),
+ letoh16(rx_frame.wi_dat_len),
+ letoh16(rx_frame.wi_status));
+ m_freem(m);
+ ifp->if_ierrors++;
return;
}
+ m->m_pkthdr.len = m->m_len =
+ letoh16(rx_frame.wi_dat_len) + WI_SNAPHDR_LEN;
- switch (msg_type) {
- case WI_STAT_1042:
- case WI_STAT_TUNNEL:
- case WI_STAT_WMP_MSG:
- if ((letoh16(rx_frame.wi_dat_len) + WI_SNAPHDR_LEN) >
- MCLBYTES) {
- printf(WI_PRT_FMT ": oversized packet received "
- "(wi_dat_len=%d, wi_status=0x%x)\n",
- WI_PRT_ARG(sc),
- letoh16(rx_frame.wi_dat_len),
- letoh16(rx_frame.wi_status));
- m_freem(m);
- ifp->if_ierrors++;
- return;
- }
- m->m_pkthdr.len = m->m_len =
- letoh16(rx_frame.wi_dat_len) + WI_SNAPHDR_LEN;
-
- bcopy((char *)&rx_frame.wi_dst_addr,
- (char *)&eh->ether_dhost, ETHER_ADDR_LEN);
- bcopy((char *)&rx_frame.wi_src_addr,
- (char *)&eh->ether_shost, ETHER_ADDR_LEN);
- bcopy((char *)&rx_frame.wi_type,
- (char *)&eh->ether_type, ETHER_TYPE_LEN);
-
- if (wi_read_data(sc, id, WI_802_11_OFFSET,
- mtod(m, caddr_t) + sizeof(struct ether_header),
- m->m_len + 2)) {
- ifp->if_ierrors++;
- m_freem(m);
- return;
- }
- break;
- default:
- if ((letoh16(rx_frame.wi_dat_len) +
- sizeof(struct ether_header)) > MCLBYTES) {
- printf(WI_PRT_FMT ": oversized packet received "
- "(wi_dat_len=%d, wi_status=0x%x)\n",
- WI_PRT_ARG(sc),
- letoh16(rx_frame.wi_dat_len),
- letoh16(rx_frame.wi_status));
- m_freem(m);
- ifp->if_ierrors++;
- return;
- }
- m->m_pkthdr.len = m->m_len =
- letoh16(rx_frame.wi_dat_len) +
- sizeof(struct ether_header);
+ bcopy((char *)&rx_frame.wi_dst_addr,
+ (char *)&eh->ether_dhost, ETHER_ADDR_LEN);
+ bcopy((char *)&rx_frame.wi_src_addr,
+ (char *)&eh->ether_shost, ETHER_ADDR_LEN);
+ bcopy((char *)&rx_frame.wi_type,
+ (char *)&eh->ether_type, ETHER_TYPE_LEN);
+
+ if (wi_read_data(sc, id, WI_802_11_OFFSET,
+ mtod(m, caddr_t) + sizeof(struct ether_header),
+ m->m_len + 2)) {
+ ifp->if_ierrors++;
+ m_freem(m);
+ return;
+ }
+ break;
+ default:
+ if ((letoh16(rx_frame.wi_dat_len) +
+ sizeof(struct ether_header)) > MCLBYTES) {
+ printf(WI_PRT_FMT ": oversized packet received "
+ "(wi_dat_len=%d, wi_status=0x%x)\n",
+ WI_PRT_ARG(sc),
+ letoh16(rx_frame.wi_dat_len),
+ letoh16(rx_frame.wi_status));
+ m_freem(m);
+ ifp->if_ierrors++;
+ return;
+ }
+ m->m_pkthdr.len = m->m_len =
+ letoh16(rx_frame.wi_dat_len) +
+ sizeof(struct ether_header);
- if (wi_read_data(sc, id, WI_802_3_OFFSET,
- mtod(m, caddr_t), m->m_len + 2)) {
- m_freem(m);
- ifp->if_ierrors++;
- return;
- }
- break;
+ if (wi_read_data(sc, id, WI_802_3_OFFSET,
+ mtod(m, caddr_t), m->m_len + 2)) {
+ m_freem(m);
+ ifp->if_ierrors++;
+ return;
}
+ break;
+ }
- ifp->if_ipackets++;
+ ifp->if_ipackets++;
- if (sc->wi_ptype == WI_PORTTYPE_HOSTAP) {
- /*
- * Give host AP code first crack at data packets.
- * If it decides to handle it (or drop it), it will
- * return a non-zero. Otherwise, it is destined for
- * this host.
- */
- if (wihap_data_input(sc, &rx_frame, m))
- return;
- }
+ if (sc->wi_ptype == WI_PORTTYPE_HOSTAP) {
+ /*
+ * Give host AP code first crack at data packets.
+ * If it decides to handle it (or drop it), it will
+ * return a non-zero. A -1 is returned for unauthorized
+ * packets, which should be captured and then dropped.
+ * Otherwise, it is destined for this host.
+ */
+ unauth = wihap_data_input(sc, &rx_frame, m);
+ if (unauth && unauth != -1)
+ return;
}
#if NBPFILTER > 0
/* Handle BPF listeners. */
- if (ifp->if_bpf)
+ if (!dontbpf && ifp->if_bpf)
BPF_MTAP(ifp, m);
#endif
- /* Receive packet unless in procframe or monitor mode. */
- if (sc->wi_procframe || sc->wi_debug.wi_monitor)
+ if (unauth == -1) {
m_freem(m);
- else
- ether_input_mbuf(ifp, m);
+ return;
+ }
+ ether_input_mbuf(ifp, m);
return;
}
@@ -733,6 +866,26 @@
ifp->if_oerrors++;
else
ifp->if_opackets++;
+
+ if (sc->wi_ptype == WI_PORTTYPE_HOSTAP &&
+ status & (WI_EV_TX | WI_EV_TX_EXC)) {
+ struct wi_frame txframe;
+ u_int16_t fid;
+ int err;
+
+ fid = CSR_READ_2(sc, WI_TX_CMP_FID);
+ if ((err = wi_read_data(sc, fid, 0, (void *)&txframe,
+ /* Read only the header portion. */
+ (char *)&txframe.wi_dat - (char *)&txframe))) {
+ ifp->if_oerrors++;
+ if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
+ printf(WI_PRT_FMT ": wi_txeof: cannot retrieve "
+ "(err=%d, fid=%u, wi_status=0x%04x)\n",
+ WI_PRT_ARG(sc), err, fid, status);
+ return;
+ }
+ wihap_tx_intr(sc, status, &txframe);
+ }
return;
}
@@ -1446,12 +1599,12 @@
switch (ifa->ifa_addr->sa_family) {
#ifdef INET
case AF_INET:
- wi_init(sc);
+ wi_init_keep_hostap(sc);
arp_ifinit(&sc->sc_arpcom, ifa);
break;
#endif /* INET */
default:
- wi_init(sc);
+ wi_init_keep_hostap(sc);
break;
}
break;
@@ -1477,7 +1630,7 @@
if (sc->wi_ptype != WI_PORTTYPE_HOSTAP)
WI_SETVAL(WI_RID_PROMISC, 0);
} else
- wi_init(sc);
+ wi_init_keep_hostap(sc);
} else if (ifp->if_flags & IFF_RUNNING)
wi_stop(sc);
sc->wi_if_flags = ifp->if_flags;
@@ -1535,6 +1688,10 @@
wreq.wi_val[0] = htole16(sc->sc_firmware_type ==
WI_LUCENT ? 0 : 1);
break;
+ case WI_RID_PRISM2HDR:
+ wreq.wi_len = 2;
+ wreq.wi_val[0] = htole16(sc->wi_prism2hdr);
+ break;
case WI_RID_SCAN_RES:
if (sc->sc_firmware_type == WI_LUCENT) {
memcpy((char *)wreq.wi_val,
@@ -1567,6 +1724,16 @@
break;
case WI_RID_PROCFRAME:
sc->wi_procframe = letoh16(wreq.wi_val[0]);
+#if NBPFILTER > 0
+ wi_reset_bpf_linktype(sc);
+#endif
+ error = 0;
+ break;
+ case WI_RID_PRISM2HDR:
+ sc->wi_prism2hdr = letoh16(wreq.wi_val[0]);
+#if NBPFILTER > 0
+ wi_reset_bpf_linktype(sc);
+#endif
error = 0;
break;
case WI_RID_SCAN_REQ:
@@ -1675,6 +1842,7 @@
error = wi_get_pm(sc, (struct ieee80211_power *)data);
break;
case SIOCHOSTAP_ADD:
+ case SIOCHOSTAP_CHANGE:
case SIOCHOSTAP_DEL:
case SIOCHOSTAP_GET:
case SIOCHOSTAP_GETALL:
@@ -1825,7 +1993,8 @@
/* enable interrupts */
CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
- wihap_init(sc);
+ if (!(sc->wi_flags & WI_FLAGS_KEEP_HOSTAP_UP))
+ wihap_init(sc);
splx(s);
@@ -1980,7 +2149,8 @@
struct mbuf *m0;
struct wi_frame tx_frame;
struct ether_header *eh;
- int id;
+ struct m_tag *mtag;
+ int id, oldtxkey, oldusewep;
sc = ifp->if_softc;
@@ -1997,20 +2167,69 @@
if (m0 == NULL)
return;
+ oldtxkey = oldusewep = -1;
+ mtag = NULL;
+ do {
+ mtag = m_tag_find(m0, PACKET_TAG_DRIVER_SPECIFIC, mtag);
+ if (mtag != NULL && mtag->m_tag_len >= 1) {
+ struct wi_tag_change_tx_key *t;
+
+ switch (*(u_char *)&mtag[1]) {
+ case WI_TAG_CHANGE_TX_KEY:
+ /* set a tx key temporarily */
+
+ t = (struct wi_tag_change_tx_key *)&mtag[1];
+ if (mtag->m_tag_len < sizeof(*t))
+ continue;
+ if (t->change_tx_key == 255) {
+ if (oldusewep == -1)
+ oldusewep = sc->wi_use_wep;
+ sc->wi_use_wep = 0;
+ WI_SETVAL(WI_RID_ENCRYPTION,
+ sc->wi_use_wep);
+ continue;
+ }
+ if (t->change_tx_key > 3)
+ continue;
+ if (oldtxkey == -1)
+ oldtxkey = sc->wi_tx_key;
+ sc->wi_tx_key = t->change_tx_key;
+ WI_SETVAL(WI_RID_TX_CRYPT_KEY, sc->wi_tx_key);
+ break;
+ }
+ }
+ } while (mtag != NULL);
bzero((char *)&tx_frame, sizeof(tx_frame));
tx_frame.wi_frame_ctl = htole16(WI_FTYPE_DATA);
id = sc->wi_tx_data_id;
eh = mtod(m0, struct ether_header *);
if (sc->wi_ptype == WI_PORTTYPE_HOSTAP) {
- if (!wihap_check_tx(&sc->wi_hostap_info, eh->ether_dhost,
- &tx_frame.wi_tx_rate) && !(ifp->if_flags & IFF_PROMISC)) {
+ int rej;
+
+ rej = wihap_check_tx(&sc->wi_hostap_info, eh->ether_dhost,
+ &tx_frame.wi_tx_rate);
+ /*
+ * Allow sending packets to unauthorized hosts only
+ * through the BIOCSTAGGED interface. This is slightly
+ * less a hack than, say, allowing ethernet type 0x888e...
+ */
+ if ((rej == -1 && oldusewep == -1 && oldtxkey == -1) ||
+ (!rej && !(ifp->if_flags & IFF_PROMISC))) {
if (ifp->if_flags & IFF_DEBUG)
printf(WI_PRT_FMT
- ": wi_start: dropping unassoc dst %s\n",
- WI_PRT_ARG(sc),
+ ": wi_start: dropping un%s dst %s\n",
+ WI_PRT_ARG(sc), rej ? "author" : "assoc",
ether_sprintf(eh->ether_dhost));
m_freem(m0);
+ if (oldtxkey != -1) {
+ sc->wi_tx_key = oldtxkey;
+ WI_SETVAL(WI_RID_TX_CRYPT_KEY, sc->wi_tx_key);
+ }
+ if (oldusewep != -1) {
+ sc->wi_use_wep = oldusewep;
+ WI_SETVAL(WI_RID_ENCRYPTION, sc->wi_use_wep);
+ }
goto nextpkt;
}
}
@@ -2022,11 +2241,13 @@
if (eh->ether_type == htons(ETHERTYPE_IP) ||
eh->ether_type == htons(ETHERTYPE_ARP) ||
eh->ether_type == htons(ETHERTYPE_REVARP) ||
- eh->ether_type == htons(ETHERTYPE_IPV6)) {
+ eh->ether_type == htons(ETHERTYPE_IPV6) ||
+ eh->ether_type == htons(0x888e) /* EAPOL */) {
bcopy((char *)&eh->ether_dhost,
(char *)&tx_frame.wi_addr1, ETHER_ADDR_LEN);
if (sc->wi_ptype == WI_PORTTYPE_HOSTAP) {
- tx_frame.wi_tx_ctl = htole16(WI_ENC_TX_MGMT); /* XXX */
+ tx_frame.wi_tx_ctl = htole16(WI_ENC_TX_MGMT |
+ WI_TXCNTL_TX_OK); /* XXX */
tx_frame.wi_frame_ctl |= htole16(WI_FCTL_FROMDS);
if (sc->wi_use_wep)
tx_frame.wi_frame_ctl |= htole16(WI_FCTL_WEP);
@@ -2087,11 +2308,14 @@
tx_frame.wi_dat_len = htole16(m0->m_pkthdr.len);
if (sc->wi_ptype == WI_PORTTYPE_HOSTAP && sc->wi_use_wep) {
+ static int doprint = 1;
- /* Do host encryption. (XXX - not implemented) */
- printf(WI_PRT_FMT
- ": host encrypt not implemented for 802.3\n",
- WI_PRT_ARG(sc));
+ if (doprint) {
+ /* Do host encryption. (XXX not implemented) */
+ printf(WI_PRT_FMT ": host encrypt not "
+ "implemented for 802.3\n", WI_PRT_ARG(sc));
+ doprint = 0;
+ }
} else {
m_copydata(m0, 0, m0->m_pkthdr.len,
(caddr_t)&sc->wi_txbuf);
@@ -2108,7 +2332,7 @@
* If there's a BPF listner, bounce a copy of
* this frame to him.
*/
- if (ifp->if_bpf)
+ if (ifp->if_bpf && !sc->wi_procframe && !sc->wi_debug.wi_monitor)
BPF_MTAP(ifp, m0);
#endif
@@ -2124,6 +2348,14 @@
*/
ifp->if_timer = 5;
+ if (oldtxkey != -1) {
+ sc->wi_tx_key = oldtxkey;
+ WI_SETVAL(WI_RID_TX_CRYPT_KEY, sc->wi_tx_key);
+ }
+ if (oldusewep != -1) {
+ sc->wi_use_wep = oldusewep;
+ WI_SETVAL(WI_RID_ENCRYPTION, sc->wi_use_wep);
+ }
return;
}
@@ -2150,7 +2382,7 @@
bcopy((char *)hdr, (char *)&tx_frame.wi_frame_ctl,
sizeof(struct wi_80211_hdr));
- tx_frame.wi_tx_ctl = htole16(WI_ENC_TX_MGMT);
+ tx_frame.wi_tx_ctl = htole16(WI_ENC_TX_MGMT | WI_TXCNTL_TX_OK);
tx_frame.wi_dat_len = len - sizeof(struct wi_80211_hdr);
tx_frame.wi_len = htole16(tx_frame.wi_dat_len);
@@ -2174,7 +2406,8 @@
{
struct ifnet *ifp;
- wihap_shutdown(sc);
+ if (!(sc->wi_flags & WI_FLAGS_KEEP_HOSTAP_UP))
+ wihap_shutdown(sc);
if (!(sc->wi_flags & WI_FLAGS_ATTACHED))
return;
@@ -2550,7 +2783,7 @@
return (error);
if (sc->sc_arpcom.ac_if.if_flags & IFF_UP)
- wi_init(sc);
+ wi_init_keep_hostap(sc);
return 0;
}
@@ -2595,7 +2828,7 @@
sc->wi_max_sleep = power->i_maxsleep;
if (sc->sc_arpcom.ac_if.if_flags & IFF_UP)
- wi_init(sc);
+ wi_init_keep_hostap(sc);
return (0);
}
@@ -2713,6 +2946,9 @@
break;
case WI_DEBUG_MONITOR:
sc->wi_debug.wi_monitor = 1;
+#if NBPFILTER > 0
+ wi_reset_bpf_linktype(sc);
+#endif
break;
case WI_DEBUG_LEDTEST:
param0 = letoh16(wreq->wi_val[0]);
@@ -2730,6 +2966,9 @@
sc->wi_debug.wi_delaysupp = 0;
sc->wi_debug.wi_txsupp = 0;
sc->wi_debug.wi_monitor = 0;
+#if NBPFILTER > 0
+ wi_reset_bpf_linktype(sc);
+#endif
sc->wi_debug.wi_ledtest = 0;
sc->wi_debug.wi_ledtest_param0 = 0;
sc->wi_debug.wi_ledtest_param1 = 0;
Index: sys/dev/ic/if_wi_hostap.c
===================================================================
RCS file: /u/cvs/SNOWNET/Soekris/OpenBSD-src/sys/dev/ic/if_wi_hostap.c,v
retrieving revision 1.1.1.1
retrieving revision 1.4
diff -u -r1.1.1.1 -r1.4
--- sys/dev/ic/if_wi_hostap.c 13 Aug 2002 03:49:51 -0000 1.1.1.1
+++ sys/dev/ic/if_wi_hostap.c 23 Jun 2003 21:17:49 -0000 1.4
@@ -80,7 +80,6 @@
struct wihap_sta_info *wihap_sta_alloc(struct wi_softc *sc, u_int8_t *addr);
void wihap_sta_delete(struct wihap_sta_info *sta);
struct wihap_sta_info *wihap_sta_find(struct wihap_info *whi, u_int8_t *addr);
-int wihap_sta_is_assoc(struct wihap_info *whi, u_int8_t addr[]);
void wihap_auth_req(struct wi_softc *sc, struct wi_frame *rxfrm,
caddr_t pkt, int len);
void wihap_sta_deauth(struct wi_softc *sc, u_int8_t sta_addr[],
@@ -95,6 +94,18 @@
caddr_t pkt, int len);
/*
+ * wihap_refresh()
+ *
+ * Update the timeout for a station and clear the did-ping flag.
+ */
+static __inline void
+wihap_refresh(struct wihap_info *whi, struct wihap_sta_info *sta) {
+
+ sta->flags &= ~WI_SIFLAGS_PING;
+ timeout_add(&sta->tmo, hz * whi->inactivity_time);
+}
+
+/*
* take_hword()
*
* Used for parsing management frames. The pkt pointer and length
@@ -288,9 +299,6 @@
s = splimp();
sta = LIST_FIRST(&whi->sta_list);
while (sta) {
-
- timeout_del(&sta->tmo);
-
if (sc->wi_flags & WI_FLAGS_ATTACHED) {
/* Disassociate station. */
if (sta->flags & WI_SIFLAGS_ASSOC)
@@ -306,7 +314,7 @@
if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
printf("wihap_shutdown: FREE(sta=0x%x)\n", sta);
next = LIST_NEXT(sta, list);
- FREE(sta, M_DEVBUF);
+ wihap_sta_delete(sta);
sta = next;
}
splx(s);
@@ -339,7 +347,36 @@
s = splsoftnet();
- if (sta->flags & WI_SIFLAGS_ASSOC) {
+ /*
+ * If there has been no activity for WIHAP_DFLT_INACTIVITY_TIME
+ * seconds, send an empty data packet to test for an ACK.
+ *
+ * The "nullfunc" packet type cannot be used because stations
+ * may or may not ACK it.
+ */
+ if (!(sta->flags & WI_SIFLAGS_PING)) {
+ struct wi_80211_hdr *resp_hdr;
+
+ if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
+ printf("Sending empty DATA ping to sta %s\n",
+ ether_sprintf(sta->addr));
+
+ /* Send empty data packet. */
+ resp_hdr = (struct wi_80211_hdr *)sc->wi_txbuf;
+ bzero(resp_hdr, sizeof(struct wi_80211_hdr));
+ resp_hdr->frame_ctl = htole16(WI_FTYPE_DATA);
+
+ bcopy(sta->addr, resp_hdr->addr1, ETHER_ADDR_LEN);
+ bcopy(sc->sc_arpcom.ac_enaddr, resp_hdr->addr2, ETHER_ADDR_LEN);
+ bcopy(sc->sc_arpcom.ac_enaddr, resp_hdr->addr3, ETHER_ADDR_LEN);
+
+ wi_mgmt_xmit(sc, (caddr_t)&sc->wi_txbuf,
+ sizeof(struct wi_80211_hdr));
+
+ sta->flags |= WI_SIFLAGS_PING;
+
+ timeout_add(&sta->tmo, hz * whi->inactivity_time);
+ } else if (sta->flags & WI_SIFLAGS_ASSOC) {
if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
printf("wihap_timer: disassoc due to inactivity: %s\n",
ether_sprintf(sta->addr));
@@ -349,10 +386,8 @@
IEEE80211_REASON_ASSOC_EXPIRE);
sta->flags &= ~WI_SIFLAGS_ASSOC;
- timeout_add(&sta->tmo, hz * whi->inactivity_time);
-
+ timeout_add(&sta->tmo, hz * whi->inactivity_time * 2);
} else if (sta->flags & WI_SIFLAGS_AUTHEN) {
-
if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
printf("wihap_timer: deauth due to inactivity: %s\n",
ether_sprintf(sta->addr));
@@ -465,6 +500,8 @@
sta->rates |= WI_SUPPRATES_2M;
if (sta->tx_max_rate < 1)
sta->tx_max_rate = 1;
+ sta->tx_max_rate = 1;
+ sta->tx_max_rate = 1;
break;
case 0x0b:
sta->rates |= WI_SUPPRATES_5M;
@@ -549,8 +586,8 @@
status = IEEE80211_STATUS_TOO_MANY_STATIONS;
goto fail;
}
- }
- timeout_add(&sta->tmo, hz * whi->inactivity_time);
+ } else
+ wihap_refresh(whi, sta);
/* Note: it's okay to leave the station info structure around
* if the authen fails. It'll be timed out eventually.
@@ -771,7 +808,7 @@
}
sta->flags |= WI_SIFLAGS_ASSOC;
- timeout_add(&sta->tmo, hz * whi->inactivity_time);
+ wihap_refresh(whi, sta);
status = IEEE80211_STATUS_SUCCESS;
fail:
@@ -941,9 +978,8 @@
pkt = mtod(m, caddr_t) + WI_802_11_OFFSET_RAW;
len = m->m_len - WI_802_11_OFFSET_RAW;
- if ((rxfrm->wi_frame_ctl & htole16(WI_FCTL_FTYPE)) ==
- htole16(WI_FTYPE_MGMT)) {
-
+ switch (letoh16(rxfrm->wi_frame_ctl) & WI_FCTL_FTYPE) {
+ case WI_FTYPE_MGMT:
/* any of the following will mess w/ the station list */
s = splsoftclock();
switch (letoh16(rxfrm->wi_frame_ctl) & WI_FCTL_STYPE) {
@@ -976,35 +1012,15 @@
break;
}
splx(s);
+ break;
}
m_freem(m);
}
-/* wihap_sta_is_assoc()
- *
- * Determine if a station is assoc'ed. Update its activity
- * counter as a side-effect.
- */
-int
-wihap_sta_is_assoc(struct wihap_info *whi, u_int8_t addr[])
-{
- struct wihap_sta_info *sta;
-
- sta = wihap_sta_find(whi, addr);
- if (sta != NULL && (sta->flags & WI_SIFLAGS_ASSOC)) {
- /* Keep it active. */
- timeout_add(&sta->tmo, hz * whi->inactivity_time);
- return (1);
- }
-
- return (0);
-}
-
/* wihap_check_tx()
*
- * Determine if a station is assoc'ed, get its tx rate, and update
- * its activity.
+ * Determine if a station is assoc'ed and get its tx rate.
*/
int
wihap_check_tx(struct wihap_info *whi, u_int8_t addr[], u_int8_t *txrate)
@@ -1020,12 +1036,14 @@
s = splsoftclock();
sta = wihap_sta_find(whi, addr);
- if (sta != NULL && (sta->flags & WI_SIFLAGS_ASSOC)) {
- /* Keep it active. */
- timeout_add(&sta->tmo, hz * whi->inactivity_time);
+ if (sta != NULL && sta->flags & WI_SIFLAGS_ASSOC) {
+ int unauth;
+
*txrate = txratetable[sta->tx_curr_rate];
+ unauth = whi->apflags & WIHAPFL_AUTHORIZED_FILT &&
+ !(sta->flags & HOSTAP_FLAGS_AUTHORIZED);
splx(s);
- return (1);
+ return (unauth ? -1 : 1);
}
splx(s);
@@ -1039,7 +1057,10 @@
* Some packets are destined for this machine, others are
* repeated to other stations.
*
- * If wihap_data_input() returns a non-zero, it has processed
+ * If wihap_data_input() returns -1, then the packet is
+ * unauthorized but not freed.
+ *
+ * If wihap_data_input() returns 1, then it has processed
* the packet and will free the mbuf.
*/
int
@@ -1047,7 +1068,7 @@
{
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
struct wihap_info *whi = &sc->wi_hostap_info;
- struct wihap_sta_info *sta;
+ struct wihap_sta_info *sta, *dststa;
int mcast, s;
/* TODS flag must be set. */
@@ -1084,15 +1105,24 @@
m_freem(m);
return (1);
}
+ if (whi->apflags & WIHAPFL_AUTHORIZED_FILT &&
+ !(sta->flags & HOSTAP_FLAGS_AUTHORIZED)) {
+ if (ifp->if_flags & IFF_DEBUG)
+ printf("wihap_data_input: dropping unauthorized "
+ "src %s\n", ether_sprintf(rxfrm->wi_addr2));
+ splx(s);
+ return (-1);
+ }
- timeout_add(&sta->tmo, hz * whi->inactivity_time);
+ wihap_refresh(whi, sta);
sta->sig_info = letoh16(rxfrm->wi_q_info);
splx(s);
/* Repeat this packet to BSS? */
mcast = (rxfrm->wi_addr3[0] & 0x01) != 0;
- if (mcast || wihap_sta_is_assoc(whi, rxfrm->wi_addr3)) {
+ dststa = wihap_sta_find(whi, rxfrm->wi_addr3);;
+ if (mcast || (dststa != NULL && dststa->flags & WI_SIFLAGS_ASSOC)) {
/* If it's multicast, make a copy.
*/
@@ -1101,6 +1131,20 @@
if (m == NULL)
return (0);
m->m_flags |= M_MCAST; /* XXX */
+ } else {
+ /*
+ * Don't send unicast packets to non-authorized
+ * hosts when in authorized-only mode.
+ */
+ if (whi->apflags & WIHAPFL_AUTHORIZED_FILT &&
+ !(dststa->flags & HOSTAP_FLAGS_AUTHORIZED)) {
+ if (ifp->if_flags & IFF_DEBUG)
+ printf("wihap_data_input: dropping "
+ "unauthorized dst %s\n",
+ ether_sprintf(rxfrm->wi_addr3));
+ m_freem(m);
+ return (1);
+ }
}
/* Queue up for repeating.
@@ -1187,6 +1231,30 @@
splx(s);
break;
+ case SIOCHOSTAP_CHANGE:
+ if ((error = suser(p->p_ucred, &p->p_acflag)))
+ break;
+ if ((error = copyin(ifr->ifr_data, &reqsta, sizeof(reqsta))))
+ break;
+ s = splimp();
+ sta = wihap_sta_find(whi, reqsta.addr);
+ if (sta == NULL)
+ error = ENOENT;
+ else {
+ if (sta->flags & WI_SIFLAGS_ASSOC &&
+ !(reqsta.flags & WI_SIFLAGS_ASSOC))
+ wihap_sta_disassoc(sc, sta->addr,
+ IEEE80211_REASON_ASSOC_LEAVE);
+ if (sta->flags & WI_SIFLAGS_AUTHEN &&
+ !(reqsta.flags & WI_SIFLAGS_AUTHEN))
+ wihap_sta_deauth(sc, sta->addr,
+ IEEE80211_REASON_AUTH_LEAVE);
+ sta->flags = (sta->flags & HOSTAP_FLAGS_CANTCHANGE) |
+ (reqsta.flags & ~HOSTAP_FLAGS_CANTCHANGE);
+ }
+ splx(s);
+ break;
+
case SIOCHOSTAP_ADD:
if ((error = suser(p->p_ucred, &p->p_acflag)))
break;
@@ -1205,8 +1273,7 @@
break;
}
sta = wihap_sta_alloc(sc, reqsta.addr);
- sta->flags = reqsta.flags;
- timeout_add(&sta->tmo, hz * whi->inactivity_time);
+ sta->flags = reqsta.flags & ~HOSTAP_FLAGS_CANTCHANGE;
splx(s);
break;
@@ -1262,4 +1329,29 @@
}
return (error);
+}
+
+/* wihap_tx_intr()
+ *
+ * Complete a TX done interrupt by updating the last-used status
+ * of a station if transmission (i.e. of a ping) was successful.
+ */
+void
+wihap_tx_intr(struct wi_softc *sc, u_int16_t status, struct wi_frame *tx_frame)
+{
+ /* Update the timeout for ACK packets. */
+ struct wihap_sta_info *sta;
+ int s;
+
+ if (status & WI_EV_TX_EXC)
+ return;
+ s = splsoftclock();
+ sta = wihap_sta_find(&sc->wi_hostap_info, tx_frame->wi_addr1);
+ if (sta != NULL) {
+ if (sc->sc_arpcom.ac_if.if_flags & IFF_DEBUG)
+ printf("wihap_tx_intr: tx completed to %s\n",
+ ether_sprintf(tx_frame->wi_addr1));
+ wihap_refresh(&sc->wi_hostap_info, sta);
+ }
+ splx(s);
}
Index: sys/dev/ic/if_wi_hostap.h
===================================================================
RCS file: /u/cvs/SNOWNET/Soekris/OpenBSD-src/sys/dev/ic/if_wi_hostap.h,v
retrieving revision 1.1.1.1
retrieving revision 1.4
diff -u -r1.1.1.1 -r1.4
--- sys/dev/ic/if_wi_hostap.h 8 Jun 2002 22:19:47 -0000 1.1.1.1
+++ sys/dev/ic/if_wi_hostap.h 24 Jun 2003 13:12:22 -0000 1.4
@@ -51,7 +51,9 @@
#define HOSTAP_FLAGS_AUTHEN 0x0001
#define HOSTAP_FLAGS_ASSOC 0x0002
#define HOSTAP_FLAGS_PERM 0x0004
-#define HOSTAP_FLAGS_BITS "\20\01ASSOC\02AUTH\03PERM"
+#define HOSTAP_FLAGS_AUTHORIZED 0x0008
+#define HOSTAP_FLAGS_PING 0x0010
+#define HOSTAP_FLAGS_BITS "\20\01AUTH\02ASSOC\03PERM\04AUTHR\05PING"
#define SIOCHOSTAP_GET _IOWR('i', 210, struct ifreq)
#define SIOCHOSTAP_ADD _IOWR('i', 211, struct ifreq)
@@ -59,13 +61,16 @@
#define SIOCHOSTAP_GETALL _IOWR('i', 213, struct ifreq)
#define SIOCHOSTAP_GFLAGS _IOWR('i', 214, struct ifreq)
#define SIOCHOSTAP_SFLAGS _IOWR('i', 215, struct ifreq)
+#define SIOCHOSTAP_CHANGE _IOWR('i', 216, struct ifreq)
/* Flags for SIOCHOSTAP_GFLAGS/SFLAGS */
#define WIHAPFL_ACTIVE 0x0001
#define WIHAPFL_MAC_FILT 0x0002
+#define WIHAPFL_AUTHORIZED_FILT 0x0004
-/* Flags set inernally only: */
+/* Flags set internally only: */
#define WIHAPFL_CANTCHANGE (WIHAPFL_ACTIVE)
+#define HOSTAP_FLAGS_CANTCHANGE (HOSTAP_FLAGS_PING)
struct hostap_getall {
int nstations;
@@ -97,6 +102,8 @@
#define WI_SIFLAGS_ASSOC HOSTAP_FLAGS_ASSOC
#define WI_SIFLAGS_AUTHEN HOSTAP_FLAGS_AUTHEN
#define WI_SIFLAGS_PERM HOSTAP_FLAGS_PERM
+#define WI_SIFLAGS_AUTHORIZED HOSTAP_FLAGS_AUTHORIZED
+#define WI_SIFLAGS_PING HOSTAP_FLAGS_PING
#define WI_STA_HASH_SIZE 113
@@ -119,7 +126,7 @@
int inactivity_time;
};
-#define WIHAP_DFLT_INACTIVITY_TIME (120) /* 2 minutes */
+#define WIHAP_DFLT_INACTIVITY_TIME (60) /* 1 minute */
struct wi_softc;
struct wi_frame;
@@ -129,6 +136,7 @@
int wihap_ioctl(struct wi_softc *, u_long, caddr_t);
void wihap_init(struct wi_softc *);
void wihap_mgmt_input(struct wi_softc *, struct wi_frame *, struct mbuf *);
+void wihap_tx_intr(struct wi_softc *, u_int16_t status, struct wi_frame *);
void wihap_shutdown(struct wi_softc *);
#endif /* _KERNEL */
Index: sys/dev/ic/if_wi_ieee.h
===================================================================
RCS file: /u/cvs/SNOWNET/Soekris/OpenBSD-src/sys/dev/ic/if_wi_ieee.h,v
retrieving revision 1.1.1.1
retrieving revision 1.5
diff -u -r1.1.1.1 -r1.5
--- sys/dev/ic/if_wi_ieee.h 10 Sep 2002 08:21:35 -0000 1.1.1.1
+++ sys/dev/ic/if_wi_ieee.h 24 Jun 2003 13:12:22 -0000 1.5
@@ -82,7 +82,7 @@
*/
#define WI_RID_IFACE_STATS 0x0100
#define WI_RID_MGMT_XMIT 0x0200
-#define WI_RID_MONITOR_MODE 0x0500
+#define WI_RID_MONITOR_MODE 0x0500
struct wi_80211_hdr {
u_int16_t frame_ctl;
@@ -180,39 +180,39 @@
/*
* Network parameters, static configuration entities.
*/
-#define WI_RID_PORTTYPE 0xFC00 /* Connection control characteristics */
-#define WI_RID_MAC_NODE 0xFC01 /* MAC address of this station */
-#define WI_RID_DESIRED_SSID 0xFC02 /* Service Set ID for connection */
-#define WI_RID_OWN_CHNL 0xFC03 /* Comm channel for BSS creation */
-#define WI_RID_OWN_SSID 0xFC04 /* IBSS creation ID */
-#define WI_RID_OWN_ATIM_WIN 0xFC05 /* ATIM window time for IBSS creation */
-#define WI_RID_SYSTEM_SCALE 0xFC06 /* scale that specifies AP density */
-#define WI_RID_MAX_DATALEN 0xFC07 /* Max len of MAC frame body data */
-#define WI_RID_MAC_WDS 0xFC08 /* MAC addr of corresponding WDS node */
-#define WI_RID_PM_ENABLED 0xFC09 /* ESS power management enable */
-#define WI_RID_PM_EPS 0xFC0A /* PM EPS/PS mode */
-#define WI_RID_MCAST_RX 0xFC0B /* ESS PM mcast reception */
-#define WI_RID_MAX_SLEEP 0xFC0C /* max sleep time for ESS PM */
-#define WI_RID_HOLDOVER 0xFC0D /* holdover time for ESS PM */
-#define WI_RID_NODENAME 0xFC0E /* ID name of this node for diag */
-#define WI_RID_DTIM_PERIOD 0xFC10 /* beacon interval between DTIMs */
-#define WI_RID_WDS_ADDR1 0xFC11 /* port 1 MAC of WDS link node */
-#define WI_RID_WDS_ADDR2 0xFC12 /* port 1 MAC of WDS link node */
-#define WI_RID_WDS_ADDR3 0xFC13 /* port 1 MAC of WDS link node */
-#define WI_RID_WDS_ADDR4 0xFC14 /* port 1 MAC of WDS link node */
-#define WI_RID_WDS_ADDR5 0xFC15 /* port 1 MAC of WDS link node */
-#define WI_RID_WDS_ADDR6 0xFC16 /* port 1 MAC of WDS link node */
-#define WI_RID_MCAST_PM_BUF 0xFC17 /* PM buffering of mcast */
-#define WI_RID_ENCRYPTION 0xFC20 /* enable/disable WEP */
-#define WI_RID_AUTHTYPE 0xFC21 /* specify authentication type */
-#define WI_RID_SYMBOL_MANDATORYBSSID 0xFC21
-#define WI_RID_P2_TX_CRYPT_KEY 0xFC23
-#define WI_RID_P2_CRYPT_KEY0 0xFC24
-#define WI_RID_P2_CRYPT_KEY1 0xFC25
-#define WI_RID_MICROWAVE_OVEN 0xFC25 /* Microwave oven robustness */
-#define WI_RID_P2_CRYPT_KEY2 0xFC26
-#define WI_RID_P2_CRYPT_KEY3 0xFC27
-#define WI_RID_P2_ENCRYPTION 0xFC28
+#define WI_RID_PORTTYPE 0xFC00 /* Connection control characteristics */
+#define WI_RID_MAC_NODE 0xFC01 /* MAC address of this station */
+#define WI_RID_DESIRED_SSID 0xFC02 /* Service Set ID for connection */
+#define WI_RID_OWN_CHNL 0xFC03 /* Comm channel for BSS creation */
+#define WI_RID_OWN_SSID 0xFC04 /* IBSS creation ID */
+#define WI_RID_OWN_ATIM_WIN 0xFC05 /* ATIM window time for IBSS creation */
+#define WI_RID_SYSTEM_SCALE 0xFC06 /* scale that specifies AP density */
+#define WI_RID_MAX_DATALEN 0xFC07 /* Max len of MAC frame body data */
+#define WI_RID_MAC_WDS 0xFC08 /* MAC addr of corresponding WDS node */
+#define WI_RID_PM_ENABLED 0xFC09 /* ESS power management enable */
+#define WI_RID_PM_EPS 0xFC0A /* PM EPS/PS mode */
+#define WI_RID_MCAST_RX 0xFC0B /* ESS PM mcast reception */
+#define WI_RID_MAX_SLEEP 0xFC0C /* max sleep time for ESS PM */
+#define WI_RID_HOLDOVER 0xFC0D /* holdover time for ESS PM */
+#define WI_RID_NODENAME 0xFC0E /* ID name of this node for diag */
+#define WI_RID_DTIM_PERIOD 0xFC10 /* beacon interval between DTIMs */
+#define WI_RID_WDS_ADDR1 0xFC11 /* port 1 MAC of WDS link node */
+#define WI_RID_WDS_ADDR2 0xFC12 /* port 1 MAC of WDS link node */
+#define WI_RID_WDS_ADDR3 0xFC13 /* port 1 MAC of WDS link node */
+#define WI_RID_WDS_ADDR4 0xFC14 /* port 1 MAC of WDS link node */
+#define WI_RID_WDS_ADDR5 0xFC15 /* port 1 MAC of WDS link node */
+#define WI_RID_WDS_ADDR6 0xFC16 /* port 1 MAC of WDS link node */
+#define WI_RID_MCAST_PM_BUF 0xFC17 /* PM buffering of mcast */
+#define WI_RID_ENCRYPTION 0xFC20 /* enable/disable WEP */
+#define WI_RID_AUTHTYPE 0xFC21 /* specify authentication type */
+#define WI_RID_SYMBOL_MANDATORYBSSID 0xFC21
+#define WI_RID_P2_TX_CRYPT_KEY 0xFC23
+#define WI_RID_P2_CRYPT_KEY0 0xFC24
+#define WI_RID_P2_CRYPT_KEY1 0xFC25
+#define WI_RID_MICROWAVE_OVEN 0xFC25 /* Microwave oven robustness */
+#define WI_RID_P2_CRYPT_KEY2 0xFC26
+#define WI_RID_P2_CRYPT_KEY3 0xFC27
+#define WI_RID_P2_ENCRYPTION 0xFC28
#define PRIVACY_INVOKED 0x01
#define EXCLUDE_UNENCRYPTED 0x02
#define HOST_ENCRYPT 0x10
@@ -221,16 +221,16 @@
#define IV_EVERY50_FRAME 0x40
#define IV_EVERY100_FRAME 0x60
#define HOST_DECRYPT 0x80
-#define WI_RID_WEP_MAPTABLE 0xFC29
-#define WI_RID_CNFAUTHMODE 0xFC2A
-#define WI_RID_SYMBOL_KEYLENGTH 0xFC2B
-#define WI_RID_ROAMING_MODE 0xFC2D /* Roaming mode (1:firm,3:disable) */
-#define WI_RID_CNF_DBM_ADJUST 0xFC46 /* Get DBM adjustment factor */
-#define WI_RID_SYMBOL_PREAMBLE 0xFC8C /* Enable/disable short preamble */
-#define WI_RID_P2_SHORT_PREAMBLE 0xFCB0 /* Short preamble support */
-#define WI_RID_P2_EXCLUDE_LONG_PREAMBLE 0xFCB1 /* Don't send long preamble */
-#define WI_RID_BASIC_RATE 0xFCB3
-#define WI_RID_SUPPORT_RATE 0xFCB4
+#define WI_RID_WEP_MAPTABLE 0xFC29
+#define WI_RID_CNFAUTHMODE 0xFC2A
+#define WI_RID_SYMBOL_KEYLENGTH 0xFC2B
+#define WI_RID_ROAMING_MODE 0xFC2D /* Roaming mode (1:firm,3:disable) */
+#define WI_RID_CNF_DBM_ADJUST 0xFC46 /* Get DBM adjustment factor */
+#define WI_RID_SYMBOL_PREAMBLE 0xFC8C /* Enable/disable short preamble */
+#define WI_RID_P2_SHORT_PREAMBLE 0xFCB0 /* Short preamble support */
+#define WI_RID_P2_EXCLUDE_LONG_PREAMBLE 0xFCB1 /* Don't send long preamble */
+#define WI_RID_BASIC_RATE 0xFCB3
+#define WI_RID_SUPPORT_RATE 0xFCB4
#define WI_RID_SYMBOL_DIVERSITY 0xFC87 /* Symbol antenna diversity */
#define WI_RID_SYMBOL_BASIC_RATE 0xFC90
@@ -544,6 +544,7 @@
*/
#define WI_RID_PROCFRAME 0x3137 /* Return full frame information */
#define WI_RID_PRISM2 0x3138 /* tell if we're a prism2 card or not */
+#define WI_RID_PRISM2HDR 0x3139 /* provide the PRISM 2 header */
/*
@@ -708,4 +709,13 @@
#define WI_RID_MAC_PROC_DELAY 0xFDC5 /* MAC processing delay time */
#define WI_RID_DATA_RATES 0xFDC6 /* supported data rates */
+/*
+ * Mbuf tag types for sending packets with special conditions utilizing
+ * the BIOCSTAGGED ioctl on bpf devices
+ */
+#define WI_TAG_CHANGE_TX_KEY 0x0 /* switch to a different WEP key */
+struct wi_tag_change_tx_key {
+ u_char type;
+ u_char change_tx_key; /* WEP key #0-N, or 255 to disable */
+};
#endif
Index: sys/dev/ic/if_wireg.h
===================================================================
RCS file: /u/cvs/SNOWNET/Soekris/OpenBSD-src/sys/dev/ic/if_wireg.h,v
retrieving revision 1.1.1.1
retrieving revision 1.6
diff -u -r1.1.1.1 -r1.6
--- sys/dev/ic/if_wireg.h 12 Sep 2002 03:48:31 -0000 1.1.1.1
+++ sys/dev/ic/if_wireg.h 24 Jun 2003 13:12:22 -0000 1.6
@@ -26,7 +26,7 @@
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * intERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
@@ -70,11 +70,11 @@
#define WI_DEFAULT_CHAN 3
-#define WI_DEFAULT_ROAMING 1
+#define WI_DEFAULT_ROAMING 1
-#define WI_DEFAULT_AUTHTYPE 1
+#define WI_DEFAULT_AUTHTYPE 1
-#define WI_DEFAULT_DIVERSITY 0
+#define WI_DEFAULT_DIVERSITY 0
/*
* register space access macros
@@ -272,6 +272,12 @@
#define WI_INTRS \
(WI_EV_RX|WI_EV_TX|WI_EV_TX_EXC|WI_EV_ALLOC|WI_EV_INFO|WI_EV_INFO_DROP)
+/* async tx failure status */
+#define WI_TX_EXC_RETRYERR 0x0001
+#define WI_TX_EXC_AGEDERR 0x0002
+#define WI_TX_EXC_DISCON 0x0004
+#define WI_TX_EXC_FORMERR 0x0008
+
/* Host software registers */
#define WI_SW0 0x28
#define WI_SW1 0x2A
@@ -301,7 +307,7 @@
#define WI_PLX_LINT1STAT 0x04 /* Local interrupt 1 status bit */
#define WI_PLX_COR_OFFSET 0x3E0 /* COR attribute offset of card */
-#define WI_DRVR_MAGIC 0x4A2D /* Magic number for card detection */
+#define WI_DRVR_MAGIC 0x4A2D /* Magic number for card detection */
#define WI_TMD_LOCALRES 0x14 /* TMD chip's local registers */
#define WI_TMD_IORES 0x18 /* Prism I/O space (TMD) */
@@ -402,19 +408,19 @@
u_int16_t wi_len;
u_int16_t wi_type;
u_int16_t wi_ver[4];
-#define WI_NIC_LUCENT 0x0001
-#define WI_NIC_SONY 0x0002
-#define WI_NIC_LUCENT_EM 0x0005
-#define WI_NIC_EVB2 0x8000
-#define WI_NIC_HWB3763 0x8001
-#define WI_NIC_HWB3163 0x8002
-#define WI_NIC_HWB3163B 0x8003
-#define WI_NIC_EVB3 0x8004
-#define WI_NIC_HWB1153 0x8007
-#define WI_NIC_P2_SST 0x8008 /* Prism2 with SST flush */
-#define WI_NIC_PRISM2_5 0x800C
-#define WI_NIC_3874A 0x8013 /* Prism2.5 Mini-PCI */
-#define WI_NIC_37300P 0x801a
+#define WI_NIC_LUCENT 0x0001
+#define WI_NIC_SONY 0x0002
+#define WI_NIC_LUCENT_EM 0x0005
+#define WI_NIC_EVB2 0x8000
+#define WI_NIC_HWB3763 0x8001
+#define WI_NIC_HWB3163 0x8002
+#define WI_NIC_HWB3163B 0x8003
+#define WI_NIC_EVB3 0x8004
+#define WI_NIC_HWB1153 0x8007
+#define WI_NIC_P2_SST 0x8008 /* Prism2 with SST flush */
+#define WI_NIC_PRISM2_5 0x800C
+#define WI_NIC_3874A 0x8013 /* Prism2.5 Mini-PCI */
+#define WI_NIC_37300P 0x801a
};
/*
@@ -530,7 +536,7 @@
#define WI_SUPPRATES_2M 0x0002
#define WI_SUPPRATES_5M 0x0004
#define WI_SUPPRATES_11M 0x0008
-#define WI_RATES_BITS "\20\0011M\0022M\0035.5M\00411M"
+#define WI_RATES_BITS "\20\0011M\0022M\0035.5M\00411M"
/*
* Information frame types.
@@ -546,12 +552,13 @@
*/
struct wi_frame {
u_int16_t wi_status; /* 0x00 */
- u_int16_t wi_rsvd0; /* 0x02 */
- u_int16_t wi_rsvd1; /* 0x04 */
+ u_int16_t wi_time0; /* 0x02 */
+ u_int16_t wi_time1; /* 0x04 */
u_int16_t wi_q_info; /* 0x06 */
- u_int16_t wi_rsvd2; /* 0x08 */
+ u_int8_t wi_rx_rate; /* 0x08 */
+ u_int8_t wi_rx_flow; /* 0x09 */
u_int8_t wi_tx_rtry; /* 0x0A */
- u_int8_t wi_tx_rate; /* 0x0A */
+ u_int8_t wi_tx_rate; /* 0x0B */
u_int16_t wi_tx_ctl; /* 0x0C */
u_int16_t wi_frame_ctl; /* 0x0E */
u_int16_t wi_id; /* 0x10 */
@@ -585,7 +592,7 @@
#define WI_ENC_TX_802_3 0x00
#define WI_ENC_TX_802_11 0x11
-#define WI_ENC_TX_MGMT 0x08
+#define WI_ENC_TX_MGMT 0x08
#define WI_ENC_TX_E_II 0x0E
#define WI_ENC_TX_1042 0x00
@@ -612,3 +619,25 @@
#define WI_SNAPHDR_LEN 0x6
#define WI_FCS_LEN 0x4
+
+/*
+ * Prism2 (?) special informational header.
+ */
+struct prism2_header {
+ u_int32_t version;
+ u_int32_t length;
+ u_int64_t mac_time;
+ u_int64_t host_time;
+ u_int32_t phy_type;
+ u_int32_t channel;
+ u_int32_t data_rate;
+ u_int32_t antenna;
+ u_int32_t priority;
+ u_int32_t ssi_type;
+ int32_t ssi_signal;
+ int32_t ssi_noise;
+ u_int32_t preamble;
+ u_int32_t encoding;
+};
+
+#define PRISM2_HEADER_VERSION 0x80211001
Index: sys/dev/ic/if_wivar.h
===================================================================
RCS file: /u/cvs/SNOWNET/Soekris/OpenBSD-src/sys/dev/ic/if_wivar.h,v
retrieving revision 1.1.1.1
retrieving revision 1.4
diff -u -r1.1.1.1 -r1.4
--- sys/dev/ic/if_wivar.h 9 Jul 2002 11:00:27 -0000 1.1.1.1
+++ sys/dev/ic/if_wivar.h 24 Jun 2003 13:12:22 -0000 1.4
@@ -52,6 +52,7 @@
int wi_flags;
int wi_if_flags;
u_int16_t wi_procframe;
+ u_int16_t wi_prism2hdr;
u_int16_t wi_ptype;
u_int16_t wi_portnum;
u_int16_t wi_max_data_len;
@@ -120,6 +121,7 @@
#define WI_FLAGS_HAS_DIVERSITY 0x0080
#define WI_FLAGS_HAS_HOSTAP 0x0100
#define WI_FLAGS_BUS_PCMCIA 0x0200
+#define WI_FLAGS_KEEP_HOSTAP_UP 0x0400
/* Firmware types */
#define WI_LUCENT 0
More information about the Hostap
mailing list