This patch implements Demon's NETALIAS hack, i.e. the ability to
ifconfig a whole network onto an interface. To enable it you need to
add ``options NETALIAS'' to the kernel configuration file and
recompile the kernel.

See also the NETBIND patch, and the file fanf/webdev/six-squid-cure
in the CVS repository.

--- /usr/src/sys/conf/options.orig	Mon Sep 27 18:58:32 1999
+++ /usr/src/sys/conf/options	Mon Sep 27 20:35:24 1999
@@ -376,3 +376,6 @@
 
 # Embedded system options
 INIT_PATH		opt_init_path.h
+
+# Demon virtual hosting hacks
+NETALIAS		
--- /usr/src/sys/net/if.c.orig	Mon Sep 27 18:58:20 1999
+++ /usr/src/sys/net/if.c	Mon Sep 27 20:32:53 1999
@@ -35,6 +35,7 @@
  */
 
 #include "opt_compat.h"
+#include "opt_netalias.h"
 
 #include <sys/param.h>
 #include <sys/malloc.h>
@@ -193,6 +194,26 @@
 		 ifa = ifa->ifa_link.tqe_next) {
 		if (ifa->ifa_addr->sa_family != addr->sa_family)
 			continue;
+#ifdef NETALIAS
+		if (ifa->ifa_netmask) {
+			register char *argaddr, *ifaddr, *mask, *maskend;
+			/* check to see that the part of the address outside the
+			 * netmask is zero (i.e. it's a network rather than a host)
+			 * and that the addresses are equal within the netmask...
+			 * (see also ifa_ifwithnet() but I prefer these variable names)
+			 */
+			argaddr = addr->sa_data;
+			ifaddr = ifa->ifa_addr->sa_data;
+			mask = ifa->ifa_netmask->sa_data;
+			maskend = (char *)ifa->ifa_netmask + ifa->ifa_netmask->sa_len;
+			for (; mask < maskend; argaddr++, ifaddr++, mask++)
+   				if ((*ifaddr & ~*mask) ||
+				    ((*argaddr ^ *ifaddr) & *mask))
+					goto breakout;
+			return (ifa);
+		}
+		breakout:
+#endif /* NETALIAS */
 		if (equal(addr, ifa->ifa_addr))
 			return (ifa);
 		if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr &&
--- /usr/src/sys/netinet/in.c.orig	Mon Sep 27 18:59:09 1999
+++ /usr/src/sys/netinet/in.c	Mon Sep 27 20:32:53 1999
@@ -34,6 +34,8 @@
  * $FreeBSD: src/sys/netinet/in.c,v 1.39.2.2 1999/08/29 16:29:33 peter Exp $
  */
 
+#include "opt_netalias.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/sockio.h>
@@ -374,7 +376,13 @@
 
 	if ((ia->ia_flags & IFA_ROUTE) == 0)
 		return;
+#ifdef NETALIAS
+	if (ifp->if_flags & IFF_POINTOPOINT ||
+	    (ifp->if_flags & IFF_LOOPBACK &&
+	    ia->ia_addr.sin_addr.s_addr & ia->ia_sockmask.sin_addr.s_addr))
+#else
 	if (ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT))
+#endif
 		rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
 	else
 		rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0);
@@ -445,6 +453,9 @@
 			htonl(ia->ia_net | ~ ia->ia_netmask);
 	} else if (ifp->if_flags & IFF_LOOPBACK) {
 		ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
+#ifdef NETALIAS
+		if (i & ~ia->ia_subnetmask)
+#endif
 		flags |= RTF_HOST;
 	} else if (ifp->if_flags & IFF_POINTOPOINT) {
 		if (ia->ia_dstaddr.sin_family != AF_INET)
--- /usr/src/sys/netinet/ip_icmp.c.orig	Mon Sep 27 18:59:09 1999
+++ /usr/src/sys/netinet/ip_icmp.c	Mon Sep 27 20:32:53 1999
@@ -34,6 +34,8 @@
  * $FreeBSD: src/sys/netinet/ip_icmp.c,v 1.33.2.2 1999/08/29 16:29:45 peter Exp $
  */
 
+#include "opt_netalias.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/mbuf.h>
@@ -545,6 +547,11 @@
 	 * to the incoming interface.
 	 */
 	for (ia = in_ifaddrhead.tqh_first; ia; ia = ia->ia_link.tqe_next) {
+#ifdef NETALIAS
+		if (ntohl(IA_SIN(ia)->sin_addr.s_addr) == ia->ia_subnet &&
+		    (ntohl(t.s_addr) & ia->ia_subnetmask) == ia->ia_subnet)
+			goto t_ok;
+#endif /* NETALIAS */
 		if (t.s_addr == IA_SIN(ia)->sin_addr.s_addr)
 			break;
 		if (ia->ia_ifp && (ia->ia_ifp->if_flags & IFF_BROADCAST) &&
@@ -562,6 +569,9 @@
 	if (ia == (struct in_ifaddr *)0)
 		ia = in_ifaddrhead.tqh_first;
 	t = IA_SIN(ia)->sin_addr;
+#ifdef NETALIAS
+	t_ok:
+#endif /* NETALIAS */
 	ip->ip_src = t;
 	ip->ip_ttl = MAXTTL;
 
--- /usr/src/sys/netinet/ip_input.c.orig	Mon Sep 27 18:59:09 1999
+++ /usr/src/sys/netinet/ip_input.c	Mon Sep 27 20:32:53 1999
@@ -38,6 +38,7 @@
 #define	_IP_VHL
 
 #include "opt_bootp.h"
+#include "opt_netalias.h"
 #include "opt_ipfw.h"
 #include "opt_ipdn.h"
 #include "opt_ipdivert.h"
@@ -475,6 +476,17 @@
 	for (ia = TAILQ_FIRST(&in_ifaddrhead); ia;
 					ia = TAILQ_NEXT(ia, ia_link)) {
 #define	satosin(sa)	((struct sockaddr_in *)(sa))
+
+#ifdef NETALIAS
+#ifdef notdef
+	        log(LOG_DEBUG, "netalias check: iaddr %lx subnet %lx mask %lx dst %lx\n",
+		       IA_SIN(ia)->sin_addr.s_addr,
+		       ia->ia_subnet, ia->ia_subnetmask, ip->ip_dst.s_addr);
+#endif
+		if (ntohl(IA_SIN(ia)->sin_addr.s_addr) == ia->ia_subnet &&
+		    (ntohl(ip->ip_dst.s_addr) & ia->ia_subnetmask) == ia->ia_subnet)
+			goto ours;
+#endif /* NETALIAS */
 
 #ifdef BOOTP_COMPAT
 		if (IA_SIN(ia)->sin_addr.s_addr == INADDR_ANY)
