On Sat, Mar 11, 2017 at 09:55:15AM +0900, Stefan Sperling wrote:
> While a wifi interface is configured to use WEP 'ifconfig scan' will
> mistakenly show all WPA APs as WEP ones. Fix below.
> 
> This is a small ABI change in struct ieee80211_nodereq.

My diff has been committed but tb@ noticed that it does not actually
work in all cases.

This diff tries to introduce a clear distinction between what is supported
and what is enabled. 'ifconfig scan' now only shows what is supported.
I hope this is more clear and correct.

Index: ieee80211_input.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_input.c,v
retrieving revision 1.187
diff -u -p -r1.187 ieee80211_input.c
--- ieee80211_input.c   1 Mar 2017 19:28:48 -0000       1.187
+++ ieee80211_input.c   12 Mar 2017 00:48:02 -0000
@@ -1654,35 +1654,57 @@ ieee80211_recv_probe_resp(struct ieee802
            && ic->ic_opmode != IEEE80211_M_HOSTAP
 #endif
           ) {
-               struct ieee80211_rsnparams rsn;
-               const u_int8_t *saveie = NULL;
+               struct ieee80211_rsnparams rsn, wpa;
+
+               ni->ni_rsnprotos = IEEE80211_PROTO_NONE;
+               ni->ni_supported_rsnprotos = IEEE80211_PROTO_NONE;
+               ni->ni_rsnakms = 0;
+               ni->ni_supported_rsnakms = 0;
+               ni->ni_rsnciphers = 0;
+               ni->ni_rsngroupcipher = 0;
+               ni->ni_rsngroupmgmtcipher = 0;
+               ni->ni_rsncaps = 0;
+
+               if (rsnie != NULL &&
+                   ieee80211_parse_rsn(ic, rsnie, &rsn) == 0) {
+                       ni->ni_supported_rsnprotos |= IEEE80211_PROTO_RSN;
+                       ni->ni_supported_rsnakms |= rsn.rsn_akms;
+               }
+               if (wpaie != NULL &&
+                   ieee80211_parse_wpa(ic, wpaie, &wpa) == 0) {
+                       ni->ni_supported_rsnprotos |= IEEE80211_PROTO_WPA;
+                       ni->ni_supported_rsnakms |= wpa.rsn_akms;
+               }
+
                /*
-                * If the AP advertises both RSN and WPA IEs (WPA1+WPA2),
-                * we only store the parameters of the highest protocol
-                * version we support.
+                * If the AP advertises both WPA and RSN IEs (WPA1+WPA2),
+                * we only use the highest protocol version we support.
                 */
                if (rsnie != NULL &&
+                   (ni->ni_supported_rsnprotos & IEEE80211_PROTO_RSN) &&
                    (ic->ic_rsnprotos & IEEE80211_PROTO_RSN)) {
-                       if (ieee80211_parse_rsn(ic, rsnie, &rsn) == 0) {
+                       if (ieee80211_save_ie(rsnie, &ni->ni_rsnie) == 0) {
                                ni->ni_rsnprotos = IEEE80211_PROTO_RSN;
-                               saveie = rsnie;
+                               ni->ni_rsnakms = rsn.rsn_akms;
+                               ni->ni_rsnciphers = rsn.rsn_ciphers;
+                               ni->ni_rsngroupcipher = rsn.rsn_groupcipher;
+                               ni->ni_rsngroupmgmtcipher =
+                                   rsn.rsn_groupmgmtcipher;
+                               ni->ni_rsncaps = rsn.rsn_caps;
                        }
                } else if (wpaie != NULL &&
+                   (ni->ni_supported_rsnprotos & IEEE80211_PROTO_WPA) &&
                    (ic->ic_rsnprotos & IEEE80211_PROTO_WPA)) {
-                       if (ieee80211_parse_wpa(ic, wpaie, &rsn) == 0) {
+                       if (ieee80211_save_ie(wpaie, &ni->ni_rsnie) == 0) {
                                ni->ni_rsnprotos = IEEE80211_PROTO_WPA;
-                               saveie = wpaie;
+                               ni->ni_rsnakms = wpa.rsn_akms;
+                               ni->ni_rsnciphers = wpa.rsn_ciphers;
+                               ni->ni_rsngroupcipher = wpa.rsn_groupcipher;
+                               ni->ni_rsngroupmgmtcipher =
+                                   wpa.rsn_groupmgmtcipher;
+                               ni->ni_rsncaps = wpa.rsn_caps;
                        }
                }
-               if (saveie != NULL &&
-                   ieee80211_save_ie(saveie, &ni->ni_rsnie) == 0) {
-                       ni->ni_rsnakms = rsn.rsn_akms;
-                       ni->ni_rsnciphers = rsn.rsn_ciphers;
-                       ni->ni_rsngroupcipher = rsn.rsn_groupcipher;
-                       ni->ni_rsngroupmgmtcipher = rsn.rsn_groupmgmtcipher;
-                       ni->ni_rsncaps = rsn.rsn_caps;
-               } else
-                       ni->ni_rsnprotos = IEEE80211_PROTO_NONE;
        }
 
        if (ssid[1] != 0 && ni->ni_esslen == 0) {
@@ -2018,6 +2040,15 @@ ieee80211_recv_assoc_req(struct ieee8021
                goto end;
        }
 
+       ni->ni_rsnprotos = IEEE80211_PROTO_NONE;
+       ni->ni_supported_rsnprotos = IEEE80211_PROTO_NONE;
+       ni->ni_rsnakms = 0;
+       ni->ni_supported_rsnakms = 0;
+       ni->ni_rsnciphers = 0;
+       ni->ni_rsngroupcipher = 0;
+       ni->ni_rsngroupmgmtcipher = 0;
+       ni->ni_rsncaps = 0;
+
        if (ic->ic_flags & IEEE80211_F_RSNON) {
                const u_int8_t *saveie;
                /*
@@ -2032,6 +2063,7 @@ ieee80211_recv_assoc_req(struct ieee8021
                        if (status != 0)
                                goto end;
                        ni->ni_rsnprotos = IEEE80211_PROTO_RSN;
+                       ni->ni_supported_rsnprotos = IEEE80211_PROTO_RSN;
                        saveie = rsnie;
                } else if (wpaie != NULL &&
                    (ic->ic_rsnprotos & IEEE80211_PROTO_WPA)) {
@@ -2039,6 +2071,7 @@ ieee80211_recv_assoc_req(struct ieee8021
                        if (status != 0)
                                goto end;
                        ni->ni_rsnprotos = IEEE80211_PROTO_WPA;
+                       ni->ni_supported_rsnprotos = IEEE80211_PROTO_WPA;
                        saveie = wpaie;
                } else {
                        /*
@@ -2112,6 +2145,7 @@ ieee80211_recv_assoc_req(struct ieee8021
                        goto end;
                }
                ni->ni_rsnakms = rsn.rsn_akms;
+               ni->ni_supported_rsnakms = rsn.rsn_akms;
                ni->ni_rsnciphers = rsn.rsn_ciphers;
                ni->ni_rsngroupcipher = ic->ic_bss->ni_rsngroupcipher;
                ni->ni_rsngroupmgmtcipher = ic->ic_bss->ni_rsngroupmgmtcipher;
@@ -2138,8 +2172,7 @@ ieee80211_recv_assoc_req(struct ieee8021
                                ni->ni_flags |= IEEE80211_NODE_PMK;
                        }
                }
-       } else
-               ni->ni_rsnprotos = IEEE80211_PROTO_NONE;
+       }
 
        ni->ni_rssi = rxi->rxi_rssi;
        ni->ni_rstamp = rxi->rxi_tstamp;
Index: ieee80211_ioctl.c
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_ioctl.c,v
retrieving revision 1.49
diff -u -p -r1.49 ieee80211_ioctl.c
--- ieee80211_ioctl.c   11 Mar 2017 13:22:36 -0000      1.49
+++ ieee80211_ioctl.c   12 Mar 2017 01:04:01 -0000
@@ -108,17 +108,17 @@ ieee80211_node2req(struct ieee80211com *
        nr->nr_rsnciphers = ni->ni_rsnciphers;
        nr->nr_rsnakms = 0;
        nr->nr_rsnprotos = 0;
-       if (ni->ni_rsnprotos & IEEE80211_PROTO_WPA)
-               nr->nr_rsnprotos |= IEEE80211_WPA_PROTO_WPA1;
-       if (ni->ni_rsnprotos & IEEE80211_PROTO_RSN)
+       if (ni->ni_supported_rsnprotos & IEEE80211_PROTO_RSN)
                nr->nr_rsnprotos |= IEEE80211_WPA_PROTO_WPA2;
-       if (ni->ni_rsnakms & IEEE80211_AKM_8021X)
+       if (ni->ni_supported_rsnprotos & IEEE80211_PROTO_WPA)
+               nr->nr_rsnprotos |= IEEE80211_WPA_PROTO_WPA1;
+       if (ni->ni_supported_rsnakms & IEEE80211_AKM_8021X)
                nr->nr_rsnakms |= IEEE80211_WPA_AKM_8021X;
-       if (ni->ni_rsnakms & IEEE80211_AKM_PSK)
+       if (ni->ni_supported_rsnakms & IEEE80211_AKM_PSK)
                nr->nr_rsnakms |= IEEE80211_WPA_AKM_PSK;
-       if (ni->ni_rsnakms & IEEE80211_AKM_SHA256_8021X)
+       if (ni->ni_supported_rsnakms & IEEE80211_AKM_SHA256_8021X)
                nr->nr_rsnakms |= IEEE80211_WPA_AKM_SHA256_8021X;
-       if (ni->ni_rsnakms & IEEE80211_AKM_SHA256_PSK)
+       if (ni->ni_supported_rsnakms & IEEE80211_AKM_SHA256_PSK)
                nr->nr_rsnakms |= IEEE80211_WPA_AKM_SHA256_PSK;
 
        /* Node flags */
Index: ieee80211_node.h
===================================================================
RCS file: /cvs/src/sys/net80211/ieee80211_node.h,v
retrieving revision 1.67
diff -u -p -r1.67 ieee80211_node.h
--- ieee80211_node.h    4 Mar 2017 12:44:27 -0000       1.67
+++ ieee80211_node.h    12 Mar 2017 00:31:47 -0000
@@ -219,7 +219,9 @@ struct ieee80211_node {
        u_int                   ni_rsn_supp_state;
        u_int                   ni_rsn_gstate;
        u_int                   ni_rsn_retries;
+       u_int                   ni_supported_rsnprotos;
        u_int                   ni_rsnprotos;
+       u_int                   ni_supported_rsnakms;
        u_int                   ni_rsnakms;
        u_int                   ni_rsnciphers;
        enum ieee80211_cipher   ni_rsngroupcipher;

Reply via email to