diff options
author | Damien Bergamini <damien@cvs.openbsd.org> | 2010-06-07 16:46:18 +0000 |
---|---|---|
committer | Damien Bergamini <damien@cvs.openbsd.org> | 2010-06-07 16:46:18 +0000 |
commit | cf027244f815057505172ecda023d8a4217d9e6a (patch) | |
tree | 8baea269cbb4fcf64e04ee6399693f073efaab4a /sys | |
parent | 104f94dd4b97509289ed863c89b58daf794e9a24 (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.c | 60 |
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); } |