diff options
author | bschmidt <bschmidt@FreeBSD.org> | 2011-02-22 19:05:42 +0000 |
---|---|---|
committer | bschmidt <bschmidt@FreeBSD.org> | 2011-02-22 19:05:42 +0000 |
commit | f2afad1aeaf2ee3687e30ab2b584a8bd7a731ddf (patch) | |
tree | 1e94b233eb819904ead53a1e753f5883f71d1706 /sys/net80211 | |
parent | 847bf79423da130be27e1335cb954bbc52471065 (diff) | |
download | FreeBSD-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.c | 17 | ||||
-rw-r--r-- | sys/net80211/ieee80211_hostap.c | 17 | ||||
-rw-r--r-- | sys/net80211/ieee80211_mesh.c | 28 | ||||
-rw-r--r-- | sys/net80211/ieee80211_sta.c | 13 | ||||
-rw-r--r-- | sys/net80211/ieee80211_wds.c | 28 |
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; |