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>
