Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/net80211 Import changes in FreeBSD's net80211 between 20...



details:   https://anonhg.NetBSD.org/src/rev/b145418a7e4f
branches:  trunk
changeset: 583252:b145418a7e4f
user:      dyoung <dyoung%NetBSD.org@localhost>
date:      Tue Jul 26 22:52:47 2005 +0000

description:
Import changes in FreeBSD's net80211 between 2005-05-18 and 2005-07-11.

A summary of changes is forthcoming.

diffstat:

 sys/net80211/ieee80211_input.c |  312 ++++++++++++++++++++++++----------------
 1 files changed, 187 insertions(+), 125 deletions(-)

diffs (truncated from 701 to 300 lines):

diff -r ca888e8a71a4 -r b145418a7e4f sys/net80211/ieee80211_input.c
--- a/sys/net80211/ieee80211_input.c    Tue Jul 26 22:52:47 2005 +0000
+++ b/sys/net80211/ieee80211_input.c    Tue Jul 26 22:52:47 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ieee80211_input.c,v 1.43 2005/07/03 21:18:42 dyoung Exp $      */
+/*     $NetBSD: ieee80211_input.c,v 1.44 2005/07/26 22:52:48 dyoung Exp $      */
 /*-
  * Copyright (c) 2001 Atsushi Onoe
  * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
@@ -33,10 +33,10 @@
 
 #include <sys/cdefs.h>
 #ifdef __FreeBSD__
-__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_input.c,v 1.33 2005/02/23 04:52:30 sam Exp $");
+__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_input.c,v 1.62 2005/07/11 03:00:20 sam Exp $");
 #endif
 #ifdef __NetBSD__
-__KERNEL_RCSID(0, "$NetBSD: ieee80211_input.c,v 1.43 2005/07/03 21:18:42 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ieee80211_input.c,v 1.44 2005/07/26 22:52:48 dyoung Exp $");
 #endif
 
 #include "opt_inet.h"
@@ -135,8 +135,10 @@
 #endif /* IEEE80211_DEBUG */
 
 static struct mbuf *ieee80211_defrag(struct ieee80211com *,
-       struct ieee80211_node *, struct mbuf *);
-static struct mbuf *ieee80211_decap(struct ieee80211com *, struct mbuf *);
+       struct ieee80211_node *, struct mbuf *, int);
+static struct mbuf *ieee80211_decap(struct ieee80211com *, struct mbuf *, int);
+static void ieee80211_send_error(struct ieee80211com *, struct ieee80211_node *,
+               const u_int8_t *mac, int subtype, int arg);
 #ifndef IEEE80211_NO_HOSTAP
 static void ieee80211_node_pwrsave(struct ieee80211_node *, int enable);
 static void ieee80211_recv_pspoll(struct ieee80211com *,
@@ -163,7 +165,7 @@
        struct ieee80211_frame *wh;
        struct ieee80211_key *key;
        struct ether_header *eh;
-       int hdrsize, off;
+       int hdrspace;
        u_int8_t dir, type, subtype;
        u_int8_t *bssid;
        u_int16_t rxseq;
@@ -177,7 +179,6 @@
                m_adj(m, -IEEE80211_CRC_LEN);
                m->m_flags &= ~M_HASFCS;
        }
-
        type = -1;                      /* undefined */
        /*
         * In monitor mode, send everything directly to bpf.
@@ -283,7 +284,7 @@
                        if (IEEE80211_QOS_HAS_SEQ(wh)) {
                                tid = ((struct ieee80211_qosframe *)wh)->
                                        i_qos[0] & IEEE80211_QOS_TID;
-                               if (tid >= WME_AC_VI)
+                               if (TID_TO_WME_AC(tid) >= WME_AC_VI)
                                        ic->ic_wme.wme_hipri_traffic++;
                                tid++;
                        } else
@@ -312,33 +313,15 @@
 
        switch (type) {
        case IEEE80211_FC0_TYPE_DATA:
-               hdrsize = ieee80211_hdrsize(wh);
-               if (ic->ic_flags & IEEE80211_F_DATAPAD)
-                       hdrsize = roundup(hdrsize, sizeof(u_int32_t));
-               if (m->m_len < hdrsize &&
-                   (m = m_pullup(m, hdrsize)) == NULL) {
+               hdrspace = ieee80211_hdrspace(ic, wh);
+               if (m->m_len < hdrspace &&
+                   (m = m_pullup(m, hdrspace)) == NULL) {
                        IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_ANY,
                            ni->ni_macaddr, NULL,
-                           "data too short: expecting %u", hdrsize);
+                           "data too short: expecting %u", hdrspace);
                        ic->ic_stats.is_rx_tooshort++;
                        goto out;               /* XXX */
                }
