summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDamien Bergamini <damien@cvs.openbsd.org>2010-06-07 16:46:18 +0000
committerDamien Bergamini <damien@cvs.openbsd.org>2010-06-07 16:46:18 +0000
commitcf027244f815057505172ecda023d8a4217d9e6a (patch)
tree8baea269cbb4fcf64e04ee6399693f073efaab4a /sys
parent104f94dd4b97509289ed863c89b58daf794e9a24 (diff)
tweak ieee80211_decap():
instead of copying the 802.11 header on the stack and building the ethernet header directly in the mbuf, build the ethernet header on the stack directly from the 802.11 header in the mbuf and copy the ethernet header to the mbuf after stripping the 802.11 header. makes the code easier to read/understand, especially, it is now explicit what is being put in the ether_type field. diff from Matthew Dempsky (matthew at dempsky dot org) moved ieee80211_align_mbuf() under #ifdef __STRICT_ALIGNMENT while i'm here.
Diffstat (limited to 'sys')
-rw-r--r--sys/net80211/ieee80211_input.c60
1 files changed, 31 insertions, 29 deletions
diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c
index 46c9eb0da55..d2f8f8fe9c5 100644
--- a/sys/net80211/ieee80211_input.c
+++ b/sys/net80211/ieee80211_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_input.c,v 1.114 2010/06/05 13:13:43 damien Exp $ */
+/* $OpenBSD: ieee80211_input.c,v 1.115 2010/06/07 16:46:17 damien Exp $ */
/*-
* Copyright (c) 2001 Atsushi Onoe
@@ -834,6 +834,7 @@ ieee80211_deliver_data(struct ieee80211com *ic, struct mbuf *m,
}
}
+#ifdef __STRICT_ALIGNMENT
/*
* Make sure protocol header (e.g. IP) is aligned on a 32-bit boundary.
* This is achieved by copying mbufs so drivers should try to map their
@@ -897,13 +898,14 @@ ieee80211_align_mbuf(struct mbuf *m)
m_freem(m);
return n0;
}
+#endif /* __STRICT_ALIGNMENT */
void
ieee80211_decap(struct ieee80211com *ic, struct mbuf *m,
struct ieee80211_node *ni, int hdrlen)
{
- struct ieee80211_frame_addr4 wh;
- struct ether_header *eh;
+ struct ether_header eh;
+ struct ieee80211_frame *wh;
struct llc *llc;
if (m->m_len < hdrlen + LLC_SNAPFRAMELEN &&
@@ -911,48 +913,48 @@ ieee80211_decap(struct ieee80211com *ic, struct mbuf *m,
ic->ic_stats.is_rx_decap++;
return;
}
- memcpy(&wh, mtod(m, caddr_t), MIN(hdrlen, sizeof(wh)));
- llc = (struct llc *)(mtod(m, caddr_t) + hdrlen);
+ wh = mtod(m, struct ieee80211_frame *);
+ switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
+ case IEEE80211_FC1_DIR_NODS:
+ IEEE80211_ADDR_COPY(eh.ether_dhost, wh->i_addr1);
+ IEEE80211_ADDR_COPY(eh.ether_shost, wh->i_addr2);
+ break;
+ case IEEE80211_FC1_DIR_TODS:
+ IEEE80211_ADDR_COPY(eh.ether_dhost, wh->i_addr3);
+ IEEE80211_ADDR_COPY(eh.ether_shost, wh->i_addr2);
+ break;
+ case IEEE80211_FC1_DIR_FROMDS:
+ IEEE80211_ADDR_COPY(eh.ether_dhost, wh->i_addr1);
+ IEEE80211_ADDR_COPY(eh.ether_shost, wh->i_addr3);
+ break;
+ case IEEE80211_FC1_DIR_DSTODS:
+ IEEE80211_ADDR_COPY(eh.ether_dhost, wh->i_addr3);
+ IEEE80211_ADDR_COPY(eh.ether_shost,
+ ((struct ieee80211_frame_addr4 *)wh)->i_addr4);
+ break;
+ }
+ llc = (struct llc *)((caddr_t)wh + 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) {
+ eh.ether_type = llc->llc_snap.ether_type;
m_adj(m, hdrlen + LLC_SNAPFRAMELEN - ETHER_HDR_LEN);
- llc = NULL;
} else {
+ eh.ether_type = htons(m->m_pkthdr.len - hdrlen);
m_adj(m, hdrlen - ETHER_HDR_LEN);
}
- eh = mtod(m, struct ether_header *);
- switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) {
- case IEEE80211_FC1_DIR_NODS:
- IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1);
- IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2);
- break;
- case IEEE80211_FC1_DIR_TODS:
- IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr3);
- IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr2);
- break;
- case IEEE80211_FC1_DIR_FROMDS:
- IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr1);
- IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr3);
- break;
- case IEEE80211_FC1_DIR_DSTODS:
- IEEE80211_ADDR_COPY(eh->ether_dhost, wh.i_addr3);
- IEEE80211_ADDR_COPY(eh->ether_shost, wh.i_addr4);
- break;
- }
+ memcpy(mtod(m, caddr_t), &eh, ETHER_HDR_LEN);
+#ifdef __STRICT_ALIGNMENT
if (!ALIGNED_POINTER(mtod(m, caddr_t) + ETHER_HDR_LEN, u_int32_t)) {
if ((m = ieee80211_align_mbuf(m)) == NULL) {
ic->ic_stats.is_rx_decap++;
return;
}
}
- if (llc != NULL) {
- eh = mtod(m, struct ether_header *);
- eh->ether_type = htons(m->m_pkthdr.len - ETHER_HDR_LEN);
- }
+#endif
ieee80211_deliver_data(ic, m, ni);
}