summaryrefslogtreecommitdiffstats
path: root/sys/net80211
diff options
context:
space:
mode:
authorbschmidt <bschmidt@FreeBSD.org>2011-02-22 19:05:42 +0000
committerbschmidt <bschmidt@FreeBSD.org>2011-02-22 19:05:42 +0000
commitf2afad1aeaf2ee3687e30ab2b584a8bd7a731ddf (patch)
tree1e94b233eb819904ead53a1e753f5883f71d1706 /sys/net80211
parent847bf79423da130be27e1335cb954bbc52471065 (diff)
downloadFreeBSD-src-f2afad1aeaf2ee3687e30ab2b584a8bd7a731ddf.zip
FreeBSD-src-f2afad1aeaf2ee3687e30ab2b584a8bd7a731ddf.tar.gz
Make sure to only accept and handle action frames which are for us. In
promiscuous mode we might receive stuff which otherwise gets filtered by hardware.
Diffstat (limited to 'sys/net80211')
-rw-r--r--sys/net80211/ieee80211_adhoc.c17
-rw-r--r--sys/net80211/ieee80211_hostap.c17
-rw-r--r--sys/net80211/ieee80211_mesh.c28
-rw-r--r--sys/net80211/ieee80211_sta.c13
-rw-r--r--sys/net80211/ieee80211_wds.c28
5 files changed, 58 insertions, 45 deletions
diff --git a/sys/net80211/ieee80211_adhoc.c b/sys/net80211/ieee80211_adhoc.c
index 9950505..35bc345 100644
--- a/sys/net80211/ieee80211_adhoc.c
+++ b/sys/net80211/ieee80211_adhoc.c
@@ -825,14 +825,23 @@ adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
case IEEE80211_FC0_SUBTYPE_ACTION:
case IEEE80211_FC0_SUBTYPE_ACTION_NOACK:
- if (vap->iv_state == IEEE80211_S_RUN) {
- if (ieee80211_parse_action(ni, m0) == 0)
- (void)ic->ic_recv_action(ni, wh, frm, efrm);
- } else {
+ if (ni == vap->iv_bss) {
+ IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
+ wh, NULL, "%s", "unknown node");
+ vap->iv_stats.is_rx_mgtdiscard++;
+ } else if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr1) &&
+ !IEEE80211_IS_MULTICAST(wh->i_addr1)) {
+ IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
+ wh, NULL, "%s", "not for us");
+ vap->iv_stats.is_rx_mgtdiscard++;
+ } else if (vap->iv_state != IEEE80211_S_RUN) {
IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
wh, NULL, "wrong state %s",
ieee80211_state_name[vap->iv_state]);
vap->iv_stats.is_rx_mgtdiscard++;
+ } else {
+ if (ieee80211_parse_action(ni, m0) == 0)
+ (void)ic->ic_recv_action(ni, wh, frm, efrm);
}
break;
diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c
index 861ff08..e3e1492 100644
--- a/sys/net80211/ieee80211_hostap.c
+++ b/sys/net80211/ieee80211_hostap.c
@@ -2195,14 +2195,23 @@ hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
case IEEE80211_FC0_SUBTYPE_ACTION:
case IEEE80211_FC0_SUBTYPE_ACTION_NOACK:
- if (vap->iv_state == IEEE80211_S_RUN) {
- if (ieee80211_parse_action(ni, m0) == 0)
- (void)ic->ic_recv_action(ni, wh, frm, efrm);
- } else {
+ if (ni == vap->iv_bss) {
+ IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
+ wh, NULL, "%s", "unknown node");
+ vap->iv_stats.is_rx_mgtdiscard++;
+ } else if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr1) &&
+ !IEEE80211_IS_MULTICAST(wh->i_addr1)) {
+ IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
+ wh, NULL, "%s", "not for us");
+ vap->iv_stats.is_rx_mgtdiscard++;
+ } else if (vap->iv_state != IEEE80211_S_RUN) {
IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
wh, NULL, "wrong state %s",
ieee80211_state_name[vap->iv_state]);
vap->iv_stats.is_rx_mgtdiscard++;
+ } else {
+ if (ieee80211_parse_action(ni, m0) == 0)
+ (void)ic->ic_recv_action(ni, wh, frm, efrm);
}
break;
diff --git a/sys/net80211/ieee80211_mesh.c b/sys/net80211/ieee80211_mesh.c
index 2559dc0..4cf2aac 100644
--- a/sys/net80211/ieee80211_mesh.c
+++ b/sys/net80211/ieee80211_mesh.c
@@ -1492,35 +1492,23 @@ mesh_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype,
case IEEE80211_FC0_SUBTYPE_ACTION:
case IEEE80211_FC0_SUBTYPE_ACTION_NOACK:
- /*
- * We received an action for an unknown neighbor.
- * XXX: wait for it to beacon or create ieee80211_node?
- */
if (ni == vap->iv_bss) {
- IEEE80211_DISCARD(vap, IEEE80211_MSG_MESH,
+ IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
wh, NULL, "%s", "unknown node");
vap->iv_stats.is_rx_mgtdiscard++;
- break;
- }
- /*
- * Discard if not for us.
- * XXX: if from us too?
- */
- if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr1) &&
+ } else if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr1) &&
!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- IEEE80211_DISCARD(vap, IEEE80211_MSG_MESH,
- wh, NULL, "%s", "not for me");
+ IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
+ wh, NULL, "%s", "not for us");
vap->iv_stats.is_rx_mgtdiscard++;
- break;
- }
- if (vap->iv_state == IEEE80211_S_RUN) {
- if (ieee80211_parse_action(ni, m0) == 0)
- (void)ic->ic_recv_action(ni, wh, frm, efrm);
- } else {
+ } else if (vap->iv_state != IEEE80211_S_RUN) {
IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
wh, NULL, "wrong state %s",
ieee80211_state_name[vap->iv_state]);
vap->iv_stats.is_rx_mgtdiscard++;
+ } else {
+ if (ieee80211_parse_action(ni, m0) == 0)
+ (void)ic->ic_recv_action(ni, wh, frm, efrm);
}
break;
diff --git a/sys/net80211/ieee80211_sta.c b/sys/net80211/ieee80211_sta.c
index bbfb36ef..0a5d7db 100644
--- a/sys/net80211/ieee80211_sta.c
+++ b/sys/net80211/ieee80211_sta.c
@@ -1719,14 +1719,19 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
case IEEE80211_FC0_SUBTYPE_ACTION:
case IEEE80211_FC0_SUBTYPE_ACTION_NOACK:
- if (vap->iv_state == IEEE80211_S_RUN) {
- if (ieee80211_parse_action(ni, m0) == 0)
- (void)ic->ic_recv_action(ni, wh, frm, efrm);
- } else {
+ if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr1) &&
+ !IEEE80211_IS_MULTICAST(wh->i_addr1)) {
+ IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
+ wh, NULL, "%s", "not for us");
+ vap->iv_stats.is_rx_mgtdiscard++;
+ } else if (vap->iv_state != IEEE80211_S_RUN) {
IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
wh, NULL, "wrong state %s",
ieee80211_state_name[vap->iv_state]);
vap->iv_stats.is_rx_mgtdiscard++;
+ } else {
+ if (ieee80211_parse_action(ni, m0) == 0)
+ (void)ic->ic_recv_action(ni, wh, frm, efrm);
}
break;
diff --git a/sys/net80211/ieee80211_wds.c b/sys/net80211/ieee80211_wds.c
index 23de423..926ef57 100644
--- a/sys/net80211/ieee80211_wds.c
+++ b/sys/net80211/ieee80211_wds.c
@@ -454,6 +454,9 @@ wds_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
*/
wh = mtod(m, struct ieee80211_frame *);
+ if (!IEEE80211_IS_MULTICAST(wh->i_addr1))
+ ni->ni_inact = ni->ni_inact_reload;
+
if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) !=
IEEE80211_FC0_VERSION_0) {
IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
@@ -536,8 +539,6 @@ wds_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
vap->iv_stats.is_rx_wrongdir++;/*XXX*/
goto out;
}
- if (!IEEE80211_IS_MULTICAST(wh->i_addr1))
- ni->ni_inact = ni->ni_inact_reload;
/*
* Handle A-MPDU re-ordering. If the frame is to be
* processed directly then ieee80211_ampdu_reorder
@@ -758,22 +759,23 @@ wds_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
switch (subtype) {
case IEEE80211_FC0_SUBTYPE_ACTION:
case IEEE80211_FC0_SUBTYPE_ACTION_NOACK:
- if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- IEEE80211_DISCARD(vap, IEEE80211_MSG_MESH,
- wh, NULL, "%s", "not directed to us");
+ if (ni == vap->iv_bss) {
+ IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
+ wh, NULL, "%s", "unknown node");
vap->iv_stats.is_rx_mgtdiscard++;
- break;
- } else
- ni->ni_inact = ni->ni_inact_reload;
-
- if (vap->iv_state == IEEE80211_S_RUN) {
- if (ieee80211_parse_action(ni, m0) == 0)
- (void)ic->ic_recv_action(ni, wh, frm, efrm);
- } else {
+ } else if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr1)) {
+ /* NB: not interested in multicast frames. */
+ IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
+ wh, NULL, "%s", "not for us");
+ vap->iv_stats.is_rx_mgtdiscard++;
+ } else if (vap->iv_state != IEEE80211_S_RUN) {
IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
wh, NULL, "wrong state %s",
ieee80211_state_name[vap->iv_state]);
vap->iv_stats.is_rx_mgtdiscard++;
+ } else {
+ if (ieee80211_parse_action(ni, m0) == 0)
+ (void)ic->ic_recv_action(ni, wh, frm, efrm);
}
break;
OpenPOWER on IntegriCloud