-               if (subtype & IEEE80211_FC0_SUBTYPE_QOS) {
-                       /* XXX discard if node w/o IEEE80211_NODE_QOS? */
-                       /*
-                        * Strip QoS control and any padding so only a
-                        * stock 802.11 header is at the front.
-                        */
-                       /* XXX 4-address QoS frame */
-                       off = hdrsize - sizeof(struct ieee80211_frame);
-                       ovbcopy(mtod(m, u_int8_t *), mtod(m, u_int8_t *) + off,
-                               hdrsize - off);
-                       m_adj(m, off);
-                       wh = mtod(m, struct ieee80211_frame *);
-                       wh->i_fc[0] &= ~IEEE80211_FC0_SUBTYPE_QOS;
-               } else {
-                       /* XXX copy up for 4-address frames w/ padding */
-               }
                switch (ic->ic_opmode) {
                case IEEE80211_M_STA:
                        if (dir != IEEE80211_FC1_DIR_FROMDS) {
@@ -397,14 +380,9 @@
                        if (ni == ic->ic_bss) {
                                IEEE80211_DISCARD(ic, IEEE80211_MSG_INPUT,
                                    wh, "data", "%s", "unknown src");
-                               /* NB: caller deals with reference */
-                               ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2);
-                               if (ni != NULL) {
-                                       IEEE80211_SEND_MGMT(ic, ni,
-                                           IEEE80211_FC0_SUBTYPE_DEAUTH,
-                                           IEEE80211_REASON_NOT_AUTHED);
-                                       ieee80211_free_node(ni);
-                               }
+                               ieee80211_send_error(ic, ni, wh->i_addr2,
+                                   IEEE80211_FC0_SUBTYPE_DEAUTH,
+                                   IEEE80211_REASON_NOT_AUTHED);
                                ic->ic_stats.is_rx_notassoc++;
                                goto err;
                        }
@@ -451,7 +429,7 @@
                                IEEE80211_NODE_STAT(ni, rx_noprivacy);
                                goto out;
                        }
