Skip site navigation (1)Skip section navigation (2)
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>