Subject: kern/2381: ARP requests for IP addresses on aliased gets get wrong source address
To: None <gnats-bugs@NetBSD.ORG>
From: None <pete@demon.net>
List: netbsd-bugs
Date: 05/08/1996 17:28:35
>Number:         2381
>Category:       kern
>Synopsis:       ARP requests for IP addresses on aliased gets get wrong source address
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed May  8 12:35:01 1996
>Last-Modified:
>Originator:     Peter Bentley
>Organization:
Demon Internet
>Release:        8 May 1996
>Environment:
System: NetBSD chico.eng.demon.net 1.1 NetBSD 1.1 (PETE) #68: Sat Apr 13 14:18:08 BST 1996 pete@chico.eng.demon.net:/src/NetBSD/1.1/src/sys/arch/i386/compile/PETE i386


>Description:
If an ethernet interface has multiple IP addresses, ARP requests are always
sent out using the 'real' IP address of the interface, even if they are
for addresses on the network of one of the interface aliases.  Cisco
routers (and possibly others) drop those packets causing problems in such
environments.
>How-To-Repeat:
Ifconfig an alias address on an interface, try and ping a host on the
network the alias belongs to (making sure it's reachable). Observe the
source IP address of the generated ARP requests with tcpdump or similar.
>Fix:

The following patch (originally from Bill Fenner <fenner@freefall.freebsd.org>) 
fixes the problem. Note, it doesn't patch if_arp.c which seems to
have appeared in my -current tree, looking a lot like a copy of
if_ether.c, but not included in the kernel build)

--- /src/NetBSD/current/src/sys/netinet/if_ether.c	Wed May  8 15:11:15 1996
+++ if_ether.c	Wed May  8 16:40:54 1996
@@ -260,17 +260,6 @@
 }
 
 /*
- * Broadcast an ARP packet, asking who has addr on interface ac.
- */
-void
-arpwhohas(ac, addr)
-	register struct arpcom *ac;
-	register struct in_addr *addr;
-{
-	arprequest(ac, &ac->ac_ipaddr.s_addr, &addr->s_addr, ac->ac_enaddr);
-}
-
-/*
  * Broadcast an ARP request. Caller specifies:
  *	- arp header source ip address
  *	- arp header target ip address
@@ -386,7 +375,10 @@
 		if (la->la_asked == 0 || rt->rt_expire != time.tv_sec) {
 			rt->rt_expire = time.tv_sec;
 			if (la->la_asked++ < arp_maxtries)
-				arpwhohas(ac, &(SIN(dst)->sin_addr));
+			    arprequest(ac,
+				&(SIN(rt->rt_ifa->ifa_addr)->sin_addr.s_addr),
+				&(SIN(dst)->sin_addr.s_addr),
+				       ac->ac_enaddr);
 			else {
 				rt->rt_flags |= RTF_REJECT;
 				rt->rt_expire += arpt_down;
@@ -611,9 +603,9 @@
 	struct ifaddr *ifa;
 {
 
-	ac->ac_ipaddr = IA_SIN(ifa)->sin_addr;
 	/* Warn the user if another station has this IP address. */
-	arpwhohas(ac, &ac->ac_ipaddr);
+	arprequest(ac, &(IA_SIN(ifa)->sin_addr.s_addr),
+		       &(IA_SIN(ifa)->sin_addr.s_addr), ac->ac_enaddr);
 	ifa->ifa_rtrequest = arp_rtrequest;
 	ifa->ifa_flags |= RTF_CLONING;
 }
--- /src/NetBSD/current/src/sys/netinet/if_ether.h	Wed Feb 14 12:36:47 1996
+++ if_ether.h	Wed May  8 15:20:39 1996
@@ -119,7 +119,6 @@
 struct	arpcom {
 	struct	 ifnet ac_if;			/* network-visible interface */
 	u_int8_t ac_enaddr[ETHER_ADDR_LEN];	/* ethernet hardware address */
-	struct	 in_addr ac_ipaddr;		/* copy of ip address- XXX */
 	LIST_HEAD(, ether_multi) ac_multiaddrs;	/* list of ether multicast addrs */
 	int	 ac_multicnt;			/* length of ac_multiaddrs list */
 };
>Audit-Trail:
>Unformatted: