mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-12-03 19:08:58 +00:00
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:
parent
c63d4e17ae
commit
76ec7b2f60
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=57900
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user