summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2004-11-25 11:20:05 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2004-11-25 11:20:05 +0000
commit7c9e4c2086c4479dbec08dd4d1e199a9864ee907 (patch)
treebba786766bdfb85b22e42c699f3856110f6d26c5 /sys
parenta9798afbe0ac1fc76003db44f88a4664cb912780 (diff)
compatibility ioctls for things like "wicontrol ath0 -l" to
list known stations on a net80211-based ap. ok millert@
Diffstat (limited to 'sys')
-rw-r--r--sys/net80211/ieee80211_ioctl.c96
1 files changed, 95 insertions, 1 deletions
diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c
index e3d6574f671..0a1ea1f2fe6 100644
--- a/sys/net80211/ieee80211_ioctl.c
+++ b/sys/net80211/ieee80211_ioctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_ioctl.c,v 1.3 2004/06/28 19:29:40 millert Exp $ */
+/* $OpenBSD: ieee80211_ioctl.c,v 1.4 2004/11/25 11:20:04 reyk Exp $ */
/* $NetBSD: ieee80211_ioctl.c,v 1.15 2004/05/06 02:58:16 dyoung Exp $ */
/*-
@@ -82,10 +82,16 @@ __KERNEL_RCSID(0, "$NetBSD: ieee80211_ioctl.c,v 1.15 2004/05/06 02:58:16 dyoung
#include <dev/wi/if_wavelan_ieee.h>
#elif defined(__OpenBSD__)
#include <dev/ic/if_wi_ieee.h>
+#include <dev/ic/if_wi_hostap.h>
#else
#include <dev/ic/wi_ieee.h>
#endif
+#if defined(__OpenBSD__)
+void node2sta(struct ieee80211com *, struct ieee80211_node *,
+ struct hostap_sta *);
+#endif
+
/*
* XXX
* Wireless LAN specific configuration interface, which is compatible
@@ -1128,6 +1134,11 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
static const u_int8_t empty_macaddr[IEEE80211_ADDR_LEN] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
+#if defined(__OpenBSD__)
+ struct ieee80211_node *ni;
+ struct hostap_getall reqall;
+ struct hostap_sta stabuf;
+#endif
switch (cmd) {
case SIOCSIFADDR:
@@ -1366,6 +1377,71 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
else
ifp->if_mtu = ifr->ifr_mtu;
break;
+#if defined(__OpenBSD__)
+ case SIOCHOSTAP_DEL:
+ if ((error = suser(curproc, 0)))
+ break;
+ if ((error = copyin(ifr->ifr_data, &stabuf, sizeof(stabuf))))
+ break;
+ ni = ieee80211_find_node(ic, stabuf.addr);
+ if (ni == NULL)
+ error = ENOENT;
+ else {
+ if (ni->ni_state == IEEE80211_STA_COLLECT)
+ break;
+
+ /* Disassociate station. */
+ if (ni->ni_state == IEEE80211_STA_ASSOC)
+ IEEE80211_SEND_MGMT(ic, ni,
+ IEEE80211_FC0_SUBTYPE_DISASSOC,
+ IEEE80211_REASON_ASSOC_LEAVE);
+
+ /* Deauth station. */
+ if (ni->ni_state >= IEEE80211_STA_AUTH)
+ IEEE80211_SEND_MGMT(ic, ni,
+ IEEE80211_FC0_SUBTYPE_DEAUTH,
+ IEEE80211_REASON_AUTH_LEAVE);
+
+ ieee80211_free_node(ic, ni);
+ }
+ break;
+ case SIOCHOSTAP_GET:
+ if ((error = copyin(ifr->ifr_data, &stabuf, sizeof(stabuf))))
+ break;
+ ni = ieee80211_find_node(ic, stabuf.addr);
+ if (ni == NULL)
+ error = ENOENT;
+ else {
+ node2sta(ic, ni, &stabuf);
+ error = copyout(&stabuf, ifr->ifr_data,
+ sizeof(stabuf));
+ }
+ break;
+ case SIOCHOSTAP_GETALL:
+ if ((error = copyin(ifr->ifr_data, &reqall, sizeof(reqall))))
+ break;
+
+ reqall.nstations = i = 0;
+ ni = TAILQ_FIRST(&ic->ic_node);
+ while(ni && reqall.size >= i + sizeof(struct hostap_sta)) {
+ node2sta(ic, ni, &stabuf);
+ error = copyout(&stabuf, (caddr_t) reqall.addr + i,
+ sizeof(struct hostap_sta));
+ if (error)
+ break;
+ i += sizeof(struct hostap_sta);
+ reqall.nstations++;
+ ni = TAILQ_NEXT(ni, ni_list);
+ }
+
+ if (!error)
+ error = copyout(&reqall, ifr->ifr_data,
+ sizeof(reqall));
+ break;
+ case SIOCHOSTAP_ADD:
+ case SIOCHOSTAP_GFLAGS:
+ case SIOCHOSTAP_SFLAGS:
+#endif
default:
error = EINVAL;
break;
@@ -1373,3 +1449,21 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
return error;
}
#endif /* !__FreeBSD__ */
+
+#if defined(__OpenBSD__)
+void
+node2sta(struct ieee80211com *ic, struct ieee80211_node *ni,
+ struct hostap_sta *sta)
+{
+ bcopy(ni->ni_macaddr, sta->addr, IEEE80211_ADDR_LEN);
+ sta->flags = 0;
+ if (ni->ni_state >= IEEE80211_STA_AUTH)
+ sta->flags |= HOSTAP_FLAGS_AUTHEN;
+ if (ni->ni_state >= IEEE80211_STA_ASSOC)
+ sta->flags |= HOSTAP_FLAGS_ASSOC;
+ sta->asid = ni->ni_associd;
+ sta->capinfo = ni->ni_capinfo;
+ sta->sig_info = (*ic->ic_node_getrssi)(ic, ni);
+ sta->rates = 0x00; /* not compatible */
+}
+#endif