Author: bschmidt
Date: Tue Feb 22 19:05:42 2011
New Revision: 218958
URL: http://svn.freebsd.org/changeset/base/218958

Log:
  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.

Modified:
  head/sys/net80211/ieee80211_adhoc.c
  head/sys/net80211/ieee80211_hostap.c
  head/sys/net80211/ieee80211_mesh.c
  head/sys/net80211/ieee80211_sta.c
  head/sys/net80211/ieee80211_wds.c

Modified: head/sys/net80211/ieee80211_adhoc.c
==============================================================================
--- head/sys/net80211/ieee80211_adhoc.c Tue Feb 22 17:51:45 2011        
(r218957)
+++ head/sys/net80211/ieee80211_adhoc.c Tue Feb 22 19:05:42 2011        
(r218958)
@@ -825,14 +825,23 @@ adhoc_recv_mgmt(struct ieee80211_node *n
 
        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;
 

Modified: head/sys/net80211/ieee80211_hostap.c
==============================================================================
--- head/sys/net80211/ieee80211_hostap.c        Tue Feb 22 17:51:45 2011        
(r218957)
+++ head/sys/net80211/ieee80211_hostap.c        Tue Feb 22 19:05:42 2011        
(r218958)
@@ -2195,14 +2195,23 @@ hostap_recv_mgmt(struct ieee80211_node *
 
        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;
 

Modified: head/sys/net80211/ieee80211_mesh.c
==============================================================================
--- head/sys/net80211/ieee80211_mesh.c  Tue Feb 22 17:51:45 2011        
(r218957)
+++ head/sys/net80211/ieee80211_mesh.c  Tue Feb 22 19:05:42 2011        
(r218958)
@@ -1492,35 +1492,23 @@ mesh_recv_mgmt(struct ieee80211_node *ni
 
        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;
 

Modified: head/sys/net80211/ieee80211_sta.c
==============================================================================
--- head/sys/net80211/ieee80211_sta.c   Tue Feb 22 17:51:45 2011        
(r218957)
+++ head/sys/net80211/ieee80211_sta.c   Tue Feb 22 19:05:42 2011        
(r218958)
@@ -1719,14 +1719,19 @@ sta_recv_mgmt(struct ieee80211_node *ni,
 
        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;
 

Modified: head/sys/net80211/ieee80211_wds.c
==============================================================================
--- head/sys/net80211/ieee80211_wds.c   Tue Feb 22 17:51:45 2011        
(r218957)
+++ head/sys/net80211/ieee80211_wds.c   Tue Feb 22 19:05:42 2011        
(r218958)
@@ -454,6 +454,9 @@ wds_input(struct ieee80211_node *ni, str
         */
        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, str
                        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,
        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;
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to