-                       key = ieee80211_crypto_decap(ic, ni, m);
+                       key = ieee80211_crypto_decap(ic, ni, m, hdrspace);
                        if (key == NULL) {
                                /* NB: stats+msgs handled in crypto_decap */
                                IEEE80211_NODE_STAT(ni, rx_wepfail);
@@ -467,7 +445,7 @@
                 * Next up, any fragmentation.
                 */
                if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
-                       m = ieee80211_defrag(ic, ni, m);
+                       m = ieee80211_defrag(ic, ni, m, hdrspace);
                        if (m == NULL) {
                                /* Fragment dropped or frame not complete yet */
                                goto out;
@@ -478,7 +456,7 @@
                /*
                 * Next strip any MSDU crypto bits.
                 */
-               if (key != NULL && !ieee80211_crypto_demic(ic, key, m)) {
+               if (key != NULL && !ieee80211_crypto_demic(ic, key, m, 0)) {
                        IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_INPUT,
                            ni->ni_macaddr, "data", "%s", "demic error");
                        IEEE80211_NODE_STAT(ni, rx_demicfail);
@@ -494,7 +472,7 @@
                /*
                 * Finally, strip the 802.11 header.
                 */
-               m = ieee80211_decap(ic, m);
+               m = ieee80211_decap(ic, m, hdrspace);
                if (m == NULL) {
                        /* don't count Null data frames as errors */
                        if (subtype == IEEE80211_FC0_SUBTYPE_NODATA)
@@ -650,7 +628,8 @@
                                ic->ic_stats.is_rx_noprivacy++;
                                goto out;
                        }
-                       key = ieee80211_crypto_decap(ic, ni, m);
+                       hdrspace = ieee80211_hdrspace(ic, wh);
+                       key = ieee80211_crypto_decap(ic, ni, m, hdrspace);
                        if (key == NULL) {
                                /* NB: stats+msgs handled in crypto_decap */
                                goto out;
@@ -704,7 +683,7 @@
  */
 static struct mbuf *
 ieee80211_defrag(struct ieee80211com *ic, struct ieee80211_node *ni,
-       struct mbuf *m)
+       struct mbuf *m, int hdrspace)
 {
        struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
        struct ieee80211_frame *lwh;
@@ -773,6 +752,7 @@
                }
                mfrag = m;
        } else {                                /* concatenate */
+               m_adj(m, hdrspace);             /* strip header */
                m_cat(mfrag, m);
                /* NB: m_cat doesn't update the packet header */
                mfrag->m_pkthdr.len += m->m_pkthdr.len;
@@ -789,26 +769,26 @@
 }
 
 static struct mbuf *
-ieee80211_decap(struct ieee80211com *ic, struct mbuf *m)
+ieee80211_decap(struct ieee80211com *ic, struct mbuf *m, int hdrlen)
 {
-       struct ieee80211_frame wh;      /* NB: QoS stripped above */
+       struct ieee80211_qosframe_addr4 wh;     /* Max size address frames */
        struct ether_header *eh;
        struct llc *llc;
 
-       if (m->m_len < sizeof(wh) + sizeof(*llc) &&
-           (m = m_pullup(m, sizeof(wh) + sizeof(*llc))) == NULL) {
+       if (m->m_len < hdrlen + sizeof(*llc) &&
+           (m = m_pullup(m, hdrlen + sizeof(*llc))) == NULL) {
                /* XXX stat, msg */
                return NULL;
        }
-       memcpy(&wh, mtod(m, caddr_t), sizeof(wh));
-       llc = (struct llc *)(mtod(m, caddr_t) + sizeof(wh));
+       memcpy(&wh, mtod(m, caddr_t), hdrlen);
+       llc = (struct llc *)(mtod(m, caddr_t) + hdrlen);
        if (llc->llc_dsap == LLC_SNAP_LSAP && llc->llc_ssap == LLC_SNAP_LSAP &&
            llc->llc_control == LLC_UI && llc->llc_snap.org_code[0] == 0 &&
            llc->llc_snap.org_code[1] == 0 && llc->llc_snap.org_code[2] == 0) {
-               m_adj(m, sizeof(wh) + sizeof(struct llc) - sizeof(*eh));
+               m_adj(m, hdrlen + sizeof(struct llc) - sizeof(*eh));
                llc = NULL;
        } else {
-               m_adj(m, sizeof(wh) - sizeof(*eh));
+               m_adj(m, hdrlen - sizeof(*eh));
        }
        eh = mtod(m, struct ether_header *);
        switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) {
@@ -825,11 +805,9 @@
                IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr3);
                break;
        case IEEE80211_FC1_DIR_DSTODS:
-               /* not yet supported */
-               IEEE80211_DISCARD(ic, IEEE80211_MSG_ANY,
-                   &wh, "data", "%s", "DS to DS not supported");
-               m_freem(m);
-               return NULL;
+               IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr3);
+               IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr4);
+               break;
        }
 #ifdef ALIGNED_POINTER
        if (!ALIGNED_POINTER(mtod(m, caddr_t) + sizeof(*eh), u_int32_t)) {
@@ -927,19 +905,27 @@
     u_int16_t status)
 {
 
+       if (ni->ni_authmode == IEEE80211_AUTH_SHARED) {
+               IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
+                   ni->ni_macaddr, "open auth",
+                   "bad sta auth mode %u", ni->ni_authmode);
+               ic->ic_stats.is_rx_bad_auth++;  /* XXX */
+               if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
+                       /* XXX hack to workaround calling convention */
+                       ieee80211_send_error(ic, ni, wh->i_addr2, 
+                           IEEE80211_FC0_SUBTYPE_AUTH,
+                           (seq + 1) | (IEEE80211_STATUS_ALG<<16));
+               }
+               return;
+       }
        switch (ic->ic_opmode) {
        case IEEE80211_M_IBSS:
-               if (ic->ic_state != IEEE80211_S_RUN ||
-                   seq != IEEE80211_AUTH_OPEN_REQUEST) {
-                       ic->ic_stats.is_rx_bad_auth++;
-                       return;
-               }
-               ieee80211_new_state(ic, IEEE80211_S_AUTH,
-                   wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK);
-               break;
-
        case IEEE80211_M_AHDEMO:
+       case IEEE80211_M_MONITOR:
                /* should not come here */
+               IEEE80211_DISCARD_MAC(ic, IEEE80211_MSG_AUTH,
+                   ni->ni_macaddr, "open auth",
+                   "bad operating mode %u", ic->ic_opmode);
                break;
 
        case IEEE80211_M_HOSTAP:
@@ -954,13 +940,26 @@
                        ni = ieee80211_dup_bss(&ic->ic_sta, wh->i_addr2);
                        if (ni == NULL)
                                return;
-               } else
+               } else if ((ni->ni_flags & IEEE80211_NODE_AREF) == 0)
                        (void) ieee80211_ref_node(ni);
+               /*
+                * Mark the node as referenced to reflect that it's
+                * reference count has been bumped to insure it remains
+                * after the transaction completes.
+                */
+               ni->ni_flags |= IEEE80211_NODE_AREF;
+
                IEEE80211_SEND_MGMT(ic, ni,
                        IEEE80211_FC0_SUBTYPE_AUTH, seq + 1);
                IEEE80211_DPRINTF(ic, IEEE80211_MSG_DEBUG | IEEE80211_MSG_AUTH,
                    "[%s] station authenticated (open)\n",
                    ether_sprintf(ni->ni_macaddr));
+               /*
+                * When 802.1x is not in use mark the port
+                * authorized at this point so traffic can flow.
+                */
+               if (ni->ni_authmode != IEEE80211_AUTH_8021X)
+                       ieee80211_node_authorize(ic, ni);
 #endif /* !IEEE80211_NO_HOSTAP */
                break;
 
@@ -979,14 +978,39 @@
                        if (ni != ic->ic_bss)
                                ni->ni_fails++;
                        ic->ic_stats.is_rx_auth_fail++;
+                       ieee80211_new_state(ic, IEEE80211_S_SCAN, 0);



Home | Main Index | Thread Index | Old Index