Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src-draft/trunk]: src/sys/net80211 Implement missing ioctls, remove verbose ...



details:   https://anonhg.NetBSD.org/src-all/rev/36c80c283442
branches:  trunk
changeset: 949691:36c80c283442
user:      Martin Husemann <martin%NetBSD.org@localhost>
date:      Sat Dec 19 16:50:34 2020 +0100

description:
Implement missing ioctls, remove verbose logging.

diffstat:

 sys/net80211/ieee80211_ioctl.c |  126 +++++++++++++++++++++++++++++++++++++++-
 1 files changed, 120 insertions(+), 6 deletions(-)

diffs (159 lines):

diff -r 5888f2637f65 -r 36c80c283442 sys/net80211/ieee80211_ioctl.c
--- a/sys/net80211/ieee80211_ioctl.c    Sat Dec 19 16:31:04 2020 +0100
+++ b/sys/net80211/ieee80211_ioctl.c    Sat Dec 19 16:50:34 2020 +0100
@@ -3721,12 +3721,15 @@
 {
        struct ieee80211vap *vap = ifp->if_softc;
        struct ieee80211com *ic = vap->iv_ic;
-       int error = 0, wait = 0, ic_used;
+       int error = 0, wait = 0, ic_used, klen, kid, i;
+       uint32_t oflags;
        struct ifreq *ifr;
        struct ifaddr *ifa;                     /* XXX */
+       uint8_t tmpkey[IEEE80211_WEP_NKID][IEEE80211_KEYBUF_SIZE];
+       struct ieee80211_key *k;
 #if __NetBSD__
        struct ieee80211_nwid nwid;
-       //      struct ieee80211_nwkey *nwkey;
+       struct ieee80211_nwkey *nwkey;
        struct ieee80211_power *power;
        struct ieee80211chanreq *chanreq;
        struct ieee80211_bssid *bssid;
@@ -3941,10 +3944,120 @@
                error = copyout(&nwid, ifr->ifr_data, sizeof(nwid));
                break;
        case SIOCS80211NWKEY:
+               nwkey = (struct ieee80211_nwkey *)data;
+               /* transmit key index out of range? */
+               kid = nwkey->i_defkid - 1;
+               if (kid < 0 || kid >= IEEE80211_WEP_NKID) {
+                       error = EINVAL;
+                       break;
+               }
+               /* no such transmit key is set? */
+               if (nwkey->i_key[kid].i_keylen == 0 ||
+                   (nwkey->i_key[kid].i_keylen == -1 &&
+                    vap->iv_nw_keys[kid].wk_keylen == 0)) {
+                       if (nwkey->i_wepon != IEEE80211_NWKEY_OPEN) {
+                               error = EINVAL;
+                               break;
+                       }
+               }
+               /* check key lengths */
+               for (kid = 0; kid < IEEE80211_WEP_NKID; kid++) {
+                       klen = nwkey->i_key[kid].i_keylen;
+                       if ((klen > 0 &&
+                           klen < IEEE80211_WEP_KEYLEN) ||
+                           klen > sizeof(vap->iv_nw_keys[kid].wk_key)) {
+                               error = EINVAL;
+                               break;
+                       }
+               }
+
+               if (error)
+                       break;
+
+               /* copy in keys */
+               (void)memset(tmpkey, 0, sizeof(tmpkey));
+               for (kid = 0; kid < IEEE80211_WEP_NKID; kid++) {
+                       klen = nwkey->i_key[kid].i_keylen;
+                       if (klen <= 0)
+                               continue;
+                       if ((error = copyin(nwkey->i_key[kid].i_keydat,
+                           tmpkey[kid], klen)) != 0)
+                               break;
+               }
+
+               if (error)
+                       break;
+
+               /* set keys */
+               ieee80211_key_update_begin(vap);
+               for (kid = 0; kid < IEEE80211_WEP_NKID; kid++) {
+                       klen = nwkey->i_key[kid].i_keylen;
+                       if (klen <= 0)
+                               continue;
+                       k = &vap->iv_nw_keys[kid];
+                       k->wk_keyix = kid;
+                       if (!ieee80211_crypto_newkey(vap, IEEE80211_CIPHER_WEP,
+                           IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV, k)) {
+                               error = EINVAL;
+                               continue;
+                       }
+                       k->wk_keylen = nwkey->i_key[kid].i_keylen;
+                       (void)memcpy(k->wk_key, tmpkey[kid],
+                           sizeof(tmpkey[kid]));
+                       if (!ieee80211_crypto_setkey(vap, k))
+                               error = EINVAL;
+               }
+               ieee80211_key_update_end(vap);
+
+               if (error)
+                       break;
+
+               /* delete keys */
+               for (kid = 0; kid < IEEE80211_WEP_NKID; kid++) {
+                       klen = nwkey->i_key[kid].i_keylen;
+                       k = &vap->iv_nw_keys[kid];
+                       if (klen <= 0)
+                               (void)ieee80211_crypto_delkey(vap, k);
+               }
+
+               /* set transmit key */
+               kid = nwkey->i_defkid - 1;
+               if (vap->iv_def_txkey != kid) {
+                       vap->iv_def_txkey = kid;
+                       error = ENETRESET;
+               }
+               oflags = vap->iv_flags;
+               if (nwkey->i_wepon == IEEE80211_NWKEY_OPEN) {
+                       vap->iv_flags &= ~IEEE80211_F_PRIVACY;
+                       vap->iv_flags &= ~IEEE80211_F_DROPUNENC;
+               } else {
+                       vap->iv_flags |= IEEE80211_F_PRIVACY;
+                       vap->iv_flags |= IEEE80211_F_DROPUNENC;
+               }
+               if (oflags != vap->iv_flags)
+                       error = ENETRESET;
+               break;
        case SIOCG80211NWKEY:
-               printf ("NetBSD NWKEY ioctl\n"); // NNN
-               error = ENOTTY;
-               break;
+               nwkey = (struct ieee80211_nwkey *)data;
+               if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0)
+                       nwkey->i_wepon = IEEE80211_NWKEY_OPEN;
+               else if (vap->iv_flags & IEEE80211_F_DROPUNENC)
+                       nwkey->i_wepon = IEEE80211_NWKEY_WEP;
+               nwkey->i_defkid = vap->iv_def_txkey + 1;
+               for (i = 0; i < IEEE80211_WEP_NKID; i++) {
+                       if (nwkey->i_key[i].i_keydat == NULL)
+                               continue;
+                       /* do not show any keys to non-root user */
+                       if ((error = ieee80211_priv(PRIV_NET80211_GETKEY,
+                           vap, 0)) != 0)
+                               break;
+                       nwkey->i_key[i].i_keylen = vap->iv_nw_keys[i].wk_keylen;
+                       if ((error = copyout(vap->iv_nw_keys[i].wk_key,
+                           nwkey->i_key[i].i_keydat,
+                           vap->iv_nw_keys[i].wk_keylen)) != 0)
+                               break;
+               }
+               break;
        case SIOCS80211POWER:
                power = (struct ieee80211_power *)data;
                ic->ic_lintval = power->i_maxsleep;
@@ -4033,11 +4146,12 @@
                    (error = ic->ic_ioctl(ic, cmd, data)) != ENOTTY)
                        break;
                error = ether_ioctl(ifp, cmd, data);
+#if 0
                if (error == ENOTTY) {
                        printf ("ieee80211_ioctl: cmd is 0x%lx. ('%c', %ld)\n",
                                cmd, (char) ((cmd>>8) & 0xff), cmd & 0xff );
-                       printf ("Unknown 802.11 IOCTL.\n"); /* NNN */
                }
+#endif
                break;
        }
 



Home | Main Index | Thread Index | Old Index