Date: Sun, 31 Jan 99 23:27:20 +0000 (GMT) From: iedowse@maths.tcd.ie To: FreeBSD-gnats-submit@FreeBSD.ORG Subject: kern/9848: ARP proxyall extra sanity check Message-ID: <9901312327.aa23568@gosset.maths.tcd.ie>
next in thread | raw e-mail | index | archive | help
>Number: 9848 >Category: kern >Synopsis: ARP proxyall extra sanity check >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Sun Jan 31 15:30:01 PST 1999 >Closed-Date: >Last-Modified: >Originator: Ian Dowse >Release: FreeBSD 3.0-STABLE i386 >Organization: School of Mathematics Trinity College Dublin >Environment: FreeBSD 3.0-STABLE i386, but applies to all versions net.link.ether.inet.proxyall=1 >Description: FreeBSD's ARP proxying, when enabled via sysctl, performs very few sanity checks before sending a proxy reply to an ARP request. It only checks that, according to the routing table, replies are not sent to the interface on which the target node is located. When ARP proxying is used on a router connecting two ethernet segments, accidentally connecting an interface to the wrong network is all too easy. In this case the routing table does not match the network topology so the interface check does no good; the network erupts quickly into an ARP battle :( The patch below provides an extra sanity check for ARP proxying. It checks that the request came in via the interface on which the sender is expected to be. In the case of a mismatch a warning is logged, and the ARP request is not proxied. >How-To-Repeat: >Fix: --- if_ether.c.orig Sun Jan 31 21:33:10 1999 +++ if_ether.c Sun Jan 31 21:49:02 1999 @@ -582,6 +582,32 @@ (void)memcpy(ea->arp_tha, ea->arp_sha, sizeof(ea->arp_sha)); (void)memcpy(ea->arp_sha, ac->ac_enaddr, sizeof(ea->arp_sha)); rtfree(rt); + + /* + * Also check that the node which sent the ARP packet + * is on the the interface we expect it to be on. This + * avoids ARP chaos if an interface is connected to the + * wrong network. + */ + sin.sin_addr = isaddr; + + rt = rtalloc1((struct sockaddr *)&sin, 0, 0UL); + if (!rt) { + m_freem(m); + return; + } + if (rt->rt_ifp != &ac->ac_if) { + log(LOG_INFO, "arp_proxy: ignoring request" + " from %s via %s%d, expecting %s%d\n", + inet_ntoa(isaddr), ac->ac_if.if_name, + ac->ac_if.if_unit, rt->rt_ifp->if_name, + rt->rt_ifp->if_unit); + rtfree(rt); + m_freem(m); + return; + } + rtfree(rt); + #ifdef DEBUG_PROXY printf("arp: proxying for %s\n", inet_ntoa(itaddr)); >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9901312327.aa23568>