From b2cf04c73adc3d161d9cff1ba53de426864e6657 Mon Sep 17 00:00:00 2001 From: stsp Date: Sat, 1 Sep 2018 08:20:56 +0000 Subject: [PATCH] Make 'ifconfig nwid' override 'ifconfig join'. There was no way to override a decision made by join's network selection algorithm (apart from disabling the feature by clearing the join list). Automatic selection is based on heuristics which cannot always guess correctly so we need to provide an override. One specific problem was that if 'nwid foo' and 'nwid bar' were both visible in the scan and only 'nwid foo' was a member of the join list, then there was no way at all to connect to 'nwid bar'. The wireless stack would keep selecting 'nwid foo' instead. 'ifconfig iwm0 nwid bar' command will now disable automatic network selection and force the use of ESSID 'bar'. Any of these commands will re-enable automatic network selection: ifconfig iwm0 -nwid ifconfig iwm0 nwid '' ifconfig iwm0 join some-network-id ok phessler@ deraadt@ --- sys/net80211/ieee80211_ioctl.c | 18 ++++++++++++++---- sys/net80211/ieee80211_node.c | 16 +++++++++++++++- sys/net80211/ieee80211_var.h | 5 +++-- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c index 2ff4c10d267..f144979e3a7 100644 --- a/sys/net80211/ieee80211_ioctl.c +++ b/sys/net80211/ieee80211_ioctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_ioctl.c,v 1.63 2018/08/06 11:42:18 benno Exp $ */ +/* $OpenBSD: ieee80211_ioctl.c,v 1.64 2018/09/01 08:20:56 stsp Exp $ */ /* $NetBSD: ieee80211_ioctl.c,v 1.15 2004/05/06 02:58:16 dyoung Exp $ */ /*- @@ -429,6 +429,13 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) memset(ic->ic_des_essid, 0, IEEE80211_NWID_LEN); ic->ic_des_esslen = nwid.i_len; memcpy(ic->ic_des_essid, nwid.i_nwid, nwid.i_len); + if (ic->ic_des_esslen > 0) { + /* 'nwid' disables auto-join magic */ + ic->ic_flags &= ~IEEE80211_F_AUTO_JOIN; + } else { + /* '-nwid' re-enables auto-join */ + ic->ic_flags |= IEEE80211_F_AUTO_JOIN; + } /* disable WPA/WEP */ ieee80211_disable_rsn(ic); ieee80211_disable_wep(ic); @@ -467,8 +474,10 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) ieee80211_disable_rsn(ic); ieee80211_disable_wep(ic); /* save nwid for auto-join */ - if (!(join.i_flags & IEEE80211_JOIN_DEL)) - ieee80211_add_ess(ic, 0, 0); + if (!(join.i_flags & IEEE80211_JOIN_DEL)) { + if (ieee80211_add_ess(ic, 0, 0) == 0) + ic->ic_flags |= IEEE80211_F_AUTO_JOIN; + } ieee80211_set_ess(ic, ic->ic_des_essid); error = ENETRESET; break; @@ -483,7 +492,8 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) join.i_len = ic->ic_bss->ni_esslen; memcpy(join.i_nwid, ic->ic_bss->ni_essid, join.i_len); - join.i_flags = IEEE80211_JOIN_FOUND; + if (ic->ic_flags & IEEE80211_F_AUTO_JOIN) + join.i_flags = IEEE80211_JOIN_FOUND; error = copyout(&join, ifr->ifr_data, sizeof(join)); break; diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c index 191fcfc877e..718576bf336 100644 --- a/sys/net80211/ieee80211_node.c +++ b/sys/net80211/ieee80211_node.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_node.c,v 1.142 2018/08/15 18:45:43 stsp Exp $ */ +/* $OpenBSD: ieee80211_node.c,v 1.143 2018/09/01 08:20:56 stsp Exp $ */ /* $NetBSD: ieee80211_node.c,v 1.14 2004/05/09 09:18:47 dyoung Exp $ */ /*- @@ -485,6 +485,20 @@ ieee80211_switch_ess(struct ieee80211com *ic) if (ess == NULL) continue; + /* + * Operate only on ic_des_essid if auto-join is disabled. + * We might have a password stored for this network. + */ + if (!ISSET(ic->ic_flags, IEEE80211_F_AUTO_JOIN)) { + if (ic->ic_des_esslen == ess->esslen && + memcmp(ic->ic_des_essid, ess->essid, + ess->esslen) == 0) { + ieee80211_set_ess(ic, ess->essid); + return; + } + continue; + } + if (selni == NULL) { seless = ess; selni = ni; diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h index 406b1601106..c5a1bd3b14a 100644 --- a/sys/net80211/ieee80211_var.h +++ b/sys/net80211/ieee80211_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_var.h,v 1.87 2018/08/06 11:28:01 stsp Exp $ */ +/* $OpenBSD: ieee80211_var.h,v 1.88 2018/09/01 08:20:56 stsp Exp $ */ /* $NetBSD: ieee80211_var.h,v 1.7 2004/05/06 03:07:10 dyoung Exp $ */ /*- @@ -392,7 +392,8 @@ struct ieee80211_ess { #define IEEE80211_F_HTON 0x02000000 /* CONF: HT enabled */ #define IEEE80211_F_PBAR 0x04000000 /* CONF: PBAC required */ #define IEEE80211_F_BGSCAN 0x08000000 /* STATUS: background scan */ -#define IEEE80211_F_USERMASK 0xf0000000 /* CONF: ioctl flag mask */ +#define IEEE80211_F_AUTO_JOIN 0x10000000 /* CONF: auto-join active */ +#define IEEE80211_F_USERMASK 0xe0000000 /* CONF: ioctl flag mask */ /* ic_xflags */ #define IEEE80211_F_TX_MGMT_ONLY 0x00000001 /* leave data frames on ifq */ -- 2.20.1