diff options
author | Hakan Olsson <ho@cvs.openbsd.org> | 2000-11-27 14:57:53 +0000 |
---|---|---|
committer | Hakan Olsson <ho@cvs.openbsd.org> | 2000-11-27 14:57:53 +0000 |
commit | 91ab060e48419de12b0d832e6ebb76b7c4027cb7 (patch) | |
tree | 5840bb2112beb35f6d27c7e42fca8890ea3800b8 /sys | |
parent | 036e2e3ecf13792067944f70c13f6c00e078f16a (diff) |
Be more careful with ARP. Fix PR#1490. From gluk@ptci.ru
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netinet/if_ether.c | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index dbcdcbf696b..7b7f2da085e 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ether.c,v 1.22 2000/06/22 19:05:51 art Exp $ */ +/* $OpenBSD: if_ether.c,v 1.23 2000/11/27 14:57:52 ho Exp $ */ /* $NetBSD: if_ether.c,v 1.31 1996/05/11 12:59:58 mycroft Exp $ */ /* @@ -460,6 +460,13 @@ in_arpinput(m) ea = mtod(m, struct ether_arp *); op = ntohs(ea->arp_op); + if ((op != ARPOP_REQUEST) && (op != ARPOP_REPLY)) + goto out; + if ((op == ARPOP_REPLY) && (m->m_flags & (M_BCAST|M_MCAST))) { + log(LOG_ERR, + "arp: received reply to broadcast or multicast address\n"); + goto out; + } bcopy((caddr_t)ea->arp_spa, (caddr_t)&isaddr, sizeof (isaddr)); bcopy((caddr_t)ea->arp_tpa, (caddr_t)&itaddr, sizeof (itaddr)); for (ia = in_ifaddr.tqh_first; ia != 0; ia = ia->ia_list.tqe_next) @@ -477,11 +484,16 @@ in_arpinput(m) if (!bcmp((caddr_t)ea->arp_sha, (caddr_t)ac->ac_enaddr, sizeof (ea->arp_sha))) goto out; /* it's from me, ignore it. */ - if (!bcmp((caddr_t)ea->arp_sha, (caddr_t)etherbroadcastaddr, - sizeof (ea->arp_sha))) { - log(LOG_ERR, - "arp: ether address is broadcast for IP address %s!\n", - inet_ntoa(isaddr)); + if (ea->arp_sha[0] & 1) { + if (!bcmp((caddr_t)ea->arp_sha, (caddr_t)etherbroadcastaddr, + sizeof (ea->arp_sha))) + log(LOG_ERR, + "arp: ether address is broadcast for IP address %s!\n", + inet_ntoa(isaddr)); + else + log(LOG_ERR, + "arp: ether address is multicast for IP address %s!\n", + inet_ntoa(isaddr)); goto out; } if (isaddr.s_addr == myaddr.s_addr) { @@ -493,8 +505,8 @@ in_arpinput(m) } la = arplookup(isaddr.s_addr, itaddr.s_addr == myaddr.s_addr, 0); if (la && (rt = la->la_rt) && (sdl = SDL(rt->rt_gateway))) { - if (sdl->sdl_alen && - bcmp((caddr_t)ea->arp_sha, LLADDR(sdl), sdl->sdl_alen)) { + if (sdl->sdl_alen) { + if (bcmp((caddr_t)ea->arp_sha, LLADDR(sdl), sdl->sdl_alen)) { if (rt->rt_flags & RTF_PERMANENT_ARP) { log(LOG_WARNING, "arp: attempt to overwrite permanent " @@ -519,6 +531,15 @@ in_arpinput(m) (&ac->ac_if)->if_xname); rt->rt_expire = 1; /* no longer static */ } + } + } else if (rt->rt_ifp != &ac->ac_if) { + log(LOG_WARNING, + "arp: attempt to add entry for %s " + "on %s by %s on %s\n", + inet_ntoa(isaddr), rt->rt_ifp->if_xname, + ether_sprintf(ea->arp_sha), + (&ac->ac_if)->if_xname); + goto out; } bcopy((caddr_t)ea->arp_sha, LLADDR(sdl), sdl->sdl_alen = sizeof(ea->arp_sha)); |