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