diff options
Diffstat (limited to 'sys/dev/ic/malo.c')
-rw-r--r-- | sys/dev/ic/malo.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/sys/dev/ic/malo.c b/sys/dev/ic/malo.c index 85676a10aa6..75a96aa2053 100644 --- a/sys/dev/ic/malo.c +++ b/sys/dev/ic/malo.c @@ -1,4 +1,4 @@ -/* $OpenBSD: malo.c,v 1.22 2006/11/12 14:18:29 claudio Exp $ */ +/* $OpenBSD: malo.c,v 1.23 2006/11/12 14:26:04 claudio Exp $ */ /* * Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org> @@ -1304,6 +1304,13 @@ malo_tx_mgt(struct malo_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) /* send mgt frames at the lowest available rate */ rate = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? 12 : 2; + if (m0->m_len < sizeof(struct ieee80211_frame *)) { + m0 = m_pullup(m0, sizeof(struct ieee80211_frame *)); + if (m0 == NULL) { + ifp->if_ierrors++; + return (ENOBUFS); + } + } wh = mtod(m0, struct ieee80211_frame *); if (wh->i_fc[1] & IEEE80211_FC1_WEP) { @@ -1347,14 +1354,20 @@ malo_tx_mgt(struct malo_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) * 6 bytes addr4 (inject) * n bytes 802.11 frame body */ - m0 = m_pullup(m0, sizeof(*wh)); - if (M_TRAILINGSPACE(m0) < 8) - return (1); - bcopy(m0->m_data + 24, m0->m_data + 32, m0->m_len - 24); - bcopy(m0->m_data, m0->m_data + 2, 24); + if (M_LEADINGSPACE(m0) < 8) { + if (M_TRAILINGSPACE(m0) < 8) + panic("%s: not enough space for mbuf dance", + sc->sc_dev.dv_xname); + bcopy(m0->m_data, m0->m_data + 8, m0->m_len); + m0->m_data += 8; + } + + /* move frame header */ + bcopy(m0->m_data, m0->m_data - 6, sizeof(*wh)); + m0->m_data -= 8; m0->m_len += 8; m0->m_pkthdr.len += 8; - *(uint16_t *)m0->m_data = htole16(m0->m_len - 32); /* FW len */ + *mtod(m0, uint16_t *) = htole16(m0->m_len - 32); /* FW len */ error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0, BUS_DMA_NOWAIT); |