The function arpintr() incorrectly checks m->m_len to detect incomplete

ARP packets. This can incorrectly reject complete frames since the frame
could be stored in more than one mbuf.

The following patches fix the length comparisson, and add several
diagnostic log messages to the interrupt handler for out-of-the-norm ARP
packets. This should make ARP problems easier to detect, diagnose and
fix.

Submitted by:	C. Stephen Gunn <csg@waterspout.com>
Approved by:	jkh
Reviewed by:	rwatson
This commit is contained in:
Robert Watson 2000-03-11 00:24:29 +00:00
parent c63d4e17ae
commit 76ec7b2f60
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=57900

View File

@ -430,9 +430,9 @@ arpresolve(ac, rt, m, dst, desten, rt0)
static void
arpintr()
{
register struct mbuf *m;
register struct mbuf *m, *m0;
register struct arphdr *ar;
int s;
int s, ml;
while (arpintrq.ifq_head) {
s = splimp();
@ -440,21 +440,44 @@ arpintr()
splx(s);
if (m == 0 || (m->m_flags & M_PKTHDR) == 0)
panic("arpintr");
if (m->m_len >= sizeof(struct arphdr) &&
(ar = mtod(m, struct arphdr *)) &&
(ntohs(ar->ar_hrd) == ARPHRD_ETHER ||
ntohs(ar->ar_hrd) == ARPHRD_IEEE802) &&
m->m_len >=
sizeof(struct arphdr) + 2 * ar->ar_hln + 2 * ar->ar_pln)
if (m->m_len < sizeof(struct arphdr) &&
(m = m_pullup(m, sizeof(struct arphdr)) == NULL)) {
log(LOG_ERR, "arp: runt packet -- m_pullup failed.");
continue;
}
ar = mtod(m, struct arphdr *);
switch (ntohs(ar->ar_pro)) {
if (ntohs(ar->ar_hrd) != ARPHRD_ETHER
&& ntohs(ar->ar_hrd) != ARPHRD_IEEE802) {
log(LOG_ERR,
"arp: unknown hardware address format (%2D)",
(unsigned char *)&ar->ar_hrd, "");
m_freem(m);
continue;
}
m0 = m;
ml = 0;
while (m0 != NULL) {
ml += m0->m_len; /* wanna implement m_size?? */
m0 = m0->m_next;
}
if (ml < sizeof(struct arphdr) + 2 * ar->ar_hln
+ 2 * ar->ar_pln) {
log(LOG_ERR, "arp: runt packet.");
m_freem(m);
continue;
}
switch (ntohs(ar->ar_pro)) {
#ifdef INET
case ETHERTYPE_IP:
in_arpinput(m);
continue;
case ETHERTYPE_IP:
in_arpinput(m);
continue;
#endif
}
}
m_freem(m);
}
}