diff options
author | bschmidt <bschmidt@FreeBSD.org> | 2011-02-21 19:59:43 +0000 |
---|---|---|
committer | bschmidt <bschmidt@FreeBSD.org> | 2011-02-21 19:59:43 +0000 |
commit | 4a678eb796530966a967308cc53226a4918751ac (patch) | |
tree | f77ffd1e3e1f1535d6cfcc3ed094387e24cbc4e5 /sys/net80211 | |
parent | cd04d02c85e125f329ea68f58525788d217869b6 (diff) | |
download | FreeBSD-src-4a678eb796530966a967308cc53226a4918751ac.zip FreeBSD-src-4a678eb796530966a967308cc53226a4918751ac.tar.gz |
Add a new mgmt subtype "ACTION NO ACK" defined in 802.11n-2009, while here
clean up parts of the *_recv_mgmt() functions.
- make sure appropriate counters are bumped and debug messages are printed
- order the unhandled subtypes by value and add a few missing ones
- fix some whitespace nits
- remove duplicate code in adhoc_recv_mgmt()
- remove a useless comment, probably left in while c&p
Diffstat (limited to 'sys/net80211')
-rw-r--r-- | sys/net80211/ieee80211.h | 1 | ||||
-rw-r--r-- | sys/net80211/ieee80211_adhoc.c | 101 | ||||
-rw-r--r-- | sys/net80211/ieee80211_hostap.c | 17 | ||||
-rw-r--r-- | sys/net80211/ieee80211_input.c | 1 | ||||
-rw-r--r-- | sys/net80211/ieee80211_mesh.c | 30 | ||||
-rw-r--r-- | sys/net80211/ieee80211_proto.c | 2 | ||||
-rw-r--r-- | sys/net80211/ieee80211_sta.c | 19 | ||||
-rw-r--r-- | sys/net80211/ieee80211_wds.c | 49 |
8 files changed, 122 insertions, 98 deletions
diff --git a/sys/net80211/ieee80211.h b/sys/net80211/ieee80211.h index 712c2a8..5d8d8fa 100644 --- a/sys/net80211/ieee80211.h +++ b/sys/net80211/ieee80211.h @@ -131,6 +131,7 @@ struct ieee80211_qosframe_addr4 { #define IEEE80211_FC0_SUBTYPE_AUTH 0xb0 #define IEEE80211_FC0_SUBTYPE_DEAUTH 0xc0 #define IEEE80211_FC0_SUBTYPE_ACTION 0xd0 +#define IEEE80211_FC0_SUBTYPE_ACTION_NOACK 0xe0 /* for TYPE_CTL */ #define IEEE80211_FC0_SUBTYPE_BAR 0x80 #define IEEE80211_FC0_SUBTYPE_BA 0x90 diff --git a/sys/net80211/ieee80211_adhoc.c b/sys/net80211/ieee80211_adhoc.c index 67bcf64..9950505 100644 --- a/sys/net80211/ieee80211_adhoc.c +++ b/sys/net80211/ieee80211_adhoc.c @@ -823,80 +823,35 @@ adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, is11bclient(rates, xrates) ? IEEE80211_SEND_LEGACY_11B : 0); break; - case IEEE80211_FC0_SUBTYPE_ACTION: { - const struct ieee80211_action *ia; - - if (vap->iv_state != IEEE80211_S_RUN) { + 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 { IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, wh, NULL, "wrong state %s", ieee80211_state_name[vap->iv_state]); vap->iv_stats.is_rx_mgtdiscard++; - return; } - /* - * action frame format: - * [1] category - * [1] action - * [tlv] parameters - */ - IEEE80211_VERIFY_LENGTH(efrm - frm, - sizeof(struct ieee80211_action), return); - ia = (const struct ieee80211_action *) frm; - - vap->iv_stats.is_rx_action++; - IEEE80211_NODE_STAT(ni, rx_action); - - /* verify frame payloads but defer processing */ - /* XXX maybe push this to method */ - switch (ia->ia_category) { - case IEEE80211_ACTION_CAT_BA: - switch (ia->ia_action) { - case IEEE80211_ACTION_BA_ADDBA_REQUEST: - IEEE80211_VERIFY_LENGTH(efrm - frm, - sizeof(struct ieee80211_action_ba_addbarequest), - return); - break; - case IEEE80211_ACTION_BA_ADDBA_RESPONSE: - IEEE80211_VERIFY_LENGTH(efrm - frm, - sizeof(struct ieee80211_action_ba_addbaresponse), - return); - break; - case IEEE80211_ACTION_BA_DELBA: - IEEE80211_VERIFY_LENGTH(efrm - frm, - sizeof(struct ieee80211_action_ba_delba), - return); - break; - } - break; - case IEEE80211_ACTION_CAT_HT: - switch (ia->ia_action) { - case IEEE80211_ACTION_HT_TXCHWIDTH: - IEEE80211_VERIFY_LENGTH(efrm - frm, - sizeof(struct ieee80211_action_ht_txchwidth), - return); - break; - } - break; - } - ic->ic_recv_action(ni, wh, frm, efrm); break; - } - case IEEE80211_FC0_SUBTYPE_AUTH: case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: - case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: + case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: - case IEEE80211_FC0_SUBTYPE_DEAUTH: + case IEEE80211_FC0_SUBTYPE_ATIM: case IEEE80211_FC0_SUBTYPE_DISASSOC: + case IEEE80211_FC0_SUBTYPE_AUTH: + case IEEE80211_FC0_SUBTYPE_DEAUTH: IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, - wh, NULL, "%s", "not handled"); + wh, NULL, "%s", "not handled"); vap->iv_stats.is_rx_mgtdiscard++; - return; + break; default: IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, - wh, "mgt", "subtype 0x%x not handled", subtype); + wh, "mgt", "subtype 0x%x not handled", subtype); vap->iv_stats.is_rx_badsubtype++; break; } @@ -910,6 +865,7 @@ ahdemo_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, { struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; + struct ieee80211_frame *wh; /* * Process management frames when scanning; useful for doing @@ -917,8 +873,33 @@ ahdemo_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, */ if (ic->ic_flags & IEEE80211_F_SCAN) adhoc_recv_mgmt(ni, m0, subtype, rssi, nf); - else - vap->iv_stats.is_rx_mgtdiscard++; + else { + wh = mtod(m0, struct ieee80211_frame *); + switch (subtype) { + case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: + case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: + case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: + case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: + case IEEE80211_FC0_SUBTYPE_PROBE_REQ: + case IEEE80211_FC0_SUBTYPE_PROBE_RESP: + case IEEE80211_FC0_SUBTYPE_BEACON: + case IEEE80211_FC0_SUBTYPE_ATIM: + case IEEE80211_FC0_SUBTYPE_DISASSOC: + case IEEE80211_FC0_SUBTYPE_AUTH: + case IEEE80211_FC0_SUBTYPE_DEAUTH: + case IEEE80211_FC0_SUBTYPE_ACTION: + case IEEE80211_FC0_SUBTYPE_ACTION_NOACK: + IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, + wh, NULL, "%s", "not handled"); + vap->iv_stats.is_rx_mgtdiscard++; + break; + default: + IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, + wh, "mgt", "subtype 0x%x not handled", subtype); + vap->iv_stats.is_rx_badsubtype++; + break; + } + } } static void diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c index 63bcd3c..861ff08 100644 --- a/sys/net80211/ieee80211_hostap.c +++ b/sys/net80211/ieee80211_hostap.c @@ -2194,18 +2194,29 @@ 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) - ic->ic_recv_action(ni, wh, frm, efrm); - } else + (void)ic->ic_recv_action(ni, wh, frm, efrm); + } else { + IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, + wh, NULL, "wrong state %s", + ieee80211_state_name[vap->iv_state]); vap->iv_stats.is_rx_mgtdiscard++; + } break; case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: + case IEEE80211_FC0_SUBTYPE_ATIM: + IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, + wh, NULL, "%s", "not handled"); + vap->iv_stats.is_rx_mgtdiscard++; + break; + default: IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, - wh, "mgt", "subtype 0x%x not handled", subtype); + wh, "mgt", "subtype 0x%x not handled", subtype); vap->iv_stats.is_rx_badsubtype++; break; } diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c index 28a58fe..c372370 100644 --- a/sys/net80211/ieee80211_input.c +++ b/sys/net80211/ieee80211_input.c @@ -677,7 +677,6 @@ ieee80211_parse_action(struct ieee80211_node *ni, struct mbuf *m) IEEE80211_NODE_STAT(ni, rx_action); /* verify frame payloads but defer processing */ - /* XXX maybe push this to method */ switch (ia->ia_category) { case IEEE80211_ACTION_CAT_BA: switch (ia->ia_action) { diff --git a/sys/net80211/ieee80211_mesh.c b/sys/net80211/ieee80211_mesh.c index 028fc14..2559dc0 100644 --- a/sys/net80211/ieee80211_mesh.c +++ b/sys/net80211/ieee80211_mesh.c @@ -1489,11 +1489,9 @@ mesh_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype, ieee80211_send_proberesp(vap, wh->i_addr2, 0); break; } + case IEEE80211_FC0_SUBTYPE_ACTION: - if (vap->iv_state != IEEE80211_S_RUN) { - vap->iv_stats.is_rx_mgtdiscard++; - break; - } + case IEEE80211_FC0_SUBTYPE_ACTION_NOACK: /* * We received an action for an unknown neighbor. * XXX: wait for it to beacon or create ieee80211_node? @@ -1506,6 +1504,7 @@ mesh_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype, } /* * Discard if not for us. + * XXX: if from us too? */ if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr1) && !IEEE80211_IS_MULTICAST(wh->i_addr1)) { @@ -1514,21 +1513,30 @@ mesh_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype, vap->iv_stats.is_rx_mgtdiscard++; break; } - /* XXX parse_action is a bit useless now */ - if (ieee80211_parse_action(ni, m0) == 0) - ic->ic_recv_action(ni, wh, frm, efrm); + if (vap->iv_state == IEEE80211_S_RUN) { + if (ieee80211_parse_action(ni, m0) == 0) + (void)ic->ic_recv_action(ni, wh, frm, efrm); + } else { + IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, + wh, NULL, "wrong state %s", + ieee80211_state_name[vap->iv_state]); + vap->iv_stats.is_rx_mgtdiscard++; + } break; - case IEEE80211_FC0_SUBTYPE_AUTH: + case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: - case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: + case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: - case IEEE80211_FC0_SUBTYPE_DEAUTH: + case IEEE80211_FC0_SUBTYPE_ATIM: case IEEE80211_FC0_SUBTYPE_DISASSOC: + case IEEE80211_FC0_SUBTYPE_AUTH: + case IEEE80211_FC0_SUBTYPE_DEAUTH: IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, wh, NULL, "%s", "not handled"); vap->iv_stats.is_rx_mgtdiscard++; - return; + break; + default: IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, wh, "mgt", "subtype 0x%x not handled", subtype); diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c index a0ddeb4..c20f083 100644 --- a/sys/net80211/ieee80211_proto.c +++ b/sys/net80211/ieee80211_proto.c @@ -64,7 +64,7 @@ const char *ieee80211_mgt_subtype_name[] = { "assoc_req", "assoc_resp", "reassoc_req", "reassoc_resp", "probe_req", "probe_resp", "reserved#6", "reserved#7", "beacon", "atim", "disassoc", "auth", - "deauth", "action", "reserved#14", "reserved#15" + "deauth", "action", "action_noack", "reserved#15" }; const char *ieee80211_ctl_subtype_name[] = { "reserved#0", "reserved#1", "reserved#2", "reserved#3", diff --git a/sys/net80211/ieee80211_sta.c b/sys/net80211/ieee80211_sta.c index f93c3ed..bbfb36ef 100644 --- a/sys/net80211/ieee80211_sta.c +++ b/sys/net80211/ieee80211_sta.c @@ -1718,21 +1718,30 @@ 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) - ic->ic_recv_action(ni, wh, frm, efrm); - } else + (void)ic->ic_recv_action(ni, wh, frm, efrm); + } else { + IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, + wh, NULL, "wrong state %s", + ieee80211_state_name[vap->iv_state]); vap->iv_stats.is_rx_mgtdiscard++; + } break; - case IEEE80211_FC0_SUBTYPE_PROBE_REQ: case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: + case IEEE80211_FC0_SUBTYPE_PROBE_REQ: + case IEEE80211_FC0_SUBTYPE_ATIM: + IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, + wh, NULL, "%s", "not handled"); vap->iv_stats.is_rx_mgtdiscard++; - return; + break; + default: IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, - wh, "mgt", "subtype 0x%x not handled", subtype); + wh, "mgt", "subtype 0x%x not handled", subtype); vap->iv_stats.is_rx_badsubtype++; break; } diff --git a/sys/net80211/ieee80211_wds.c b/sys/net80211/ieee80211_wds.c index 15518d8..23de423 100644 --- a/sys/net80211/ieee80211_wds.c +++ b/sys/net80211/ieee80211_wds.c @@ -756,31 +756,46 @@ wds_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, frm = (u_int8_t *)&wh[1]; efrm = mtod(m0, u_int8_t *) + m0->m_len; switch (subtype) { - case IEEE80211_FC0_SUBTYPE_DEAUTH: - case IEEE80211_FC0_SUBTYPE_PROBE_RESP: - case IEEE80211_FC0_SUBTYPE_BEACON: - case IEEE80211_FC0_SUBTYPE_PROBE_REQ: - case IEEE80211_FC0_SUBTYPE_AUTH: + 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"); + 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 { + IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, + wh, NULL, "wrong state %s", + ieee80211_state_name[vap->iv_state]); + vap->iv_stats.is_rx_mgtdiscard++; + } + break; + case IEEE80211_FC0_SUBTYPE_ASSOC_REQ: - case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: + case IEEE80211_FC0_SUBTYPE_REASSOC_REQ: case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: + case IEEE80211_FC0_SUBTYPE_PROBE_REQ: + case IEEE80211_FC0_SUBTYPE_PROBE_RESP: + case IEEE80211_FC0_SUBTYPE_BEACON: + case IEEE80211_FC0_SUBTYPE_ATIM: case IEEE80211_FC0_SUBTYPE_DISASSOC: + case IEEE80211_FC0_SUBTYPE_AUTH: + case IEEE80211_FC0_SUBTYPE_DEAUTH: + IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, + wh, NULL, "%s", "not handled"); vap->iv_stats.is_rx_mgtdiscard++; break; - case IEEE80211_FC0_SUBTYPE_ACTION: - if (vap->iv_state != IEEE80211_S_RUN || - IEEE80211_IS_MULTICAST(wh->i_addr1)) { - vap->iv_stats.is_rx_mgtdiscard++; - break; - } - ni->ni_inact = ni->ni_inact_reload; - if (ieee80211_parse_action(ni, m0) == 0) - ic->ic_recv_action(ni, wh, frm, efrm); - break; + default: IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, - wh, "mgt", "subtype 0x%x not handled", subtype); + wh, "mgt", "subtype 0x%x not handled", subtype); vap->iv_stats.is_rx_badsubtype++; break; } |