summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authoronoe <onoe@NetBSD.org>2000-07-21 04:48:55 +0000
committeronoe <onoe@NetBSD.org>2000-07-21 04:48:55 +0000
commitafa5b645c2e987aaa4b0068381ae39afcf3f98dc (patch)
tree6934962e23da90a76784729dd16ed4c4df46702b /sys/dev
parentf4aa4a560c09d45570a36f75ba851c61e9d2949a (diff)
add support for SIOCS80211NWKEY and SIOCG80211NWKEY.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ic/awi.c8
-rw-r--r--sys/dev/ic/awi_wep.c80
-rw-r--r--sys/dev/ic/awivar.h4
-rw-r--r--sys/dev/pcmcia/if_wi.c110
4 files changed, 198 insertions, 4 deletions
diff --git a/sys/dev/ic/awi.c b/sys/dev/ic/awi.c
index 84d8c9b893d..aa395f0dbef 100644
--- a/sys/dev/ic/awi.c
+++ b/sys/dev/ic/awi.c
@@ -1,4 +1,4 @@
-/* $NetBSD: awi.c,v 1.25 2000/07/19 06:00:40 onoe Exp $ */
+/* $NetBSD: awi.c,v 1.26 2000/07/21 04:48:55 onoe Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -548,6 +548,12 @@ awi_ioctl(ifp, cmd, data)
p = sc->sc_mib_mac.aDesired_ESS_ID;
error = copyout(p + 1, ifr->ifr_data, 1 + IEEE80211_NWID_LEN);
break;
+ case SIOCS80211NWKEY:
+ error = awi_wep_setnwkey(sc, (struct ieee80211_nwkey *)data);
+ break;
+ case SIOCG80211NWKEY:
+ error = awi_wep_getnwkey(sc, (struct ieee80211_nwkey *)data);
+ break;
#ifdef IFM_IEEE80211
case SIOCSIFMEDIA:
case SIOCGIFMEDIA:
diff --git a/sys/dev/ic/awi_wep.c b/sys/dev/ic/awi_wep.c
index 151b36c1290..9cff8a04622 100644
--- a/sys/dev/ic/awi_wep.c
+++ b/sys/dev/ic/awi_wep.c
@@ -1,4 +1,4 @@
-/* $NetBSD: awi_wep.c,v 1.2 2000/07/04 14:47:58 onoe Exp $ */
+/* $NetBSD: awi_wep.c,v 1.3 2000/07/21 04:48:56 onoe Exp $ */
/*
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -140,6 +140,84 @@ static struct awi_wep_algo awi_wep_algo[] = {
};
int
+awi_wep_setnwkey(sc, nwkey)
+ struct awi_softc *sc;
+ struct ieee80211_nwkey *nwkey;
+{
+ int i, len, error;
+ u_int8_t keybuf[AWI_MAX_KEYLEN];
+
+ if (nwkey->i_defkid <= 0 ||
+ nwkey->i_defkid > IEEE80211_WEP_NKID)
+ return EINVAL;
+ error = 0;
+ for (i = 0; i < IEEE80211_WEP_NKID; i++) {
+ if (nwkey->i_key[i].i_keydat == NULL)
+ continue;
+ len = nwkey->i_key[i].i_keylen;
+ if (len > sizeof(keybuf)) {
+ error = EINVAL;
+ break;
+ }
+ error = copyin(nwkey->i_key[i].i_keydat, keybuf, len);
+ if (error)
+ break;
+ error = awi_wep_setkey(sc, i, keybuf, len);
+ if (error)
+ break;
+ }
+ if (error == 0) {
+ sc->sc_wep_defkid = nwkey->i_defkid - 1;
+ error = awi_wep_setalgo(sc, nwkey->i_wepon);
+ if (error == 0 && sc->sc_enabled) {
+ awi_stop(sc);
+ error = awi_init(sc);
+ }
+ }
+ return error;
+}
+
+int
+awi_wep_getnwkey(sc, nwkey)
+ struct awi_softc *sc;
+ struct ieee80211_nwkey *nwkey;
+{
+ int i, len, error, suerr;
+ u_int8_t keybuf[AWI_MAX_KEYLEN];
+
+ nwkey->i_wepon = awi_wep_getalgo(sc);
+ nwkey->i_defkid = sc->sc_wep_defkid + 1;
+ /* do not show any keys to non-root user */
+#ifdef __FreeBSD__
+ suerr = suser(curproc);
+#else
+ suerr = suser(curproc->p_ucred, &curproc->p_acflag);
+#endif
+ error = 0;
+ for (i = 0; i < IEEE80211_WEP_NKID; i++) {
+ if (nwkey->i_key[i].i_keydat == NULL)
+ continue;
+ if (suerr) {
+ error = suerr;
+ break;
+ }
+ len = sizeof(keybuf);
+ error = awi_wep_getkey(sc, i, keybuf, &len);
+ if (error)
+ break;
+ if (nwkey->i_key[i].i_keylen < len) {
+ error = ENOSPC;
+ break;
+ }
+ nwkey->i_key[i].i_keylen = len;
+ error = copyout(keybuf, nwkey->i_key[i].i_keydat, len);
+ if (error)
+ break;
+ }
+ return error;
+}
+
+int
awi_wep_getalgo(sc)
struct awi_softc *sc;
{
diff --git a/sys/dev/ic/awivar.h b/sys/dev/ic/awivar.h
index 3ae1d3a1edd..517728a60b3 100644
--- a/sys/dev/ic/awivar.h
+++ b/sys/dev/ic/awivar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: awivar.h,v 1.11 2000/07/04 14:27:57 onoe Exp $ */
+/* $NetBSD: awivar.h,v 1.12 2000/07/21 04:48:56 onoe Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -212,6 +212,8 @@ int awi_init __P((struct awi_softc *sc));
int awi_init_region __P((struct awi_softc *));
int awi_wicfg __P((struct ifnet *, u_long, caddr_t));
+int awi_wep_setnwkey __P((struct awi_softc *, struct ieee80211_nwkey *));
+int awi_wep_getnwkey __P((struct awi_softc *, struct ieee80211_nwkey *));
int awi_wep_getalgo __P((struct awi_softc *));
int awi_wep_setalgo __P((struct awi_softc *, int));
int awi_wep_setkey __P((struct awi_softc *, int, unsigned char *, int));
diff --git a/sys/dev/pcmcia/if_wi.c b/sys/dev/pcmcia/if_wi.c
index ab4838dcd0d..38b00feb675 100644
--- a/sys/dev/pcmcia/if_wi.c
+++ b/sys/dev/pcmcia/if_wi.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wi.c,v 1.25 2000/07/18 15:01:55 onoe Exp $ */
+/* $NetBSD: if_wi.c,v 1.26 2000/07/21 04:48:57 onoe Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@@ -169,6 +169,8 @@ static void wi_request_fill_ssid __P((struct wi_req *,
struct ieee80211_nwid *));
static int wi_write_ssid __P((struct wi_softc *, int, struct wi_req *,
struct ieee80211_nwid *));
+static int wi_set_nwkey __P((struct wi_softc *, struct ieee80211_nwkey *));
+static int wi_get_nwkey __P((struct wi_softc *, struct ieee80211_nwkey *));
struct cfattach wi_ca = {
sizeof(struct wi_softc), wi_match, wi_attach, wi_detach, wi_activate
@@ -1459,6 +1461,12 @@ static int wi_ioctl(ifp, command, data)
/* Reinitialize WaveLAN. */
wi_init(sc);
break;
+ case SIOCS80211NWKEY:
+ error = wi_set_nwkey(sc, (struct ieee80211_nwkey *)data);
+ break;
+ case SIOCG80211NWKEY:
+ error = wi_get_nwkey(sc, (struct ieee80211_nwkey *)data);
+ break;
default:
error = EINVAL;
break;
@@ -1883,3 +1891,103 @@ wi_media_status(ifp, imr)
imr->ifm_active = sc->sc_media.ifm_cur->ifm_media;
imr->ifm_status = IFM_AVALID|IFM_ACTIVE;
}
+
+static int
+wi_set_nwkey(sc, nwkey)
+ struct wi_softc *sc;
+ struct ieee80211_nwkey *nwkey;
+{
+ int i, len, error;
+ struct wi_req wreq;
+ struct wi_ltv_keys *wk = (struct wi_ltv_keys *)&wreq;
+
+ if (!sc->wi_has_wep)
+ return ENODEV;
+ if (nwkey->i_defkid <= 0 ||
+ nwkey->i_defkid > IEEE80211_WEP_NKID)
+ return EINVAL;
+ memcpy(wk, &sc->wi_keys, sizeof(*wk));
+ for (i = 0; i < IEEE80211_WEP_NKID; i++) {
+ if (nwkey->i_key[i].i_keydat == NULL)
+ continue;
+ len = nwkey->i_key[i].i_keylen;
+ if (len > sizeof(wk->wi_keys[i].wi_keydat))
+ return EINVAL;
+ error = copyin(nwkey->i_key[i].i_keydat,
+ wk->wi_keys[i].wi_keydat, len);
+ if (error)
+ return error;
+ wk->wi_keys[i].wi_keylen = len;
+ }
+
+ wk->wi_len = (sizeof(*wk) / 2) + 1;
+ wk->wi_type = WI_RID_DEFLT_CRYPT_KEYS;
+ if (sc->sc_enabled != 0) {
+ error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq);
+ if (error)
+ return error;
+ }
+ error = wi_setdef(sc, &wreq);
+ if (error)
+ return error;
+
+ wreq.wi_len = 2;
+ wreq.wi_type = WI_RID_TX_CRYPT_KEY;
+ wreq.wi_val[0] = nwkey->i_defkid - 1;
+ if (sc->sc_enabled != 0) {
+ error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq);
+ if (error)
+ return error;
+ }
+ error = wi_setdef(sc, &wreq);
+ if (error)
+ return error;
+
+ wreq.wi_type = WI_RID_ENCRYPTION;
+ wreq.wi_val[0] = nwkey->i_wepon;
+ if (sc->sc_enabled != 0) {
+ error = wi_write_record(sc, (struct wi_ltv_gen *)&wreq);
+ if (error)
+ return error;
+ }
+ error = wi_setdef(sc, &wreq);
+ if (error)
+ return error;
+
+ if (sc->sc_enabled != 0)
+ wi_init(sc);
+ return 0;
+}
+
+static int
+wi_get_nwkey(sc, nwkey)
+ struct wi_softc *sc;
+ struct ieee80211_nwkey *nwkey;
+{
+ int i, len, error;
+ struct wi_ltv_keys *wk = &sc->wi_keys;
+
+ if (!sc->wi_has_wep)
+ return ENODEV;
+ nwkey->i_wepon = sc->wi_use_wep;
+ nwkey->i_defkid = sc->wi_tx_key + 1;
+
+ /* do not show any keys to non-root user */
+ error = suser(curproc->p_ucred, &curproc->p_acflag);
+ for (i = 0; i < IEEE80211_WEP_NKID; i++) {
+ if (nwkey->i_key[i].i_keydat == NULL)
+ continue;
+ /* error holds results of suser() for the first time */
+ if (error)
+ return error;
+ len = wk->wi_keys[i].wi_keylen;
+ if (nwkey->i_key[i].i_keylen < len)
+ return ENOSPC;
+ nwkey->i_key[i].i_keylen = len;
+ error = copyout(wk->wi_keys[i].wi_keydat,
+ nwkey->i_key[i].i_keydat, len);
+ if (error)
+ return error;
+ }
+ return 0;
+}