This fixes ifconfig 'nwflags' hiddennwid and nobridge; these flags
currently overlap with other flags, such as the AUTO_JOIN flag and
hence can't be used.
While here, add another flag which makes the interface ignore deauth frames.
diff 63562686d340902505feb02c68d09c5d34652880 /usr/src
blob - adc7fa737fc2f734df37a6c286e0ff50ad36425c
file + sbin/ifconfig/ifconfig.8
--- sbin/ifconfig/ifconfig.8
+++ sbin/ifconfig/ifconfig.8
@@ -969,22 +969,32 @@ Show the list of currently configured auto-join networ
Remove all networks in the list of auto-join networks.
.It Cm nwflag Ar flag
Set specified flag.
-The flag name can be either
-.Ql hidenwid
-or
-.Ql nobridge .
+The flag name can be:
+.Bl -tag -width tenletters
+.It hidenwid
The
.Ql hidenwid
flag will hide the network ID (ESSID) in beacon frames when operating
in Host AP mode.
It will also prevent responses to probe requests with an unspecified
network ID.
+.It nobridge
The
.Ql nobridge
flag will disable the direct bridging of frames between associated
nodes when operating in Host AP mode.
Setting this flag will block and filter direct inter-station
communications.
+.It stayauth
+The
+.Ql stayauth
+flag will cause the interface to ignore deauth frames from the
+access point.
+This flag should only be used on wifi networks which are being
+attacked with spoofed deauth frames.
+It breaks interoperability with spectrum management solutions and access
+points that perform band-steering of clients.
+.El
.Pp
Note that the
.Ql hidenwid
diff 63562686d340902505feb02c68d09c5d34652880 /usr/src
blob - 1c863e788dca720c3666be6387d7ea812d7a937a
file + sys/net80211/ieee80211_input.c
--- sys/net80211/ieee80211_input.c
+++ sys/net80211/ieee80211_input.c
@@ -882,7 +882,7 @@ ieee80211_deliver_data(struct ieee80211com *ic, struct
m1 = NULL;
#ifndef IEEE80211_STA_ONLY
if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
- !(ic->ic_flags & IEEE80211_F_NOBRIDGE) &&
+ !(ic->ic_userflags & IEEE80211_F_NOBRIDGE) &&
eh->ether_type != htons(ETHERTYPE_PAE)) {
struct ieee80211_node *ni1;
@@ -2418,7 +2418,9 @@ ieee80211_recv_deauth(struct ieee80211com *ic, struct
case IEEE80211_M_STA: {
int bgscan = ((ic->ic_flags & IEEE80211_F_BGSCAN) &&
ic->ic_state == IEEE80211_S_RUN);
- if (!bgscan) /* ignore deauth during bgscan */
+ int stay_auth = ((ic->ic_userflags & IEEE80211_F_STAYAUTH) &&
+ ic->ic_state >= IEEE80211_S_AUTH);
+ if (!(bgscan || stay_auth))
ieee80211_new_state(ic, IEEE80211_S_AUTH,
IEEE80211_FC0_SUBTYPE_DEAUTH);
}
blob - f9a7edff8968924fb609ef7b829682fba923ac55
file + sys/net80211/ieee80211_ioctl.c
--- sys/net80211/ieee80211_ioctl.c
+++ sys/net80211/ieee80211_ioctl.c
@@ -903,17 +903,17 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t
}
break;
case SIOCG80211FLAGS:
- flags = ic->ic_flags;
+ flags = ic->ic_userflags;
#ifndef IEEE80211_STA_ONLY
if (ic->ic_opmode != IEEE80211_M_HOSTAP)
#endif
flags &= ~IEEE80211_F_HOSTAPMASK;
- ifr->ifr_flags = flags >> IEEE80211_F_USERSHIFT;
+ ifr->ifr_flags = flags;
break;
case SIOCS80211FLAGS:
if ((error = suser(curproc)) != 0)
break;
- flags = (u_int32_t)ifr->ifr_flags << IEEE80211_F_USERSHIFT;
+ flags = ifr->ifr_flags;
if (
#ifndef IEEE80211_STA_ONLY
ic->ic_opmode != IEEE80211_M_HOSTAP &&
@@ -922,7 +922,7 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t
error = EINVAL;
break;
}
- ic->ic_flags = (ic->ic_flags & ~IEEE80211_F_USERMASK) | flags;
+ ic->ic_userflags = flags;
error = ENETRESET;
break;
case SIOCADDMULTI:
blob - 69dbc52cbe8738b74669a4e85084512f8e0de5b3
file + sys/net80211/ieee80211_ioctl.h
--- sys/net80211/ieee80211_ioctl.h
+++ sys/net80211/ieee80211_ioctl.h
@@ -394,20 +394,21 @@ struct ieee80211_nodereq_all {
#define SIOCG80211ALLNODES _IOWR('i', 214, struct ieee80211_nodereq_all)
/* net80211 specific interface flags */
-#define IEEE80211_F_HIDENWID 0x10000000 /* CONF: hidden ssid mode */
-#define IEEE80211_F_NOBRIDGE 0x20000000 /* CONF: no internal bridging */
-#define IEEE80211_F_HOSTAPMASK 0x30000000
-#define IEEE80211_F_USERSHIFT 28
-#define IEEE80211_F_USERBITS "\20\01HIDENWID\02NOBRIDGE"
+#define IEEE80211_F_HIDENWID 0x00000001 /* CONF: hidden ssid mode */
+#define IEEE80211_F_NOBRIDGE 0x00000002 /* CONF: no internal bridging */
+#define IEEE80211_F_HOSTAPMASK 0x00000003
+#define IEEE80211_F_STAYAUTH 0x00000004 /* CONF: ignore deauth */
+#define IEEE80211_F_USERBITS "\20\01HIDENWID\02NOBRIDGE\03STAYAUTH"
struct ieee80211_flags {
const char *f_name;
u_int f_flag;
};
-#define IEEE80211_FLAGS {
\
- { "hidenwid", IEEE80211_F_HIDENWID >> IEEE80211_F_USERSHIFT }, \
- { "nobridge", IEEE80211_F_NOBRIDGE >> IEEE80211_F_USERSHIFT } \
+#define IEEE80211_FLAGS { \
+ { "hidenwid", IEEE80211_F_HIDENWID }, \
+ { "nobridge", IEEE80211_F_NOBRIDGE }, \
+ { "stayauth", IEEE80211_F_STAYAUTH } \
}
#define SIOCG80211FLAGS _IOWR('i', 216, struct ifreq)
blob - 2f6e0e77d2e3a668b04b12461bd690d34c8d8b92
file + sys/net80211/ieee80211_output.c
--- sys/net80211/ieee80211_output.c
+++ sys/net80211/ieee80211_output.c
@@ -1818,7 +1818,8 @@ ieee80211_beacon_alloc(struct ieee80211com *ic, struct
m = ieee80211_getmgmt(M_DONTWAIT, MT_DATA,
8 + 2 + 2 +
- 2 + ((ic->ic_flags & IEEE80211_F_HIDENWID) ? 0 : ni->ni_esslen) +
+ 2 + ((ic->ic_userflags & IEEE80211_F_HIDENWID) ?
+ 0 : ni->ni_esslen) +
2 + min(rs->rs_nrates, IEEE80211_RATE_SIZE) +
2 + 1 +
2 + ((ic->ic_opmode == IEEE80211_M_IBSS) ? 2 : 254) +
@@ -1853,7 +1854,7 @@ ieee80211_beacon_alloc(struct ieee80211com *ic, struct
memset(frm, 0, 8); frm += 8; /* timestamp is set by hardware */
LE_WRITE_2(frm, ni->ni_intval); frm += 2;
frm = ieee80211_add_capinfo(frm, ic, ni);
- if (ic->ic_flags & IEEE80211_F_HIDENWID)
+ if (ic->ic_userflags & IEEE80211_F_HIDENWID)
frm = ieee80211_add_ssid(frm, NULL, 0);
else
frm = ieee80211_add_ssid(frm, ni->ni_essid, ni->ni_esslen);
blob - eaf7649c4dbad2884d6adfde39c9fffb0a5b2d09
file + sys/net80211/ieee80211_var.h
--- sys/net80211/ieee80211_var.h
+++ sys/net80211/ieee80211_var.h
@@ -247,6 +247,7 @@ struct ieee80211com {
u_int8_t ic_scan_count; /* count scans */
u_int32_t ic_flags; /* state flags */
u_int32_t ic_xflags; /* more flags */
+ u_int32_t ic_userflags; /* yet more flags */
u_int32_t ic_caps; /* capabilities */
u_int16_t ic_modecaps; /* set of mode capabilities */
u_int16_t ic_curmode; /* current mode */
@@ -395,7 +396,6 @@ struct ieee80211_ess {
#define IEEE80211_F_BGSCAN 0x08000000 /* STATUS: background
scan */
#define IEEE80211_F_AUTO_JOIN 0x10000000 /* CONF: auto-join active */
#define IEEE80211_F_VHTON 0x20000000 /* CONF: VHT enabled */
-#define IEEE80211_F_USERMASK 0xc0000000 /* CONF: ioctl flag mask */
/* ic_xflags */
#define IEEE80211_F_TX_MGMT_ONLY 0x00000001 /* leave data frames on
ifq */
diff 63562686d340902505feb02c68d09c5d34652880 /usr/src
blob - 5451345b7673ff3ab88503eb534d054d796c6aad
file + sys/dev/ic/if_wi.c
--- sys/dev/ic/if_wi.c
+++ sys/dev/ic/if_wi.c
@@ -1963,8 +1963,7 @@ wi_ioctl(struct ifnet *ifp, u_long command, caddr_t da
}
sc->wi_enh_security = letoh16(wreq->wi_val[0]);
if (sc->wi_enh_security == WI_HIDESSID_IGNPROBES)
- ifr->ifr_flags |= IEEE80211_F_HIDENWID >>
- IEEE80211_F_USERSHIFT;
+ ifr->ifr_flags |= IEEE80211_F_HIDENWID;
}
break;
case SIOCS80211FLAGS:
@@ -1974,7 +1973,7 @@ wi_ioctl(struct ifnet *ifp, u_long command, caddr_t da
error = EINVAL;
break;
}
- flags = (u_int32_t)ifr->ifr_flags << IEEE80211_F_USERSHIFT;
+ flags = (u_int32_t)ifr->ifr_flags;
if (sc->wi_flags & WI_FLAGS_HAS_ENH_SECURITY) {
sc->wi_enh_security = (flags & IEEE80211_F_HIDENWID) ?
WI_HIDESSID_IGNPROBES : 0;