Subject: Re: 2.0.2 an ftp
To: David Young <dyoung@pobox.com>
From: John Nemeth <jnemeth@victoria.tc.ca>
List: current-users
Date: 05/12/2005 00:40:11
On Oct 1, 7:23pm, David Young wrote:
} On Wed, May 11, 2005 at 05:19:06PM -0700, John Nemeth wrote:
} > I have a Cisco 350 Wireless Adapter that I'm trying to use with
} > 2.0.2 on my laptop. Whenever I try to fetch a file via FTP the
} > following message is logged and ftp receives nothing:
} >
} > an0: discarding oversize frame (len=1516)
}
} This ought to be fixed in -current, can you try? A pull-up to the 2.x
} branch may be in order.
Thanks. I grabbed anreg.h and anvar.h from -current. Then I
patched an.c with just the required changes in order to eliminate any
other differences between 2.0.2 and -current. Patch is included
below. All files are in src/sys/dev/ic. This seems to have done the
job. My test case was 'download-vulnerability-list'. Unfortunately,
it failed. It appears that the signoff message from ftp.netbsd.org is
being truncated. I tried another test by doing a 'make fetch' in
pkgsrc/devel/gmake. This seemed to have worked, so the failing test
may not be related. If it matters I'm using a 2.0.2 i386 box for NAT.
Index: an.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/an.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -r1.32 -r1.33
--- an.c 24 Aug 2004 00:53:29 -0000 1.32
+++ an.c 15 Jan 2005 11:01:46 -0000 1.33
@@ -1228,7 +1351,8 @@
struct an_rxframe frmhdr;
struct mbuf *m;
u_int16_t status;
- int fid, off, len;
+ int fid, gaplen, len, off;
+ uint8_t *gap;
fid = CSR_READ_2(sc, AN_RX_FID);
@@ -1264,7 +1388,8 @@
return;
}
- len = le16toh(frmhdr.an_rx_payload_len);
+ /* the payload length field includes a 16-bit "mystery field" */
+ len = le16toh(frmhdr.an_rx_payload_len) - sizeof(uint16_t);
off = ALIGN(sizeof(struct ieee80211_frame));
if (off + len > MCLBYTES) {
@@ -1284,7 +1409,7 @@
DPRINTF(("an_rx_intr: MGET failed\n"));
return;
}
- if (off + len > MHLEN) {
+ if (off + len + AN_GAPLEN_MAX > MHLEN) {
MCLGET(m, M_DONTWAIT);
if ((m->m_flags & M_EXT) == 0) {
CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_RX);
@@ -1297,29 +1422,45 @@
m->m_data += off - sizeof(struct ieee80211_frame);
if (ic->ic_opmode != IEEE80211_M_MONITOR) {
+ gaplen = le16toh(frmhdr.an_gaplen);
+ if (gaplen > AN_GAPLEN_MAX) {
+ CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_RX);
+ m_freem(m);
+ ifp->if_ierrors++;
+ DPRINTF(("%s: gap too long\n", __func__));
+ return;
+ }
/*
- * The gap and the payload length should be skipped.
- * Make dummy read to avoid seek.
+ * We don't need the 16-bit mystery field (payload length?),
+ * so read it into the region reserved for the 802.11 header.
+ *
+ * When Cisco Aironet 350 cards w/ firmware version 5 or
+ * greater operate with certain Cisco 350 APs,
+ * the "gap" is filled with the SNAP header. Read
+ * it in after the 802.11 header.
*/
- an_read_bap(sc, fid, -1, m->m_data,
- le16toh(frmhdr.an_gaplen) + sizeof(u_int16_t));
+ gap = m->m_data + sizeof(struct ieee80211_frame) -
+ sizeof(uint16_t);
+ an_read_bap(sc, fid, -1, gap, gaplen + sizeof(u_int16_t));
#ifdef AN_DEBUG
if ((ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) ==
(IFF_DEBUG|IFF_LINK2)) {
int i;
printf(" gap&len");
- for (i = 0;
- i < le16toh(frmhdr.an_gaplen) + sizeof(u_int16_t);
- i++)
- printf(" %02x", mtod(m, u_int8_t *)[i]);
+ for (i = 0; i < gaplen + sizeof(u_int16_t); i++)
+ printf(" %02x", gap[i]);
printf("\n");
}
#endif
- }
+ } else
+ gaplen = 0;
+
+ an_read_bap(sc, fid, -1,
+ m->m_data + sizeof(struct ieee80211_frame) + gaplen, len);
+ m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame) + gaplen +
+ len;
+
memcpy(m->m_data, &frmhdr.an_whdr, sizeof(struct ieee80211_frame));
- an_read_bap(sc, fid, -1, m->m_data + sizeof(struct ieee80211_frame),
- len);
- m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame) + len;
m->m_pkthdr.rcvif = ifp;
CSR_WRITE_2(sc, AN_EVENT_ACK, AN_EV_RX);
}-- End of excerpt from David Young