diff options
Diffstat (limited to 'sys/net80211')
-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); } |