Subject: Re: ipf, ipv6 & arp questions
To: None <tech-net@netbsd.org>
From: Julian Coleman <jdc@coris.demon.co.uk>
List: tech-net
Date: 10/16/2001 12:05:03
> So, my questions again in brief:
>    2) How to publish arp info correctly, so that my gateway does
>    not answer to arp queries from inside the subnet, only to the
> outside?

I have a similar setup with 212.135.108.0/30 and 212.135.108.0/25.  I run
choparp (pkgsrc/net/choparp) with the appended patch to handle proxy arp :

  /usr/pkg/sbin/choparp le0 00:80:f1:00:53:fc 212.135.108.0 255.255.255.128 212.135.108.0 255.255.255.252 
  /usr/pkg/sbin/choparp le1 00:80:f1:00:53:fc 212.135.108.0 255.255.255.252 

J

-- 
                    My other computer also runs NetBSD
                          http://www.netbsd.org/

 ---8<---------------------------- Cut here ---------------------------->8---

--- choparp.8.orig	Thu Oct 19 19:30:16 2000
+++ choparp.8	Thu Oct 19 20:55:28 2000
@@ -0,0 +1,80 @@
+.\" Copyright (c) 1997 by Takamichi Tateoka.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by Takamichi Tateoka.
+.\" 4. Neither the name of the author may be used to endorse or promote
+.\"    products derived from this software without specific prior
+.\"    written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY TAKAMICHI TATEOKA ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd October 7, 1997
+.Dt CHOPARP 8
+.Os
+.Sh NAME
+.Nm choparp
+.Nd cheap and omitted proxy arp
+.Sh SYNOPSIS
+.Nm chpoarp
+.Ar if_name mac_addr net_addr net_mask [excl_addr excl_mask]
+.Sh DESCRIPTION
+.Pp
+.Nm choparp 
+is a easy-to-use proxy arp daemon.
+It watches arp request packets visible on the interface specified by argument
+.Ar if_name ,
+and sends proxy arp reply to the sender if the arp request queries the
+MAC address (ethernet hardware address) for the network specified by
+.Ar net_addr
+and
+.Ar net_mask .  If
+.Ar excl_addr
+and .Ar excl_mask
+are also specified, then no proxy arp reply will be sent for this network.
+.Pp
+.Ar mac_addr
+has to be the MAC address assigned to the interface
+.Ar if_name .
+The format of
+.Ar mac_addr
+must be 6 bytes of hexadecimal value, separated by colons (":") ;
+for example, "00:00:01:01:14:46".
+The format of
+.Ar net_addr
+and
+.Ar net_mask
+must be dot notation (say, 133.138.1.134) or 32bit hexadecimal value
+starting with "0x" (say, 0x858a0186).
+.Sh EXAMPLES
+If you have network interface "ne0" with MAC address "00:00:01:01:14:16",
+and would like to send proxy arp reply for 192.168.0.64/26,
+the argument would be as follows:
+.Bd -literal -offset indent
+choparp ne0 00:00:01:01:14:46 192.168.0.64 255.255.255.192
+.Ed
+.Sh BUGS
+Supports ethernet interfaces only.
+Handles single interface at a time.
+(you can start multiple
+.Nm choparp
+for multiple interfaces, though)
+MAC address should be automatically detected.
--- choparp.c.orig	Tue Oct  7 10:29:46 1997
+++ choparp.c	Thu Oct 19 20:51:23 2000
@@ -12,6 +12,9 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <string.h>
+#ifdef __NetBSD__
+#  include <stdlib.h> /* malloc() */
+#endif
 #include <sys/types.h>
 #include <fcntl.h>
 #include <sys/time.h>
@@ -24,6 +27,7 @@
 #include <netinet/if_ether.h>
 #include <sys/param.h>
 #include <errno.h>
+#include <assert.h>
 
 #define	BPFFILENAME	"/dev/bpf%d"	/* bpf file template */
 #ifndef	NBPFILTER			/* number of available bpf */
@@ -32,6 +36,8 @@
 
 u_long	target_net;		/* target network address (host order) */
 u_long	target_mask;		/* target network netmask (host order) */
+u_long	target_exclnet;		/* target network exclude addrs (host order) */
+u_long	target_exclmask;	/* target network exclude masks (host order) */
 u_char	target_mac[ETHER_ADDR_LEN];	/* target MAC address */
 
 /*
@@ -181,7 +187,8 @@
 	return(0);
     }
     target_ip = ntohl(*(u_long *)(arp->arp_tpa));
-    if ((target_ip & target_mask) == target_net)
+    if ((target_ip & target_mask) == target_net && (target_exclnet &&
+	(target_ip & target_exclmask) != target_exclnet))
 	return(-1);		/* OK */
     return(0);
 }
@@ -217,20 +224,35 @@
 
 void
 loop(int fd, char *buf, size_t buflen){
-    size_t  rlen;
+    ssize_t  rlen;
     char    *p, *nextp;
     size_t  nextlen;
     char    *rframe;
     size_t  rframe_len;
     char    *sframe;
     size_t  sframe_len;
+    fd_set fdset;
+
+    FD_ZERO(&fdset);
+    FD_SET(fd,&fdset);
 
     for(;;){
-	if ((rlen = read(fd, buf, buflen)) <= 0){
-	    fprintf(stderr,"loop: read: %s\n", strerror(errno));
-	    /* XXX: restart itself if daemon mode */
-	    return;
-	}
+      int r;
+      r = select(fd+1,&fdset, 0, 0, 0);
+      if ((r < 0) && (errno == EINTR)) continue;
+      if (r < 0) {
+	perror("select");
+	return;
+      }
+      assert(r == 1);
+
+      rlen = read(fd, buf, buflen);
+      if ((rlen < 0) && (errno = EINTR)) continue;
+      if (rlen < 0) {
+	perror("loop: read");
+	return;
+      }
+
 	p = buf;
 	while((rframe = getarp(p, rlen, &nextp, &nextlen)) != NULL){
 	    if (checkarp(rframe)){
@@ -294,6 +316,12 @@
 	atoip(argv[4], &target_mask)){
 	usage();
     }
+
+    if (argc == 7) {
+	atoip(argv[5], &target_exclnet);
+	atoip(argv[6], &target_exclmask);
+    } else
+	target_exclnet = 0;
 
     if ((fd = openbpf(argv[1], &buf, &buflen)) < 0)
 	return(-1);