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/033c3641f7ed
branches:  trunk
changeset: 829129:033c3641f7ed
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 4e94e4ca651d -r 033c3641f7ed 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