summaryrefslogtreecommitdiffstats
path: root/sys/net80211
diff options
context:
space:
mode:
authorbschmidt <bschmidt@FreeBSD.org>2011-02-21 19:59:43 +0000
committerbschmidt <bschmidt@FreeBSD.org>2011-02-21 19:59:43 +0000
commit4a678eb796530966a967308cc53226a4918751ac (patch)
treef77ffd1e3e1f1535d6cfcc3ed094387e24cbc4e5 /sys/net80211
parentcd04d02c85e125f329ea68f58525788d217869b6 (diff)
downloadFreeBSD-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.h1
-rw-r--r--sys/net80211/ieee80211_adhoc.c101
-rw-r--r--sys/net80211/ieee80211_hostap.c17
-rw-r--r--sys/net80211/ieee80211_input.c1
-rw-r--r--sys/net80211/ieee80211_mesh.c30
-rw-r--r--sys/net80211/ieee80211_proto.c2
-rw-r--r--sys/net80211/ieee80211_sta.c19
-rw-r--r--sys/net80211/ieee80211_wds.c49
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;
}
OpenPOWER on IntegriCloud