Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/net80211 Several changes:
details: https://anonhg.NetBSD.org/src/rev/eba0cad8229b
branches: trunk
changeset: 358828:eba0cad8229b
user: maxv <maxv%NetBSD.org@localhost>
date: Thu Jan 18 13:24:01 2018 +0000
description:
Several changes:
* Make the code more readable. In particular, declare variables as const
along the way.
* Explain what we're doing in ieee80211_send_mgmt(). The
IEEE80211_FC0_SUBTYPE_PROBE_RESP case has some inconsistencies, but
they are not inherently wrong so I'm not changing that.
* When sending IEEE80211_FC0_SUBTYPE_REASSOC_RESP frames, make sure to
zero out the 'association ID', otherwise two bytes are leaked.
* Fix a possible memory leak in ieee80211_send_probereq().
diffstat:
sys/net80211/ieee80211_output.c | 180 +++++++++++++++++++++++++++------------
1 files changed, 122 insertions(+), 58 deletions(-)
diffs (truncated from 508 to 300 lines):
diff -r 0558b76209b2 -r eba0cad8229b sys/net80211/ieee80211_output.c
--- a/sys/net80211/ieee80211_output.c Thu Jan 18 12:49:09 2018 +0000
+++ b/sys/net80211/ieee80211_output.c Thu Jan 18 13:24:01 2018 +0000
@@ -1,5 +1,6 @@
-/* $NetBSD: ieee80211_output.c,v 1.59 2017/09/26 07:42:06 knakahara Exp $ */
-/*-
+/* $NetBSD: ieee80211_output.c,v 1.60 2018/01/18 13:24:01 maxv Exp $ */
+
+/*
* Copyright (c) 2001 Atsushi Onoe
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
* All rights reserved.
@@ -36,7 +37,7 @@
__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_output.c,v 1.34 2005/08/10 16:22:29 sam Exp $");
#endif
#ifdef __NetBSD__
-__KERNEL_RCSID(0, "$NetBSD: ieee80211_output.c,v 1.59 2017/09/26 07:42:06 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ieee80211_output.c,v 1.60 2018/01/18 13:24:01 maxv Exp $");
#endif
#ifdef _KERNEL_OPT
@@ -115,6 +116,7 @@
#define WH4(wh) ((struct ieee80211_frame_addr4 *)wh)
wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | type;
+
if ((type & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA) {
switch (ic->ic_opmode) {
case IEEE80211_M_STA:
@@ -123,6 +125,7 @@
IEEE80211_ADDR_COPY(wh->i_addr2, sa);
IEEE80211_ADDR_COPY(wh->i_addr3, da);
break;
+
case IEEE80211_M_IBSS:
case IEEE80211_M_AHDEMO:
wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
@@ -130,12 +133,14 @@
IEEE80211_ADDR_COPY(wh->i_addr2, sa);
IEEE80211_ADDR_COPY(wh->i_addr3, bssid);
break;
+
case IEEE80211_M_HOSTAP:
wh->i_fc[1] = IEEE80211_FC1_DIR_FROMDS;
IEEE80211_ADDR_COPY(wh->i_addr1, da);
IEEE80211_ADDR_COPY(wh->i_addr2, bssid);
IEEE80211_ADDR_COPY(wh->i_addr3, sa);
break;
+
case IEEE80211_M_MONITOR: /* NB: to quiet compiler */
break;
}
@@ -145,6 +150,7 @@
IEEE80211_ADDR_COPY(wh->i_addr2, sa);
IEEE80211_ADDR_COPY(wh->i_addr3, bssid);
}
+
*(u_int16_t *)&wh->i_dur[0] = 0;
/* NB: use non-QoS tid */
*(u_int16_t *)&wh->i_seq[0] =
@@ -187,9 +193,9 @@
M_SETCTX(m, ni);
wh = mtod(m, struct ieee80211_frame *);
- ieee80211_send_setup(ic, ni, wh,
- IEEE80211_FC0_TYPE_MGT | type,
- ic->ic_myaddr, ni->ni_macaddr, ni->ni_bssid);
+ ieee80211_send_setup(ic, ni, wh, IEEE80211_FC0_TYPE_MGT | type,
+ ic->ic_myaddr, ni->ni_macaddr, ni->ni_bssid);
+
if ((m->m_flags & M_LINK0) != 0 && ni->ni_challenge != NULL) {
m->m_flags &= ~M_LINK0;
IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
@@ -197,6 +203,7 @@
ether_sprintf(wh->i_addr1), __func__);
wh->i_fc[1] |= IEEE80211_FC1_WEP;
}
+
#ifdef IEEE80211_DEBUG
/* avoid printing too many frames */
if ((ieee80211_msg_debug(ic) && doprint(ic, type)) ||
@@ -209,6 +216,7 @@
ieee80211_chan2ieee(ic, ic->ic_curchan));
}
#endif
+
IEEE80211_NODE_STAT(ni, tx_mgmt);
IF_ENQUEUE(&ic->ic_mgtq, m);
if (timer) {
@@ -247,13 +255,17 @@
M_SETCTX(m, ni);
wh = mtod(m, struct ieee80211_frame *);
+
ieee80211_send_setup(ic, ni, wh,
- IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_NODATA,
- ic->ic_myaddr, ni->ni_macaddr, ni->ni_bssid);
+ IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_NODATA,
+ ic->ic_myaddr, ni->ni_macaddr, ni->ni_bssid);
+
/* NB: power management bit is never sent by an AP */
if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) &&
- ic->ic_opmode != IEEE80211_M_HOSTAP)
+ ic->ic_opmode != IEEE80211_M_HOSTAP) {
wh->i_fc[1] |= IEEE80211_FC1_PWR_MGT;
+ }
+
m->m_len = m->m_pkthdr.len = sizeof(struct ieee80211_frame);
IEEE80211_NODE_STAT(ni, tx_data);
@@ -277,7 +289,8 @@
* applied.
*/
int
-ieee80211_classify(struct ieee80211com *ic, struct mbuf *m, struct ieee80211_node *ni)
+ieee80211_classify(struct ieee80211com *ic, struct mbuf *m,
+ struct ieee80211_node *ni)
{
int v_wme_ac, d_wme_ac, ac;
#ifdef INET
@@ -405,6 +418,7 @@
needed_space += key->wk_cipher->ic_header;
/* XXX frags */
}
+
/*
* We know we are called just before stripping an Ethernet
* header and prepending an LLC header. This means we know
@@ -423,8 +437,10 @@
m_freem(m);
return NULL;
}
+
IASSERT(needed_space <= MHLEN,
("not enough room, need %u got %zu\n", needed_space, MHLEN));
+
/*
* Setup new mbuf to have leading space to prepend the
* 802.11 header and any crypto header bits that are
@@ -451,7 +467,8 @@
n->m_next = m;
m = n;
} else {
- /* We will overwrite the ethernet header in the
+ /*
+ * We will overwrite the ethernet header in the
* 802.11 encapsulation stage. Make sure that it
* is writable.
*/
@@ -539,10 +556,11 @@
*/
if (ic->ic_flags & IEEE80211_F_PRIVACY) {
if (ic->ic_opmode == IEEE80211_M_STA ||
- !IEEE80211_IS_MULTICAST(eh.ether_dhost))
+ !IEEE80211_IS_MULTICAST(eh.ether_dhost)) {
key = ieee80211_crypto_getucastkey(ic, ni);
- else
+ } else {
key = ieee80211_crypto_getmcastkey(ic, ni);
+ }
if (key == NULL && eh.ether_type != htons(ETHERTYPE_PAE)) {
IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
"[%s] no default transmit key (%s) deftxkey %u\n",
@@ -550,10 +568,13 @@
ic->ic_def_txkey);
ic->ic_stats.is_tx_nodefkey++;
}
- } else
+ } else {
key = NULL;
- /* XXX 4-address format */
+ }
+
/*
+ * XXX 4-address format.
+ *
* XXX Some ap's don't handle QoS-encapsulated EAPOL
* frames so suppress use. This may be an issue if other
* ap's require all data frames to be QoS-encapsulated
@@ -561,13 +582,14 @@
* configurable.
*/
addqos = (ni->ni_flags & IEEE80211_NODE_QOS) &&
- eh.ether_type != htons(ETHERTYPE_PAE);
+ eh.ether_type != htons(ETHERTYPE_PAE);
if (addqos)
hdrsize = sizeof(struct ieee80211_qosframe);
else
hdrsize = sizeof(struct ieee80211_frame);
if (ic->ic_flags & IEEE80211_F_DATAPAD)
hdrsize = roundup(hdrsize, sizeof(u_int32_t));
+
m = ieee80211_mbuf_adjust(ic, hdrsize, key, m);
if (m == NULL) {
/* NB: ieee80211_mbuf_adjust handles msgs+statistics */
@@ -590,9 +612,11 @@
ic->ic_stats.is_tx_nobuf++;
goto bad;
}
+
wh = mtod(m, struct ieee80211_frame *);
wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA;
*(u_int16_t *)wh->i_dur = 0;
+
switch (ic->ic_opmode) {
case IEEE80211_M_STA:
wh->i_fc[1] = IEEE80211_FC1_DIR_TODS;
@@ -600,6 +624,7 @@
IEEE80211_ADDR_COPY(wh->i_addr2, eh.ether_shost);
IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_dhost);
break;
+
case IEEE80211_M_IBSS:
case IEEE80211_M_AHDEMO:
wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
@@ -611,22 +636,26 @@
*/
IEEE80211_ADDR_COPY(wh->i_addr3, ic->ic_bss->ni_bssid);
break;
+
case IEEE80211_M_HOSTAP:
#ifndef IEEE80211_NO_HOSTAP
wh->i_fc[1] = IEEE80211_FC1_DIR_FROMDS;
IEEE80211_ADDR_COPY(wh->i_addr1, eh.ether_dhost);
IEEE80211_ADDR_COPY(wh->i_addr2, ni->ni_bssid);
IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_shost);
-#endif /* !IEEE80211_NO_HOSTAP */
+#endif
break;
+
case IEEE80211_M_MONITOR:
goto bad;
}
+
if (m->m_flags & M_MORE_DATA)
wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA;
+
if (addqos) {
struct ieee80211_qosframe *qwh =
- (struct ieee80211_qosframe *) wh;
+ (struct ieee80211_qosframe *)wh;
int ac, tid;
ac = M_WME_GETAC(m);
@@ -646,10 +675,12 @@
htole16(ni->ni_txseqs[0] << IEEE80211_SEQ_SEQ_SHIFT);
ni->ni_txseqs[0]++;
}
+
/* check if xmit fragmentation is required */
txfrag = (m->m_pkthdr.len > ic->ic_fragthreshold &&
!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
(m->m_flags & M_FF) == 0); /* NB: don't fragment ff's */
+
if (key != NULL) {
/*
* IEEE 802.1X: send EAPOL frames always in the clear.
@@ -670,6 +701,7 @@
}
}
}
+
if (txfrag && !ieee80211_fragment(ic, m, hdrsize,
key != NULL ? key->wk_cipher->ic_header : 0, ic->ic_fragthreshold))
goto bad;
@@ -678,6 +710,7 @@
IEEE80211_NODE_STAT_ADD(ni, tx_bytes, datalen);
return m;
+
bad:
if (m != NULL)
m_freem(m);
@@ -1338,14 +1371,17 @@
m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT);
- if (m == NULL)
+ if (m == NULL) {
+ ic->ic_stats.is_tx_nobuf++;
+ ieee80211_free_node(ni);
return ENOMEM;
+ }
M_SETCTX(m, ni);
wh = mtod(m, struct ieee80211_frame *);
ieee80211_send_setup(ic, ni, wh,
- IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_REQ,
- sa, da, bssid);
+ IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_REQ,
+ sa, da, bssid);
/* XXX power management? */
IEEE80211_NODE_STAT(ni, tx_probereq);
@@ -1374,7 +1410,7 @@
struct mbuf *m;
u_int8_t *frm;
u_int16_t capinfo;
- int has_challenge, is_shared_key, ret, timer, status;
+ int ret, timer, status;
Home |
Main Index |
Thread Index |
Old Index