diff options
| author | onoe <onoe@NetBSD.org> | 2000-07-21 04:48:55 +0000 |
|---|---|---|
| committer | onoe <onoe@NetBSD.org> | 2000-07-21 04:48:55 +0000 |
| commit | afa5b645c2e987aaa4b0068381ae39afcf3f98dc (patch) | |
| tree | 6934962e23da90a76784729dd16ed4c4df46702b /sys/dev | |
| parent | f4aa4a560c09d45570a36f75ba851c61e9d2949a (diff) | |
add support for SIOCS80211NWKEY and SIOCG80211NWKEY.
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/ic/awi.c | 8 | ||||
| -rw-r--r-- | sys/dev/ic/awi_wep.c | 80 | ||||
| -rw-r--r-- | sys/dev/ic/awivar.h | 4 | ||||
| -rw-r--r-- | sys/dev/pcmcia/if_wi.c | 110 |
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; +} |
